diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..cd49bbc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,27 @@ +name: CI + +on: + push: + branches: [main, dev, master] + pull_request: + branches: [main, dev, master] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: npm + + - name: Install + run: npm ci + + - name: Typecheck + run: npm run typecheck + + - name: Build + run: npm run build diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..95c121c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,33 @@ +# Changelog + +All notable changes to **God Panel Nuxt** are documented in this file. Versions follow the package version in `package.json`. + +## [2.1.0] - 2026-04-20 + +### Added + +- **Icons:** [Solar](https://icon-sets.iconify.design/solar/) via [`@nuxt/icon`](https://github.com/nuxt/icon), with [`@iconify-json/solar`](https://www.npmjs.com/package/@iconify-json/solar) and [`@iconify-json/simple-icons`](https://www.npmjs.com/package/@iconify-json/simple-icons) for brand marks. Legacy MDI-style names are mapped in `app/utils/app-icon-resolve.ts`. +- **Settings — icon style:** `iconStyle` in app settings (`linear` | `solid`), persisted with other preferences. **Linear** uses Solar `*-linear` glyphs; **solid** uses `*-bold`. Default is **linear**. Controlled from the settings drawer, **Theme settings** on `/dashboard/settings`, and validated in `app/types/validation.ts`. +- **God Kit documentation:** Sidebar nav item and footer help links to [God Kit docs](https://godkit.godplans.org/). `package.json` field `godKitDocumentation` and `runtimeConfig.public.godKitDocumentation` (override with `NUXT_PUBLIC_GOD_KIT_DOCS`). Settings info panel lists Solar icon option and a resources link to God Kit. +- **Changelog:** This file. + +### Changed + +- **`AppIcon`:** Renders Iconify SVGs through Nuxt Icon instead of the Material Design Icons webfont. +- **Navigation:** External doc links use `` where appropriate (`DashboardNavItemLink`). + +### Removed + +- **`@mdi/font`** and **`@mdi/js`** (replaced by the Iconify workflow above). + +### Tooling and documentation + +- **TypeScript:** `npm run typecheck` with `@types/node`, `typescript.tsConfig.compilerOptions.types`, **`vue-router` ^5** (Nuxt 4.4), **`nuxt` ^4.4.2**, **`typescript`** devDependency. +- **Dependencies:** `god-kit` pinned to **`^0.8.1`** (replaces `latest`). +- **Nuxt Icon:** `icon.serverBundle.externalizeIconsJson` **`false`** for SSR hosts without JSON imports. +- **Docs:** README dev URL **3333**; [docs/DEMO_AND_API.md](./docs/DEMO_AND_API.md); [DESIGN_IMPROVEMENTS.md](./DESIGN_IMPROVEMENTS.md) aligned with Solar / Iconify. +- **CI:** [.github/workflows/ci.yml](.github/workflows/ci.yml) — `npm ci`, `typecheck`, `build` on push/PR to `main`, `dev`, `master`. + +## [2.0.0] - earlier + +Initial tracked major version. For older history, see the Git log on the repository’s default branch. diff --git a/DESIGN_IMPROVEMENTS.md b/DESIGN_IMPROVEMENTS.md index 67f3f8c..54eaf9e 100644 --- a/DESIGN_IMPROVEMENTS.md +++ b/DESIGN_IMPROVEMENTS.md @@ -1,175 +1,45 @@ -# Settings Panel Design Improvements - -## ✅ Completed Improvements - -### 🎨 **Icons Fixed & Implemented** -- ✅ Replaced MDI icons with SVG icons from `/assets/icons/setting/` -- ✅ All icons now display correctly (moon, contrast, align-right, autofit-width, sidebar icons, font icon) -- ✅ Icons match the Next.js design exactly - -### 📐 **Layout & Design Improvements** - -#### **BaseOption Component** -- ✅ Redesigned with cleaner layout matching Next.js -- ✅ Icon and switch in top section -- ✅ Label and tooltip in bottom section -- ✅ Improved padding and spacing (16px padding, 24px gap) -- ✅ Border radius increased to 16px -- ✅ Subtle hover effects -- ✅ Selected state with proper background - -#### **PresetsOptions Component** -- ✅ Black pill-style title badge (dark background with light text) -- ✅ 3-column grid layout -- ✅ Cleaner preset buttons with sidebar icon -- ✅ Selected state with color-tinted background -- ✅ Hover effect with transform -- ✅ Proper color values for all presets - -#### **FontOptions Component** -- ✅ Black pill-style title badge matching presets -- ✅ 2-column grid layout -- ✅ Font icon with gradient background when selected -- ✅ Box shadow on selected state -- ✅ Font family applied to buttons -- ✅ Cleaner typography - -#### **NavOptions Component** -- ✅ Black pill-style title badge with tooltip icon -- ✅ Separated Layout and Color sections with labels -- ✅ CSS variables for consistent styling -- ✅ Improved spacing and organization -- ✅ Better visual hierarchy - -#### **LayoutOption Component** -- ✅ Complete redesign matching Next.js visual preview -- ✅ Visual representation of navigation layouts -- ✅ Circle, primary, and secondary items with gradient when selected -- ✅ Proper dimensions for vertical, horizontal, and mini layouts -- ✅ Border and shadow effects - -#### **ColorOption Component** -- ✅ Sidebar icon with proper outline/filled variants -- ✅ Gradient mask effect on selected icons -- ✅ Box shadow on selection -- ✅ Capitalized labels -- ✅ Improved hover states - -#### **SettingsDrawer Component** -- ✅ Backdrop blur effect (0.9 opacity with 20px blur) -- ✅ Improved header layout -- ✅ Custom scrollbar styling (6px width, themed colors) -- ✅ 2-column grid for base options -- ✅ Consistent 48px spacing between sections -- ✅ Better content padding (20px) -- ✅ Cleaner visual hierarchy - -### 🎯 **Design Elements** - -**Title Badges (god-kit tokens):** -```css -- Background: var(--gk-color-on-surface) or var(--gk-color-text) (pill on light surfaces) -- Text Color: var(--gk-color-surface) or var(--gk-color-bg) -- Border Radius: 22px -- Padding: 0 10px -- Line Height: 22px -- Font Size: 13px -- Font Weight: 600 -``` - -**Box Shadows:** -```css --8px 8px 20px -4px color-mix(in srgb, var(--gk-color-text) 12%, transparent) -``` - -**Border Radius:** -```css -- Main containers: 16px -- Badges: 22px -- Items: 12px (var(--gk-radius-md) / var(--gk-radius-lg)) -- Small elements: 8px -``` - -**Colors:** -```css -- Borders: color-mix(in srgb, var(--gk-color-on-surface) 12%, transparent) -- Backgrounds: color-mix(in srgb, var(--gk-color-on-surface) 8%, transparent) -- Item BG: color-mix(in srgb, var(--gk-color-on-surface) 20%, transparent) -- Hover: color-mix(in srgb, var(--gk-color-on-surface) 4%, transparent) -``` - -**Gradients:** -```css -linear-gradient(135deg, var(--gk-color-primary) 0%, var(--gk-color-primary-hover) 100%) -``` - -### 📊 **Component Comparison** - -| Component | Before | After | Status | -|-----------|--------|-------|--------| -| BaseOption | MDI icons, vertical layout | SVG icons, top/bottom sections | ✅ Complete | -| PresetsOptions | Simple grid | Black badge, icon-based | ✅ Complete | -| FontOptions | Basic buttons | Gradient icons, shadows | ✅ Complete | -| NavOptions | Simple layout | Black badge, visual previews | ✅ Complete | -| LayoutOption | Text-based | Visual navigation preview | ✅ Complete | -| ColorOption | Simple icons | Gradient masks, better UX | ✅ Complete | -| SettingsDrawer | Basic drawer | Blur effect, custom scrollbar | ✅ Complete | - -### 🎨 **Visual Features** - -**All Components Now Have:** -- ✅ Proper SVG icons from `/assets/icons/setting/` -- ✅ Black pill-style title badges (where applicable) -- ✅ Consistent border radius (16px for containers) -- ✅ Box shadows on selected states -- ✅ Subtle hover effects -- ✅ Smooth transitions (0.2s ease) -- ✅ Theme-aware colors -- ✅ Proper spacing and padding -- ✅ Visual hierarchy -- ✅ Professional polish - -### 🚀 **User Experience Improvements** - -1. **Better Visual Feedback:** - - Hover states on all interactive elements - - Selected states clearly indicated - - Smooth transitions between states - -2. **Improved Readability:** - - Better contrast with black badges - - Clearer text hierarchy - - Proper font weights and sizes - -3. **Professional Appearance:** - - Matches Next.js reference design - - Consistent design language - - Modern, clean aesthetic - -4. **Better Organization:** - - Logical grouping of settings - - Clear section separation - - Visual previews for layouts - -### 📝 **Files Updated** - -1. `app/components/settings/drawer/BaseOption.vue` - Complete redesign -2. `app/components/settings/drawer/PresetsOptions.vue` - Black badge, icon-based -3. `app/components/settings/drawer/FontOptions.vue` - Gradient icons -4. `app/components/settings/drawer/NavOptions.vue` - Black badge, sections -5. `app/components/settings/drawer/LayoutOption.vue` - Visual preview -6. `app/components/settings/drawer/ColorOption.vue` - Gradient masks -7. `app/components/settings/drawer/SettingsDrawer.vue` - Blur, scrollbar, grid - -### 🎉 **Result** - -The settings panel now perfectly matches the Next.js reference design with: -- ✅ All icons displaying correctly -- ✅ Professional, modern appearance -- ✅ Consistent design language -- ✅ Smooth interactions -- ✅ Better UX and visual feedback -- ✅ Theme-aware styling -- ✅ Responsive layout - -**The panel is now production-ready with a polished, professional look!** 🚀 +# Settings panel design notes + +Historical notes for the **settings drawer** and related UI. For **icons**, the app uses **[Solar](https://icon-sets.iconify.design/solar/)** (and **Simple Icons** for brands) through **`@nuxt/icon`**, with legacy name mapping in [`app/utils/app-icon-resolve.ts`](app/utils/app-icon-resolve.ts). See [`CHANGELOG.md`](CHANGELOG.md) for release-level changes. + +## Layout and components + +### BaseOption + +- Icon and switch in the top section; label and tooltip below +- Padding and spacing (e.g. 16px padding, gap between sections) +- Border radius and selected / hover states aligned with god-kit tokens + +### PresetsOptions, FontOptions, NavOptions + +- Pill-style section titles +- Grid layouts for presets and fonts +- **NavOptions:** layout choices with visual previews (`LayoutOption`) + +### LayoutOption + +- Visual preview for vertical, horizontal, and mini navigation layouts + +### SettingsDrawer + +- Header with reset / close actions +- Scrollable body; themed scrollbar where styled +- Grid of quick toggles (theme, contrast, RTL, compact, icon style, etc.) + +## Design tokens (reference) + +Title badges and surfaces often use: + +- **Borders:** `color-mix(in srgb, var(--gk-color-on-surface) 12%, transparent)` +- **Surfaces:** `color-mix(in srgb, var(--gk-color-on-surface) 8%, transparent)` +- **Radius:** `var(--gk-radius-md)` / `var(--gk-radius-lg)` where applicable + +## Component file map + +| Area | Main files under `app/components/settings/drawer/` | +|------------|-----------------------------------------------------| +| Drawer | `SettingsDrawer.vue` | +| Options | `BaseOption.vue`, `PresetsOptions.vue`, `FontOptions.vue`, `NavOptions.vue`, `LayoutOption.vue` | +| Chrome | `FullscreenButton.vue` | + +For **global theme** behavior (god-kit sync, SSR presets), see [`README.md`](README.md) and `app/plugins/god-kit.client.ts`. diff --git a/README.md b/README.md index 5ce4f00..0c4a1fe 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ A modern, feature-rich admin dashboard built with **Nuxt.js 4**, **[god-kit](htt - **State Management:** Pinia - **Validation:** Zod - **HTTP Client:** Axios -- **Icons:** Material Design Icons +- **Icons:** [Solar](https://icon-sets.iconify.design/solar/) (via [`@nuxt/icon`](https://github.com/nuxt/icon) + `@iconify-json/solar`), with [Simple Icons](https://simpleicons.org/) for brand marks — see `app/utils/app-icon-resolve.ts` for legacy name mapping - **Persistence:** Cookies + LocalStorage ## 📦 Installation @@ -73,7 +73,7 @@ A modern, feature-rich admin dashboard built with **Nuxt.js 4**, **[god-kit](htt pnpm dev ``` - Visit `http://localhost:3000` to see the application. + Visit `http://localhost:3333` (or the port set in [`nuxt.config.ts`](nuxt.config.ts) under `devServer.port`) to see the application. ## 🚀 Build & Production @@ -195,7 +195,10 @@ The application supports multiple theme configurations: **Optional observability:** Set `NUXT_PUBLIC_SENTRY_DSN` when wiring `@sentry/nuxt`; see `app/plugins/error-handler.client.ts`. ### Release QA (manual) -Before shipping, verify: **LTR + RTL** (e.g. Persian), **mini rail** and **compact** layout, **mobile drawer**, **settings save** (including primary preset and **dark mode**), and **dynamic fonts** (`useDynamicFonts`). +Before shipping, verify: **LTR + RTL** (e.g. Persian), **mini rail** and **compact** layout, **mobile drawer**, **settings save** (including primary preset and **dark mode**), and **dynamic fonts** (`useDynamicFonts`). Run **`npm run typecheck`** in CI or locally before releases. + +### Demo vs production API +Dashboard and analytics pages may use **placeholder metrics and charts** until a real backend is connected. See **[docs/DEMO_AND_API.md](./docs/DEMO_AND_API.md)** for `NUXT_PUBLIC_API_URL`, optional **`ENABLE_MOCK_DATA`**, and how auth/settings services relate to a live API. ### Layouts Choose from different dashboard layouts: diff --git a/app/components/settings/drawer/SettingsDrawer.vue b/app/components/settings/drawer/SettingsDrawer.vue index 19ca782..86de59f 100644 --- a/app/components/settings/drawer/SettingsDrawer.vue +++ b/app/components/settings/drawer/SettingsDrawer.vue @@ -84,6 +84,24 @@ :selected="settingsStore.settings.compactLayout" @click="toggleCompactLayout" /> + + + + (), { @@ -156,7 +175,8 @@ const props = withDefaults(defineProps(), { hideContrast: false, hideNavLayout: false, hideDirection: false, - hideColorScheme: false + hideColorScheme: false, + hideIconStyle: false, }) const settingsStore = useSettingsStore() diff --git a/app/components/theme/ThemeSettings.vue b/app/components/theme/ThemeSettings.vue index 7d91870..b4cecc4 100644 --- a/app/components/theme/ThemeSettings.vue +++ b/app/components/theme/ThemeSettings.vue @@ -83,6 +83,31 @@ /> +
+ +
+ + + {{ t('settingsDrawer.iconStyleLinearShort') }} + + + + {{ t('settingsDrawer.iconStyleSolidShort') }} + +
+

