From 47f7645dc4a4cce06ec710a0d4e1f308d8c60625 Mon Sep 17 00:00:00 2001 From: Blaquewithaq Date: Mon, 16 Jun 2025 15:11:55 -0500 Subject: [PATCH 1/3] chore: code cleanup --- .gitignore | 1 - TODO.md | 25 +++++++ app/app.config.ts | 42 +++++++++++ content/1.docs/1.getting-started/1.index.md | 41 +---------- .../1.getting-started/2.installation.md | 19 +---- nuxt.config.ts | 48 ++++++++++--- package.json | 1 - scripts/extract-icons.ts | 70 +++++++++++++------ 8 files changed, 155 insertions(+), 92 deletions(-) create mode 100644 TODO.md diff --git a/.gitignore b/.gitignore index 4f43501..c037aad 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,5 @@ logs .history # Project -.private public/assets package-lock.json diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..e9dcc42 --- /dev/null +++ b/TODO.md @@ -0,0 +1,25 @@ +# ToDo + +## Site Finalization + +- [ ] Figure out legal policies +- [ ] Logo needs fixed (replace text with svg to fix it) +- [ ] Seo for entire site +- [ ] Expand ftp script to push data,images,videos separately + +## Rebrand + +### Usernames & Social Media + +- GitHub: [projectM-visualizer](https://github.com/projectM-visualizer) +- Twitter/X: [@projectMvisual](https://x.com/projectMViz) +- Mastodon: [@projectm](https://fosstodon.org/@projectm) +- Discord: [projectM](https://discord.gg/projectM) + +### UPDATED - Usernames & Social Media + +- GitHub: [ProjectM Visualizer](https://github.com/projectm-visualizer) +- Twitter/X: [@ProjectMVisualizer](https://twitter.com/projectm-visualizer) +- Mastodon: [ProjectM Visualizer](https://fosstodon.org/@projectm-visualizer) +- Bluesky: [ProjectM Visualizer](https://bsky.app/profile/projectm-visualizer.org) +- Discord: [ProjectM Visualizer](https://discord.gg/projectm-visualizer) diff --git a/app/app.config.ts b/app/app.config.ts index a749451..5d5a083 100644 --- a/app/app.config.ts +++ b/app/app.config.ts @@ -3,6 +3,48 @@ export default defineAppConfig({ colors: { primary: 'teal', neutral: 'gray' + }, + icons: { + arrowUp: 'i-lucide-arrow-up', + arrowDown: 'i-lucide-arrow-down', + caution: 'i-lucide-circle-alert', + copy: 'i-lucide-copy', + copyCheck: 'i-lucide-copy-check', + dark: 'i-lucide-moon', + error: 'i-lucide-circle-x', + eye: 'i-lucide-eye', + eyeOff: 'i-lucide-eye-off', + file: 'i-lucide-file-text', + folder: 'i-lucide-folder', + folderOpen: 'i-lucide-folder-open', + hash: 'i-lucide-hash', + info: 'i-lucide-info', + light: 'i-lucide-sun', + menu: 'i-lucide-menu', + panelClose: 'i-lucide-panel-left-close', + panelOpen: 'i-lucide-panel-left-open', + reload: 'i-lucide-rotate-ccw', + stop: 'i-lucide-square', + success: 'i-lucide-circle-check', + system: 'i-lucide-monitor', + tip: 'i-lucide-lightbulb', + warning: 'i-lucide-triangle-alert', + arrowLeft: 'i-lucide-arrow-left', + arrowRight: 'i-lucide-arrow-right', + check: 'i-lucide-check', + chevronDoubleLeft: 'i-lucide-chevrons-left', + chevronDoubleRight: 'i-lucide-chevrons-right', + chevronDown: 'i-lucide-chevron-down', + chevronLeft: 'i-lucide-chevron-left', + chevronRight: 'i-lucide-chevron-right', + chevronUp: 'i-lucide-chevron-up', + close: 'i-lucide-x', + ellipsis: 'i-lucide-ellipsis', + external: 'i-lucide-arrow-up-right', + loading: 'i-lucide-loader-circle', + minus: 'i-lucide-minus', + plus: 'i-lucide-plus', + search: 'i-lucide-search' } } }) diff --git a/content/1.docs/1.getting-started/1.index.md b/content/1.docs/1.getting-started/1.index.md index 5995e3b..f6861d7 100644 --- a/content/1.docs/1.getting-started/1.index.md +++ b/content/1.docs/1.getting-started/1.index.md @@ -1,44 +1,5 @@ --- title: Introduction -description: Welcome to Nuxt UI Pro SaaS template. +description: Welcome to our User Guide --- -This template is a ready-to-use SaaS template made with [Nuxt UI Pro](https://ui.nuxt.com/pro), a collection of premium components built on top of [Nuxt UI](https://ui.nuxt.com) to create beautiful & responsive Nuxt applications in minutes. - -This template includes a customizable landing page, a pricing page, a documentation, a blog and authentication pages (login, register). - -## Features - -- Powered by [Nuxt 3](https://nuxt.com) -- Built with [Nuxt UI](https://ui.nuxt.com) and [Nuxt UI Pro](https://ui.nuxt.com/pro) -- Write content with [MDC syntax](https://content.nuxt.com/usage/markdown) thanks to [Nuxt Content](https://content.nuxt.com) -- Beautiful Typography styles -- Full-Text Search out of the box -- Dark mode support -- And more... - -## Play online - -You can start playing with this template in your browser using our online sandboxes: - -::u-button ---- -class: mr-4 -icon: i-simple-icons-stackblitz -label: Play on StackBlitz -target: _blank -to: https://stackblitz.com/github/nuxt-ui-pro/saas/ ---- -:: - -::u-button ---- -class: mt-2 sm:mt-0 -icon: i-simple-icons-codesandbox -label: Play on CodeSandbox -target: _blank -to: https://codesandbox.io/s/github/nuxt-ui-pro/saas/ ---- -:: - -Or open [Nuxt UI playground](https://ui.nuxt.com/playground). diff --git a/content/1.docs/1.getting-started/2.installation.md b/content/1.docs/1.getting-started/2.installation.md index cc41f93..7277e32 100644 --- a/content/1.docs/1.getting-started/2.installation.md +++ b/content/1.docs/1.getting-started/2.installation.md @@ -1,21 +1,4 @@ --- title: Installation -description: Get started with Nuxt UI Pro SaaS template. +description: Get started with the installation of our software. --- - -## Quick Start - -You can start a fresh new project with: - -```bash [Terminal] -npx nuxi init -t github:nuxt-ui-pro/saas -``` - -or create a new repository from GitHub: - -1. Open -2. Click on `Use this template` button -3. Enter repository name and click on `Create repository from template` button -4. Clone your new repository -5. Install dependencies with your favorite package manager -6. Start development server diff --git a/nuxt.config.ts b/nuxt.config.ts index 9a1e845..a85066f 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -68,34 +68,64 @@ export default defineNuxtConfig({ clientBundle: { scan: true, icons: [ - 'lucide:menu', - 'lucide:chevron-down', - 'lucide:arrow-up-right', + 'lucide:arrow-down', + 'lucide:arrow-left', 'lucide:arrow-right', - 'lucide:x', - 'lucide:hash', - 'lucide:sun', - 'lucide:moon', + 'lucide:arrow-up', + 'lucide:arrow-up-right', 'lucide:book', 'lucide:book-open', 'lucide:book-text', + 'lucide:check', + 'lucide:chevron-down', + 'lucide:chevron-left', + 'lucide:chevron-right', + 'lucide:chevron-up', + 'lucide:chevrons-left', + 'lucide:chevrons-right', + 'lucide:circle-alert', + 'lucide:circle-check', + 'lucide:circle-x', 'lucide:code-xml', + 'lucide:copy', + 'lucide:copy-check', 'lucide:credit-card', 'lucide:download', + 'lucide:ellipsis', 'lucide:equal-approximately', + 'lucide:eye', + 'lucide:eye-off', + 'lucide:file-text', + 'lucide:folder', + 'lucide:folder-open', 'lucide:folder-root', 'lucide:git-fork', + 'lucide:hash', + 'lucide:info', + 'lucide:lightbulb', + 'lucide:loader-circle', + 'lucide:menu', + 'lucide:minus', + 'lucide:monitor', + 'lucide:moon', 'lucide:newspaper', + 'lucide:panel-left-close', + 'lucide:panel-left-open', 'lucide:pencil', + 'lucide:plus', + 'lucide:rotate-ccw', + 'lucide:search', 'lucide:spline', + 'lucide:square', 'lucide:star', + 'lucide:sun', + 'lucide:triangle-alert', + 'lucide:x', 'simple-icons:apple', - 'simple-icons:codesandbox', 'simple-icons:discord', 'simple-icons:github', 'simple-icons:linux', 'simple-icons:mastodon', - 'simple-icons:stackblitz', 'simple-icons:windows', 'simple-icons:x', 'simple-icons:youtube' diff --git a/package.json b/package.json index 4ea4ab0..5fe3e70 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,6 @@ "eslint": "^9.28.0", "libsodium-wrappers": "^0.7.15", "lint-staged": "^16.1.1", - "node-gyp": "^11.2.0", "octokit": "^5.0.3", "semantic-release": "^24.2.5", "simple-git-hooks": "^2.13.0", diff --git a/scripts/extract-icons.ts b/scripts/extract-icons.ts index 12b3f87..31b06ae 100644 --- a/scripts/extract-icons.ts +++ b/scripts/extract-icons.ts @@ -10,11 +10,15 @@ import { readdirSync, statSync } from 'node:fs' // ---------- Config & Constants ---------- -// const NUXT_CONFIG_FILE = 'nuxt.config.ts' +const NUXT_CONFIG_FILE = 'nuxt.config.ts' // Match only icons that start with "i-" and follow the pattern: i-[namespace]-[icon-name] -const ICON_REGEX = /\bi-([\w]+-[\w-]+)\b/g +const ICON_REGEX = /\bi-([a-zA-Z0-9_-]+)\b/g const VALID_EXTENSIONS = ['.yml', '.yaml', '.json', '.md', '.vue', '.ts'] const DIRS = ['./app', './content', './shared'] +const ICON_COLLECTIONS = [ + 'lucide', + 'simple-icons' +] // ---------- Arg Parser ---------- @@ -71,39 +75,58 @@ async function scanDirRecursively(dir: string, icons: Set) { // ---------- Nuxt Config Update ---------- -// TODO: Implement this function to update the Nuxt config file with the extracted icons -// without overwriting existing icons. -// async function updateNuxtConfig(icons: string[]) { -// const nuxtConfigPath = join(process.cwd(), NUXT_CONFIG_FILE) -// const config = await Bun.file(nuxtConfigPath).text() +async function updateNuxtConfig(icons: string[]) { + const nuxtConfigPath = join(process.cwd(), NUXT_CONFIG_FILE) + const configContent = await Bun.file(nuxtConfigPath).text() -// const mergedIcons = new Set([ -// ...(config.icon?.clientBundle?.icons || []), -// ...icons -// ]) + const formattedIcons = icons.map(icon => ` '${icon}'`).join(',\n ') -// config.icon.clientBundle.icons = mergedIcons + const updated = configContent.replace( + /icons:\s*\[[\s\S]*?\]/m, + `icons: [\n ${formattedIcons}\n ]` + ) -// await Bun.write(nuxtConfigPath, config) -// console.log(`✅ Updated ${NUXT_CONFIG_FILE} with ${icons.length} icons.`) -// } + if (updated === configContent) { + console.warn('⚠️ No change made. Could not locate icons array to update.') + return + } + + await Bun.write(nuxtConfigPath, updated) + console.log(`✅ Updated ${NUXT_CONFIG_FILE} with ${icons.length} icons.`) +} // ---------- Format ---------- function cleanIcons(icons: Set): string[] { return Array.from(icons) .map(icon => icon.trim()) - .filter(icon => icon.length > 0 && !icon.includes(' ')) - .map(icon => icon.replace(/_/g, '-')) + .filter(icon => ICON_COLLECTIONS.some(collection => icon.includes(`${collection}-`))) .map((icon) => { - const lastDash = icon.lastIndexOf('-') - return lastDash !== -1 - ? icon.slice(0, lastDash) + ':' + icon.slice(lastDash + 1) - : icon + const raw = icon.replace(/i-/, '').trim() + + const matchedCollection = ICON_COLLECTIONS + .filter(collection => raw.startsWith(`${collection}-`)) + .sort((a, b) => b.length - a.length)[0] + + if (!matchedCollection) { + console.warn(`⚠️ Unknown icon collection for: ${icon}`) + return null + } + + const iconName = raw.slice(matchedCollection.length + 1) + + if (!iconName) { + console.warn(`⚠️ Empty icon name for: ${icon}`) + return null + } + + return `${matchedCollection}:${iconName}` }) + .filter((icon): icon is string => !!icon) .filter((icon, index, self) => self.indexOf(icon) === index) .sort((a, b) => a.localeCompare(b)) } + // ---------- Main ---------- async function main() { @@ -115,11 +138,12 @@ async function main() { } const sortedIcons = cleanIcons(icons) - console.log(`🔍 Found ${sortedIcons.length} styled icons:`) + console.log(`🔍 Extracted ${icons.size} icons from directories: ${dirs.join(', ')}`) console.log(sortedIcons.map(i => ` '${i}'`).join(',\n')) + console.log(`🔍 Sorted ${sortedIcons.length} icons:`) if (write) { - // await updateNuxtConfig(sortedIcons) + await updateNuxtConfig(sortedIcons) } } From 13d93fa6bdba58957435ad5ec2dea739af0bc964 Mon Sep 17 00:00:00 2001 From: Blaquewithaq Date: Mon, 16 Jun 2025 15:51:13 -0500 Subject: [PATCH 2/3] feat: added docs page --- app/error.vue | 22 ++--- app/pages/docs/[...slug].vue | 54 ++++++++++++- bun.lock | 80 ++----------------- content.config.ts | 1 + .../1.docs/1.getting-started/.navigation.yml | 1 - content/1.docs/1.user/.navigation.yml | 1 + .../{1.getting-started => 1.user}/1.index.md | 0 .../2.installation.md | 0 content/1.docs/2.developer/.navigation.yml | 1 + content/1.docs/2.developer/1.index.md | 5 ++ content/1.docs/2.developer/2.installation.md | 4 + content/app.yml | 8 +- nuxt.config.ts | 2 +- 13 files changed, 81 insertions(+), 98 deletions(-) delete mode 100644 content/1.docs/1.getting-started/.navigation.yml create mode 100644 content/1.docs/1.user/.navigation.yml rename content/1.docs/{1.getting-started => 1.user}/1.index.md (100%) rename content/1.docs/{1.getting-started => 1.user}/2.installation.md (100%) create mode 100644 content/1.docs/2.developer/.navigation.yml create mode 100644 content/1.docs/2.developer/1.index.md create mode 100644 content/1.docs/2.developer/2.installation.md diff --git a/app/error.vue b/app/error.vue index b4bcd66..598c962 100644 --- a/app/error.vue +++ b/app/error.vue @@ -14,9 +14,11 @@ useHead({ } }) +const { data: app } = await useAsyncData('app-error', () => queryCollection('app').first()) + useSeoMeta({ - title: 'Page not found', - description: 'We are sorry but this page could not be found.' + title: app.value?.error.title || 'Page not found', + description: app.value?.error.description || 'We are sorry but this page could not be found.' }) const { data: navigation } = await useAsyncData('navigation', () => queryCollectionNavigation('docs'), { @@ -25,20 +27,6 @@ const { data: navigation } = await useAsyncData('navigation', () => queryCollect const { data: files } = useLazyAsyncData('search', () => queryCollectionSearchSections('docs'), { server: false }) - -const links = [{ - label: 'Docs', - icon: 'i-lucide-book', - to: '/docs/getting-started' -}, { - label: 'Pricing', - icon: 'i-lucide-credit-card', - to: '/pricing' -}, { - label: 'Blog', - icon: 'i-lucide-pencil', - to: '/blog' -}] diff --git a/app/pages/blog/index.vue b/app/pages/blog/index.vue index 2b70d76..5a430a3 100644 --- a/app/pages/blog/index.vue +++ b/app/pages/blog/index.vue @@ -14,8 +14,11 @@ useSeoMeta({ ogDescription: description }) -// TODO: Figure out OgImage component usage in static builds -// if (import.meta.client) defineOgImageComponent('myOgImage') +if (page.value?.seo.image) { + defineOgImage({ + url: page.value.seo.image as string + }) +}