+ {{ t('settingsDrawer.iconStyleHelp') }} +

+
+
+
+

{{ t('pages.settings.resources') }}

+

+ {{ t('pages.settings.godKitDocsBlurb') }} + + {{ t('pages.settings.godKitDocsLink') }} + +

+
+ + +

{{ t('pages.settings.colorPalette') }}

{{ t('pages.settings.colorPaletteDesc') }}

@@ -53,6 +71,7 @@ import ThemeSettings from '~/components/theme/ThemeSettings.vue' import AppIcon from '~/components/ui/AppIcon.vue' const { t } = useI18n() +const config = useRuntimeConfig() definePageMeta({ layout: 'dashboard', @@ -97,4 +116,15 @@ useHead({ color: var(--gk-color-on-surface-muted); line-height: 1.6; } + +.settings-docs-link { + color: var(--gk-color-primary); + font-weight: 600; + text-decoration: underline; + text-underline-offset: 2px; +} + +.settings-docs-link:hover { + color: color-mix(in srgb, var(--gk-color-primary) 85%, var(--gk-color-on-surface)); +} diff --git a/app/stores/settings.ts b/app/stores/settings.ts index dacfd48..d52558d 100644 --- a/app/stores/settings.ts +++ b/app/stores/settings.ts @@ -9,7 +9,8 @@ const defaultSettings: Settings = { primaryColor: 'default', navLayout: 'vertical', compactLayout: true, - fontFamily: 'Inter' + fontFamily: 'Inter', + iconStyle: 'linear', } export const useSettingsStore = defineStore('settings', () => { diff --git a/app/types/validation.ts b/app/types/validation.ts index b7ed143..5f757c7 100644 --- a/app/types/validation.ts +++ b/app/types/validation.ts @@ -55,7 +55,9 @@ export const settingsSchema = z.object({ primaryColor: z.enum(['default', 'purple', 'cyan', 'blue', 'orange', 'red']), navLayout: z.enum(['vertical', 'horizontal', 'mini']), compactLayout: z.boolean(), - fontFamily: z.enum(['Inter', 'Roboto', 'Poppins', 'Barlow', 'DM Sans', 'Nunito Sans']) + fontFamily: z.enum(['Inter', 'Roboto', 'Poppins', 'Barlow', 'DM Sans', 'Nunito Sans']), + /** App icons: Solar linear (outline) vs solid (filled) */ + iconStyle: z.enum(['linear', 'solid']).default('linear'), }) // API Response Schemas diff --git a/app/utils/app-icon-resolve.ts b/app/utils/app-icon-resolve.ts new file mode 100644 index 0000000..ab6ca0b --- /dev/null +++ b/app/utils/app-icon-resolve.ts @@ -0,0 +1,105 @@ +/** + * Maps legacy MDI-style `AppIcon` names (with or without `mdi-`) to Iconify ids. + * Solar icons are stored as **-bold** (filled); `iconStyle: 'linear'` swaps to **-linear**. + * Brands (`simple-icons:*`) are unchanged. + */ + +export type AppIconStyle = 'linear' | 'solid' + +function applySolarVariant(iconId: string, iconStyle: AppIconStyle): string { + if (iconStyle === 'solid' || !iconId.startsWith('solar:')) return iconId + return iconId.replace(/-bold$/, '-linear') +} +const LEGACY_TO_ICONIFY: Record = { + account: 'solar:user-circle-bold', + 'account-group': 'solar:users-group-rounded-bold', + 'account-multiple': 'solar:users-group-rounded-bold', + 'account-plus': 'solar:user-plus-bold', + 'alert-circle': 'solar:danger-circle-bold', + alert: 'solar:danger-triangle-bold', + 'align-right': 'solar:align-right-bold', + 'arrow-collapse-horizontal': 'solar:round-transfer-horizontal-bold', + 'arrow-left': 'solar:arrow-left-bold', + 'autofit-width': 'solar:round-transfer-horizontal-bold', + bell: 'solar:bell-bing-bold', + 'bell-alert': 'solar:bell-bing-bold', + 'book-open-page-variant': 'solar:book-2-bold', + 'book-open-variant': 'solar:book-bold', + bug: 'solar:bug-minimalistic-bold', + 'cart-plus': 'solar:cart-plus-bold', + cart: 'solar:cart-large-2-bold', + 'chart-areaspline': 'solar:graph-new-bold', + 'chart-line': 'solar:chart-2-bold', + 'check-circle': 'solar:check-circle-bold', + 'chevron-down': 'solar:alt-arrow-down-bold', + 'chevron-left': 'solar:alt-arrow-left-bold', + 'chevron-right': 'solar:alt-arrow-right-bold', + 'chevron-up': 'solar:alt-arrow-up-bold', + 'circle-small': 'solar:record-bold', + circle: 'solar:record-circle-bold', + 'clock-outline': 'solar:clock-circle-bold', + close: 'solar:close-circle-bold', + 'code-braces': 'solar:code-bold', + cog: 'solar:settings-bold', + contrast: 'solar:filters-bold', + 'contrast-circle': 'solar:filters-bold', + 'credit-card-off': 'solar:card-bold', + discord: 'simple-icons:discord', + 'document-text': 'solar:document-text-bold', + 'exit-run': 'solar:exit-bold', + eye: 'solar:eye-bold', + 'eye-off': 'solar:eye-closed-bold', + 'file-question': 'solar:document-text-bold', + 'format-align-right': 'solar:align-right-bold', + 'format-font': 'solar:text-bold-bold', + 'fullscreen-exit': 'solar:minimize-square-3-bold', + fullscreen: 'solar:maximize-square-3-bold', + github: 'simple-icons:github', + 'help-circle': 'solar:question-circle-bold', + home: 'solar:home-2-bold', + information: 'solar:info-circle-bold', + 'information-outline': 'solar:info-circle-bold', + linkedin: 'simple-icons:linkedin', + loading: 'solar:refresh-bold', + logout: 'solar:logout-3-bold', + magnify: 'solar:magnifer-bold', + menu: 'solar:hamburger-menu-bold', + monitor: 'solar:monitor-bold', + moon: 'solar:moon-bold', + 'numeric-5-circle': 'solar:star-circle-bold', + 'numeric-6-circle': 'solar:bookmark-circle-bold', + 'package-variant': 'solar:box-minimalistic-bold', + palette: 'solar:palette-bold', + 'palette-outline': 'solar:palette-bold', + 'pallete-2': 'solar:pallete-2-bold', + refresh: 'solar:refresh-bold', + restart: 'solar:restart-bold', + 'trending-down': 'solar:graph-down-bold', + 'trending-up': 'solar:graph-up-bold', + twitter: 'simple-icons:x', + 'view-dashboard-outline': 'solar:widget-4-bold', + 'view-dashboard': 'solar:widget-5-bold', + 'weather-night': 'solar:moon-bold', + 'weather-sunny': 'solar:sun-2-bold', + cellphone: 'solar:smartphone-bold', + tablet: 'solar:tablet-bold', + 'folder-multiple': 'solar:folder-2-bold', +} + +export function resolveAppIconifyIcon( + raw: string, + iconStyle: AppIconStyle = 'linear' +): string { + const trimmed = raw.trim() + if (trimmed.includes(':')) { + return applySolarVariant(trimmed, iconStyle) + } + + const key = trimmed.replace(/^mdi-/i, '').toLowerCase() + const resolved = LEGACY_TO_ICONIFY[key] ?? 'solar:record-circle-bold' + return applySolarVariant(resolved, iconStyle) +} + +export function appIconNormalizedKey(raw: string): string { + return raw.trim().replace(/^mdi-/i, '').toLowerCase() +} diff --git a/app/utils/nav.ts b/app/utils/nav.ts index c2b1d7a..fcbeced 100644 --- a/app/utils/nav.ts +++ b/app/utils/nav.ts @@ -1,4 +1,4 @@ -/** Strip MDI prefix for AppIcon / webfont names */ +/** Strip `mdi-` prefix so `AppIcon` resolves the same key as short names */ export function navIconName(icon: string): string { return icon.replace(/^mdi-/, '') } diff --git a/docs/DEMO_AND_API.md b/docs/DEMO_AND_API.md new file mode 100644 index 0000000..15d52f5 --- /dev/null +++ b/docs/DEMO_AND_API.md @@ -0,0 +1,29 @@ +# Demo mode and API expectations + +God Panel Nuxt is a **full UI shell** (layouts, auth flows, settings, navigation) that can run **without a custom backend** for demos. Connecting a **real API** replaces mocks and unlocks live data. + +## Environment variables + +| Variable | Purpose | +|----------|---------| +| `NUXT_PUBLIC_API_URL` | Base URL for Axios (`app/services/api-client.ts`). Default in code is often `http://localhost:4000` when unset in `.env`. | +| `NUXT_PUBLIC_SITE_URL` | Canonical site URL (SEO, links). Optional. | +| `NUXT_PUBLIC_GOD_KIT_DOCS` | Overrides God Kit documentation URL (`nuxt.config` → `runtimeConfig.public.godKitDocumentation`). | +| `ENABLE_MOCK_DATA` | When `true`, some code paths may use mock-friendly behavior (see README / runtime config `enableMockData`). | + +## What is demo / placeholder today + +- **Dashboard home** (`/dashboard`): sample stat cards and “recent activity” copy are **static examples**, not wired to `dashboard.service` for live aggregates. +- **Analytics** (`/dashboard/analytics`): metrics, traffic chart area, and device breakdown use **in-page demo data**; charts are intentionally not bundled until you add a library and API. +- **Auth**: Login/register call **`auth.service`** against `NUXT_PUBLIC_API_URL`. Without a server implementing those routes, flows fail at the network layer unless you stub or mock. + +## Moving to production + +1. Implement or deploy an API that matches the contracts expected by **`app/services/auth.service.ts`**, **`app/services/settings.service.ts`**, and **`app/services/api-client.ts`** (interceptors, tokens, errors). +2. Set **`NUXT_PUBLIC_API_URL`** in each environment. +3. Replace placeholder dashboard/analytics sections with composables that fetch real endpoints; code-split heavy chart libraries if needed. +4. Run **`npm run build`** and **`npm run typecheck`** in CI (see `.github/workflows/ci.yml`). + +## Settings persistence + +Theme and layout preferences are stored in the **browser cookie** (`settings` store) for SSR-friendly hydration. Server-side **user settings** via `settingsService` are separate and require a working API. diff --git a/i18n/locales/en.json b/i18n/locales/en.json index eb91733..8950f7a 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -216,6 +216,14 @@ "settingsDrawer": { "presets": "Presets", "font": "Font", + "icons": "Icons", + "iconStyleLinear": "Icons: linear", + "iconStyleSolid": "Icons: solid", + "iconStyleLinearShort": "Linear", + "iconStyleSolidShort": "Solid", + "iconStyleHelp": "Solar icon weight: outline (linear) or filled (solid). Default is linear.", + "iconStyleLinearHint": "Outline-style icons (Solar linear)", + "iconStyleSolidHint": "Filled icons (Solar bold)", "nav": "Nav", "navLayout": "Layout", "themeFeatures": "Theme Features", @@ -248,6 +256,10 @@ "layoutOptions": "Multiple layout options", "fontCustomization": "Font family customization", "highContrast": "High contrast mode", + "solarIconStyle": "Solar icons: linear (outline) or solid (filled) — settings drawer or below", + "resources": "Resources", + "godKitDocsBlurb": "UI components and tokens are powered by God Kit.", + "godKitDocsLink": "Open God Kit documentation →", "colorPalette": "Color Palette", "colorPaletteDesc": "The theme system uses a comprehensive color palette with primary, secondary, and semantic colors (success, warning, error, info).", "typography": "Typography", diff --git a/i18n/locales/fa.json b/i18n/locales/fa.json index 06074c7..23841b9 100644 --- a/i18n/locales/fa.json +++ b/i18n/locales/fa.json @@ -171,6 +171,14 @@ "settingsDrawer": { "presets": "پیش فرض ها", "font": "فونت", + "icons": "آیکن ها", + "iconStyleLinear": "آیکن: خطی", + "iconStyleSolid": "آیکن: توپر", + "iconStyleLinearShort": "خطی", + "iconStyleSolidShort": "توپر", + "iconStyleHelp": "وزن آیکن Solar: خطی (linear) یا توپر (solid). پیش فرض خطی است.", + "iconStyleLinearHint": "آیکن های خطی (Solar linear)", + "iconStyleSolidHint": "آیکن های پر شده (Solar bold)", "nav": "ناوبری", "navLayout": "چیدمان", "themeFeatures": "ویژگی های تم", @@ -247,6 +255,10 @@ "layoutOptions": "گزینه های چیدمان متعدد", "fontCustomization": "شخصی سازی خانواده فونت", "highContrast": "حالت کنتراست بالا", + "solarIconStyle": "آیکن های Solar: خطی (outline) یا توپر (filled) — از کشوی تنظیمات یا بخش زیر", + "resources": "منابع", + "godKitDocsBlurb": "اجزای رابط و توکن ها با God Kit پیاده سازی شده اند.", + "godKitDocsLink": "باز کردن مستندات God Kit ←", "colorPalette": "پالت رنگ", "colorPaletteDesc": "سیستم تم از پالت رنگی جامع با رنگ های اصلی، ثانویه و معنایی (موفقیت، هشدار، خطا، اطلاعات) استفاده می کند.", "typography": "تایپوگرافی", diff --git a/nuxt.config.ts b/nuxt.config.ts index b2f8eb5..f0f2da0 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -12,9 +12,20 @@ export default defineNuxtConfig({ '@nuxtjs/tailwindcss', '@pinia/nuxt', '@nuxtjs/color-mode', - "@nuxtjs/i18n", + '@nuxtjs/i18n', + '@nuxt/icon', ], + /** + * Bundle icon JSON into the server build so SSR hosts without JSON import + * support still resolve icons (see Nuxt Icon serverBundle docs). + */ + icon: { + serverBundle: { + externalizeIconsJson: false, + }, + }, + // Auto-imports for better DX imports: { autoImport: true @@ -30,6 +41,9 @@ export default defineNuxtConfig({ /** When set, error-handler can forward to Sentry (wire in `error-handler.client.ts`) */ sentryDsn: process.env.NUXT_PUBLIC_SENTRY_DSN || '', enableMockData: process.env.ENABLE_MOCK_DATA === 'true', + /** God Kit docs (override via NUXT_PUBLIC_GOD_KIT_DOCS) */ + godKitDocumentation: + process.env.NUXT_PUBLIC_GOD_KIT_DOCS || 'https://godkit.godplans.org/', }, private: { jwtSecret: process.env.JWT_SECRET, @@ -51,8 +65,7 @@ export default defineNuxtConfig({ // CSS — god-kit tokens + component styles before app Tailwind layers - // MDI webfont: large payload (~400KB+ woff2). Future path: tree-shake with @mdi/js + inline SVG - // or a small sprite for icons used in AppIcon; measure LCP before/after. + // Icons: `@nuxt/icon` + Iconify (`@iconify-json/solar`, `simple-icons`) via `AppIcon`. css: [ 'god-kit/tokens.css', 'god-kit/vue.css', @@ -60,7 +73,6 @@ export default defineNuxtConfig({ // After main/Tailwind so `.dn-*` nav rules are reliably bundled (avoid @import in main.css) '~/assets/css/dashboard-nav.css', '~/assets/css/panel-shell.css', - '@mdi/font/css/materialdesignicons.min.css', ], @@ -86,12 +98,11 @@ export default defineNuxtConfig({ output: { manualChunks: { vendor: ['vue', 'vue-router'], - ui: ['@mdi/js'], - utils: ['axios', 'clsx'] - } - } - } - } + utils: ['axios', 'clsx'], + }, + }, + }, + }, }, // Experimental features @@ -103,7 +114,12 @@ export default defineNuxtConfig({ // TypeScript typescript: { strict: true, - typeCheck: false // Disable during development for better performance + typeCheck: false, // Disable during development for better performance + tsConfig: { + compilerOptions: { + types: ['node'], + }, + }, }, // App configuration diff --git a/package-lock.json b/package-lock.json index fbac4dc..cf9d542 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,18 @@ { "name": "god-panel-nuxt", - "version": "2.0.0", + "version": "2.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "god-panel-nuxt", - "version": "2.0.0", + "version": "2.1.0", "hasInstallScript": true, "license": "GNU AFFERO GENERAL PUBLIC LICENSE", "dependencies": { - "@mdi/font": "^7.4.47", - "@mdi/js": "^7.4.47", + "@iconify-json/simple-icons": "^1.2.79", + "@iconify-json/solar": "^1.2.5", + "@nuxt/icon": "^2.2.1", "@nuxtjs/color-mode": "^3.5.2", "@nuxtjs/i18n": "^10.1.1", "@nuxtjs/tailwindcss": "^6.14.0", @@ -19,18 +20,19 @@ "axios": "^1.12.2", "clsx": "^2.1.1", "date-fns": "^4.1.0", - "god-kit": "latest", - "nuxt": "^4.1.3", + "god-kit": "^0.8.1", + "nuxt": "^4.4.2", "pinia": "^3.0.3", "tailwind-merge": "^3.3.1", "vue": "^3.5.22", - "vue-router": "^4.5.1", - "vue-tsc": "^3.1.1", + "vue-router": "^5.0.3", "zod": "^3.24.0" }, "devDependencies": { + "@types/node": "^22.15.21", "sass": "^1.93.3", - "sass-embedded": "^1.93.3" + "sass-embedded": "^1.93.3", + "typescript": "^5.7.2" } }, "node_modules/@alloc/quick-lru": { @@ -45,6 +47,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@antfu/install-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", + "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", + "license": "MIT", + "dependencies": { + "package-manager-detector": "^1.3.0", + "tinyexec": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@babel/code-frame": { "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", @@ -1220,6 +1235,65 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@iconify-json/simple-icons": { + "version": "1.2.79", + "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.79.tgz", + "integrity": "sha512-aNyO7Fd1qej9oQfIyohYFRv0lhQLaZ+6UkK1c1qwax0MDPUOZOdq65MlU500kow97pD/W+b2u1And3e25eE24Q==", + "license": "CC0-1.0", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify-json/solar": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@iconify-json/solar/-/solar-1.2.5.tgz", + "integrity": "sha512-WMAiNwchU8zhfrySww6KQBRIBbsQ6SvgIu2yA+CHGyMima/0KQwT5MXogrZPJGoQF+1Ye3Qj6K+1CiyNn3YkoA==", + "license": "CC-BY-4.0", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/collections": { + "version": "1.0.674", + "resolved": "https://registry.npmjs.org/@iconify/collections/-/collections-1.0.674.tgz", + "integrity": "sha512-YLEpD2DufdlvG6keWnfyBL+FrIOxm2+2aypAVns9vZCBMvWSU4dn/gQEz9CV7k5QPM1uE9OQqfHAaBMR+kf1kg==", + "license": "MIT", + "dependencies": { + "@iconify/types": "*" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "license": "MIT" + }, + "node_modules/@iconify/utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.0.tgz", + "integrity": "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==", + "license": "MIT", + "dependencies": { + "@antfu/install-pkg": "^1.1.0", + "@iconify/types": "^2.0.0", + "mlly": "^1.8.0" + } + }, + "node_modules/@iconify/vue": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@iconify/vue/-/vue-5.0.0.tgz", + "integrity": "sha512-C+KuEWIF5nSBrobFJhT//JS87OZ++QDORB6f2q2Wm6fl2mueSTpFBeBsveK0KW9hWiZ4mNiPjsh6Zs4jjdROSg==", + "license": "MIT", + "dependencies": { + "@iconify/types": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/cyberalien" + }, + "peerDependencies": { + "vue": ">=3" + } + }, "node_modules/@intlify/bundle-utils": { "version": "11.0.7", "resolved": "https://registry.npmjs.org/@intlify/bundle-utils/-/bundle-utils-11.0.7.tgz", @@ -1709,18 +1783,6 @@ "node": ">=18" } }, - "node_modules/@mdi/font": { - "version": "7.4.47", - "resolved": "https://registry.npmjs.org/@mdi/font/-/font-7.4.47.tgz", - "integrity": "sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw==", - "license": "Apache-2.0" - }, - "node_modules/@mdi/js": { - "version": "7.4.47", - "resolved": "https://registry.npmjs.org/@mdi/js/-/js-7.4.47.tgz", - "integrity": "sha512-KPnNOtm5i2pMabqZxpUz7iQf+mfrYZyKCZ8QNz85czgEt7cuHcGorWfdzUMWYA0SD+a6Hn4FmJ+YhzzzjkTZrQ==", - "license": "Apache-2.0" - }, "node_modules/@miyaneee/rollup-plugin-json5": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@miyaneee/rollup-plugin-json5/-/rollup-plugin-json5-1.2.0.tgz", @@ -1966,6 +2028,82 @@ "pathe": "^2.0.3" } }, + "node_modules/@nuxt/icon": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@nuxt/icon/-/icon-2.2.1.tgz", + "integrity": "sha512-GI840yYGuvHI0BGDQ63d6rAxGzG96jQcWrnaWIQKlyQo/7sx9PjXkSHckXUXyX1MCr9zY6U25Td6OatfY6Hklw==", + "license": "MIT", + "dependencies": { + "@iconify/collections": "^1.0.641", + "@iconify/types": "^2.0.0", + "@iconify/utils": "^3.1.0", + "@iconify/vue": "^5.0.0", + "@nuxt/devtools-kit": "^3.1.1", + "@nuxt/kit": "^4.2.2", + "consola": "^3.4.2", + "local-pkg": "^1.1.2", + "mlly": "^1.8.0", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinyglobby": "^0.2.15" + } + }, + "node_modules/@nuxt/icon/node_modules/@nuxt/kit": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-4.4.2.tgz", + "integrity": "sha512-5+IPRNX2CjkBhuWUwz0hBuLqiaJPRoKzQ+SvcdrQDbAyE+VDeFt74VpSFr5/R0ujrK4b+XnSHUJWdS72w6hsog==", + "license": "MIT", + "dependencies": { + "c12": "^3.3.3", + "consola": "^3.4.2", + "defu": "^6.1.4", + "destr": "^2.0.5", + "errx": "^0.1.0", + "exsolve": "^1.0.8", + "ignore": "^7.0.5", + "jiti": "^2.6.1", + "klona": "^2.0.6", + "mlly": "^1.8.1", + "ohash": "^2.0.11", + "pathe": "^2.0.3", + "pkg-types": "^2.3.0", + "rc9": "^3.0.0", + "scule": "^1.3.0", + "semver": "^7.7.4", + "tinyglobby": "^0.2.15", + "ufo": "^1.6.3", + "unctx": "^2.5.0", + "untyped": "^2.0.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@nuxt/icon/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/@nuxt/icon/node_modules/pkg-types": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", + "license": "MIT", + "dependencies": { + "confbox": "^0.2.2", + "exsolve": "^1.0.7", + "pathe": "^2.0.3" + } + }, + "node_modules/@nuxt/icon/node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "license": "MIT" + }, "node_modules/@nuxt/kit": { "version": "3.21.2", "resolved": "https://registry.npmjs.org/@nuxt/kit/-/kit-3.21.2.tgz", @@ -2394,39 +2532,6 @@ "node": ">=18.12.0" } }, - "node_modules/@nuxtjs/i18n/node_modules/@vue/devtools-api": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-8.1.1.tgz", - "integrity": "sha512-bsDMJ07b3GN1puVwJb/fyFnj/U2imyswK5UQVLZwVl7O05jDrt6BHxeG5XffmOOdasOj/bOmIjxJvGPxU7pcqw==", - "license": "MIT", - "dependencies": { - "@vue/devtools-kit": "^8.1.1" - } - }, - "node_modules/@nuxtjs/i18n/node_modules/@vue/devtools-kit": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.1.1.tgz", - "integrity": "sha512-gVBaBv++i+adg4JpH71k9ppl4soyR7Y2McEqO5YNgv0BI1kMZ7BDX5gnwkZ5COYgiCyhejZG+yGNrBAjj6Coqg==", - "license": "MIT", - "dependencies": { - "@vue/devtools-shared": "^8.1.1", - "birpc": "^2.6.1", - "hookable": "^5.5.3", - "perfect-debounce": "^2.0.0" - } - }, - "node_modules/@nuxtjs/i18n/node_modules/@vue/devtools-shared": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.1.1.tgz", - "integrity": "sha512-+h4ttmJYl/txpxHKaoZcaKpC+pvckgLzIDiSQlaQ7kKthKh8KuwoLW2D8hPJEnqKzXOvu15UHEoGyngAXCz0EQ==", - "license": "MIT" - }, - "node_modules/@nuxtjs/i18n/node_modules/hookable": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", - "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", - "license": "MIT" - }, "node_modules/@nuxtjs/i18n/node_modules/pathe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", @@ -2444,65 +2549,6 @@ "pathe": "^2.0.3" } }, - "node_modules/@nuxtjs/i18n/node_modules/vue-router": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.0.4.tgz", - "integrity": "sha512-lCqDLCI2+fKVRl2OzXuzdSWmxXFLQRxQbmHugnRpTMyYiT+hNaycV0faqG5FBHDXoYrZ6MQcX87BvbY8mQ20Bg==", - "license": "MIT", - "dependencies": { - "@babel/generator": "^7.28.6", - "@vue-macros/common": "^3.1.1", - "@vue/devtools-api": "^8.0.6", - "ast-walker-scope": "^0.8.3", - "chokidar": "^5.0.0", - "json5": "^2.2.3", - "local-pkg": "^1.1.2", - "magic-string": "^0.30.21", - "mlly": "^1.8.0", - "muggle-string": "^0.4.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "scule": "^1.3.0", - "tinyglobby": "^0.2.15", - "unplugin": "^3.0.0", - "unplugin-utils": "^0.3.1", - "yaml": "^2.8.2" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "@pinia/colada": ">=0.21.2", - "@vue/compiler-sfc": "^3.5.17", - "pinia": "^3.0.4", - "vue": "^3.5.0" - }, - "peerDependenciesMeta": { - "@pinia/colada": { - "optional": true - }, - "@vue/compiler-sfc": { - "optional": true - }, - "pinia": { - "optional": true - } - } - }, - "node_modules/@nuxtjs/i18n/node_modules/vue-router/node_modules/unplugin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.0.0.tgz", - "integrity": "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==", - "license": "MIT", - "dependencies": { - "@jridgewell/remapping": "^2.3.5", - "picomatch": "^4.0.3", - "webpack-virtual-modules": "^0.6.2" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - } - }, "node_modules/@nuxtjs/tailwindcss": { "version": "6.14.0", "resolved": "https://registry.npmjs.org/@nuxtjs/tailwindcss/-/tailwindcss-6.14.0.tgz", @@ -4836,6 +4882,16 @@ "license": "MIT", "peer": true }, + "node_modules/@types/node": { + "version": "22.19.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz", + "integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, "node_modules/@types/resolve": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", @@ -5048,6 +5104,8 @@ "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.28.tgz", "integrity": "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==", "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@volar/source-map": "2.4.28" } @@ -5056,13 +5114,17 @@ "version": "2.4.28", "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.28.tgz", "integrity": "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==", - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/@volar/typescript": { "version": "2.4.28", "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.28.tgz", "integrity": "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==", "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@volar/language-core": "2.4.28", "path-browserify": "^1.0.1", @@ -5283,6 +5345,8 @@ "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.2.6.tgz", "integrity": "sha512-xYYYX3/aVup576tP/23sEUpgiEnujrENaoNRbaozC1/MA9I6EGFQRJb4xrt/MmUCAGlxTKL2RmT8JLTPqagCkg==", "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@volar/language-core": "2.4.28", "@vue/compiler-dom": "^3.5.0", @@ -5437,7 +5501,9 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-3.1.2.tgz", "integrity": "sha512-d9dYqZTS90WLiU0I5c6DHj/HcKkF8ZyGN3G5x8wSbslulz70KOxaqCT0hQCo9KOyhVqzqGojvNdJXoTumZOtcw==", - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/ansi-regex": { "version": "6.2.2", @@ -7996,9 +8062,9 @@ } }, "node_modules/god-kit": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/god-kit/-/god-kit-0.7.5.tgz", - "integrity": "sha512-0KTIiRfSW6reetT0QGzkH2Gem9lO1P4s4IzHvLDP69dL2HflRaotWutGZ8fsL/O6YfxrkVNjecazK5mk5CP/eQ==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/god-kit/-/god-kit-0.8.1.tgz", + "integrity": "sha512-M60Srd5taTsmMqJ7wpkV6SyBaZLvBOgmb91suDVPykOa4OntFDE7ZkLO+LN83Jjt19mkcPW/Jtn2YuBIoCueOw==", "license": "MIT", "dependencies": { "@tanstack/vue-virtual": "^3.13.23", @@ -11772,15 +11838,6 @@ "node": "^20.19.0 || >=22.12.0" } }, - "node_modules/nuxt/node_modules/@vue/devtools-api": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-8.1.1.tgz", - "integrity": "sha512-bsDMJ07b3GN1puVwJb/fyFnj/U2imyswK5UQVLZwVl7O05jDrt6BHxeG5XffmOOdasOj/bOmIjxJvGPxU7pcqw==", - "license": "MIT", - "dependencies": { - "@vue/devtools-kit": "^8.1.1" - } - }, "node_modules/nuxt/node_modules/@vue/devtools-kit": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.1.1.tgz", @@ -12055,51 +12112,6 @@ } } }, - "node_modules/nuxt/node_modules/vue-router": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.0.4.tgz", - "integrity": "sha512-lCqDLCI2+fKVRl2OzXuzdSWmxXFLQRxQbmHugnRpTMyYiT+hNaycV0faqG5FBHDXoYrZ6MQcX87BvbY8mQ20Bg==", - "license": "MIT", - "dependencies": { - "@babel/generator": "^7.28.6", - "@vue-macros/common": "^3.1.1", - "@vue/devtools-api": "^8.0.6", - "ast-walker-scope": "^0.8.3", - "chokidar": "^5.0.0", - "json5": "^2.2.3", - "local-pkg": "^1.1.2", - "magic-string": "^0.30.21", - "mlly": "^1.8.0", - "muggle-string": "^0.4.1", - "pathe": "^2.0.3", - "picomatch": "^4.0.3", - "scule": "^1.3.0", - "tinyglobby": "^0.2.15", - "unplugin": "^3.0.0", - "unplugin-utils": "^0.3.1", - "yaml": "^2.8.2" - }, - "funding": { - "url": "https://github.com/sponsors/posva" - }, - "peerDependencies": { - "@pinia/colada": ">=0.21.2", - "@vue/compiler-sfc": "^3.5.17", - "pinia": "^3.0.4", - "vue": "^3.5.0" - }, - "peerDependenciesMeta": { - "@pinia/colada": { - "optional": true - }, - "@vue/compiler-sfc": { - "optional": true - }, - "pinia": { - "optional": true - } - } - }, "node_modules/nuxt/node_modules/which": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/which/-/which-6.0.1.tgz", @@ -12429,6 +12441,12 @@ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "license": "MIT" + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -12442,7 +12460,9 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "license": "MIT" + "license": "MIT", + "optional": true, + "peer": true }, "node_modules/path-exists": { "version": "4.0.0", @@ -15455,11 +15475,10 @@ "license": "MIT" }, "node_modules/typescript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", - "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -15507,6 +15526,13 @@ "@types/estree": "^1.0.0" } }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "devOptional": true, + "license": "MIT" + }, "node_modules/unenv": { "version": "2.0.0-rc.24", "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz", @@ -16791,31 +16817,110 @@ "license": "MIT" }, "node_modules/vue-router": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz", - "integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-5.0.4.tgz", + "integrity": "sha512-lCqDLCI2+fKVRl2OzXuzdSWmxXFLQRxQbmHugnRpTMyYiT+hNaycV0faqG5FBHDXoYrZ6MQcX87BvbY8mQ20Bg==", "license": "MIT", "dependencies": { - "@vue/devtools-api": "^6.6.4" + "@babel/generator": "^7.28.6", + "@vue-macros/common": "^3.1.1", + "@vue/devtools-api": "^8.0.6", + "ast-walker-scope": "^0.8.3", + "chokidar": "^5.0.0", + "json5": "^2.2.3", + "local-pkg": "^1.1.2", + "magic-string": "^0.30.21", + "mlly": "^1.8.0", + "muggle-string": "^0.4.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "scule": "^1.3.0", + "tinyglobby": "^0.2.15", + "unplugin": "^3.0.0", + "unplugin-utils": "^0.3.1", + "yaml": "^2.8.2" }, "funding": { "url": "https://github.com/sponsors/posva" }, "peerDependencies": { + "@pinia/colada": ">=0.21.2", + "@vue/compiler-sfc": "^3.5.17", + "pinia": "^3.0.4", "vue": "^3.5.0" + }, + "peerDependenciesMeta": { + "@pinia/colada": { + "optional": true + }, + "@vue/compiler-sfc": { + "optional": true + }, + "pinia": { + "optional": true + } } }, "node_modules/vue-router/node_modules/@vue/devtools-api": { - "version": "6.6.4", - "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", - "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-8.1.1.tgz", + "integrity": "sha512-bsDMJ07b3GN1puVwJb/fyFnj/U2imyswK5UQVLZwVl7O05jDrt6BHxeG5XffmOOdasOj/bOmIjxJvGPxU7pcqw==", + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^8.1.1" + } + }, + "node_modules/vue-router/node_modules/@vue/devtools-kit": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-8.1.1.tgz", + "integrity": "sha512-gVBaBv++i+adg4JpH71k9ppl4soyR7Y2McEqO5YNgv0BI1kMZ7BDX5gnwkZ5COYgiCyhejZG+yGNrBAjj6Coqg==", + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^8.1.1", + "birpc": "^2.6.1", + "hookable": "^5.5.3", + "perfect-debounce": "^2.0.0" + } + }, + "node_modules/vue-router/node_modules/@vue/devtools-shared": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-8.1.1.tgz", + "integrity": "sha512-+h4ttmJYl/txpxHKaoZcaKpC+pvckgLzIDiSQlaQ7kKthKh8KuwoLW2D8hPJEnqKzXOvu15UHEoGyngAXCz0EQ==", "license": "MIT" }, + "node_modules/vue-router/node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "license": "MIT" + }, + "node_modules/vue-router/node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "license": "MIT" + }, + "node_modules/vue-router/node_modules/unplugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-3.0.0.tgz", + "integrity": "sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "picomatch": "^4.0.3", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/vue-tsc": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.2.6.tgz", "integrity": "sha512-gYW/kWI0XrwGzd0PKc7tVB/qpdeAkIZLNZb10/InizkQjHjnT8weZ/vBarZoj4kHKbUTZT/bAVgoOr8x4NsQ/Q==", "license": "MIT", + "optional": true, + "peer": true, "dependencies": { "@volar/typescript": "2.4.28", "@vue/language-core": "3.2.6" diff --git a/package.json b/package.json index 6eca11d..f281c8e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "god-panel-nuxt", - "version": "2.0.0", + "version": "2.1.0", "description": "God Panel — Nuxt admin dashboard with god-kit, Tailwind CSS, and Pinia", "godKitDocumentation": "https://godkit.godplans.org/", "author": "God Plan Team", @@ -18,8 +18,9 @@ "typecheck": "nuxt typecheck" }, "dependencies": { - "@mdi/font": "^7.4.47", - "@mdi/js": "^7.4.47", + "@iconify-json/simple-icons": "^1.2.79", + "@iconify-json/solar": "^1.2.5", + "@nuxt/icon": "^2.2.1", "@nuxtjs/color-mode": "^3.5.2", "@nuxtjs/i18n": "^10.1.1", "@nuxtjs/tailwindcss": "^6.14.0", @@ -27,17 +28,18 @@ "axios": "^1.12.2", "clsx": "^2.1.1", "date-fns": "^4.1.0", - "god-kit": "latest", - "nuxt": "^4.1.3", + "god-kit": "^0.8.1", + "nuxt": "^4.4.2", "pinia": "^3.0.3", "tailwind-merge": "^3.3.1", - "zod": "^3.24.0", "vue": "^3.5.22", - "vue-router": "^4.5.1", - "vue-tsc": "^3.1.1" + "vue-router": "^5.0.3", + "zod": "^3.24.0" }, "devDependencies": { + "@types/node": "^22.15.21", "sass": "^1.93.3", - "sass-embedded": "^1.93.3" + "sass-embedded": "^1.93.3", + "typescript": "^5.7.2" } }