@beknurakhmed/webforge-cli 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +226 -226
- package/package.json +63 -63
- package/templates/angular/angular.json +28 -2
- package/templates/extras/typescript/deps.json +6 -0
- package/templates/extras/typescript/react/tsconfig.json +21 -0
- package/templates/extras/typescript/vanilla/tsconfig.json +19 -0
- package/templates/extras/typescript/vue/tsconfig.json +20 -0
- package/templates/overlays/blog/angular/src/app/app.component.ts +100 -0
- package/templates/overlays/blog/angular/src/app/app.routes.ts +12 -0
- package/templates/overlays/blog/angular/src/app/components/blog-sidebar.component.ts +115 -0
- package/templates/overlays/blog/angular/src/app/components/post-card.component.ts +94 -0
- package/templates/overlays/blog/angular/src/app/pages/about.component.ts +114 -0
- package/templates/overlays/blog/angular/src/app/pages/category.component.ts +141 -0
- package/templates/overlays/blog/angular/src/app/pages/home.component.ts +143 -0
- package/templates/overlays/blog/angular/src/app/pages/post-detail.component.ts +196 -0
- package/templates/overlays/blog/angular/src/main.ts +10 -0
- package/templates/overlays/blog/nextjs/src/app/about/page.tsx +55 -0
- package/templates/overlays/blog/nextjs/src/app/category/[slug]/page.tsx +52 -0
- package/templates/overlays/blog/nextjs/src/app/components/BlogFooter.tsx +46 -0
- package/templates/overlays/blog/nextjs/src/app/components/BlogHeader.tsx +37 -0
- package/templates/overlays/blog/nextjs/src/app/components/BlogSidebar.tsx +56 -0
- package/templates/overlays/blog/nextjs/src/app/components/PostCard.tsx +42 -0
- package/templates/overlays/blog/nextjs/src/app/globals.css +158 -0
- package/templates/overlays/blog/nextjs/src/app/layout.tsx +20 -0
- package/templates/overlays/blog/nextjs/src/app/page.tsx +36 -0
- package/templates/overlays/blog/nextjs/src/app/post/[id]/page.tsx +78 -0
- package/templates/overlays/blog/nuxt/app.vue +27 -0
- package/templates/overlays/blog/nuxt/components/BlogFooter.vue +48 -0
- package/templates/overlays/blog/nuxt/components/BlogHeader.vue +55 -0
- package/templates/overlays/blog/nuxt/components/BlogSidebar.vue +144 -0
- package/templates/overlays/blog/nuxt/components/PostCard.vue +125 -0
- package/templates/overlays/blog/nuxt/layouts/default.vue +25 -0
- package/templates/overlays/blog/nuxt/pages/about.vue +161 -0
- package/templates/overlays/blog/nuxt/pages/category/[slug].vue +80 -0
- package/templates/overlays/blog/nuxt/pages/index.vue +54 -0
- package/templates/overlays/blog/nuxt/pages/post/[id].vue +158 -0
- package/templates/overlays/blog/react/src/App.css +58 -18
- package/templates/overlays/blog/react/src/App.tsx +16 -31
- package/templates/overlays/blog/react/src/components/BlogFooter.tsx +4 -2
- package/templates/overlays/blog/react/src/components/BlogHeader.tsx +12 -6
- package/templates/overlays/blog/react/src/components/BlogSidebar.tsx +9 -8
- package/templates/overlays/blog/react/src/components/Layout.tsx +17 -0
- package/templates/overlays/blog/react/src/components/PostCard.tsx +30 -0
- package/templates/overlays/blog/react/src/data/posts.ts +22 -0
- package/templates/overlays/blog/react/src/pages/About.tsx +33 -0
- package/templates/overlays/blog/react/src/pages/Category.tsx +29 -0
- package/templates/overlays/blog/react/src/pages/Home.tsx +18 -0
- package/templates/overlays/blog/react/src/pages/PostDetail.tsx +38 -0
- package/templates/overlays/blog/vanilla/src/main.ts +112 -0
- package/templates/overlays/blog/vanilla/src/pages/about.ts +106 -0
- package/templates/overlays/blog/vanilla/src/pages/category.ts +86 -0
- package/templates/overlays/blog/vanilla/src/pages/home.ts +103 -0
- package/templates/overlays/blog/vanilla/src/pages/post-detail.ts +108 -0
- package/templates/overlays/blog/vanilla/src/router.ts +33 -0
- package/templates/overlays/blog/vanilla/src/style.css +677 -0
- package/templates/overlays/blog/vue/src/App.vue +29 -0
- package/templates/overlays/blog/vue/src/components/BlogFooter.vue +8 -0
- package/templates/overlays/blog/vue/src/components/BlogHeader.vue +14 -0
- package/templates/overlays/blog/vue/src/components/BlogSidebar.vue +31 -0
- package/templates/overlays/blog/vue/src/components/PostCard.vue +17 -0
- package/templates/overlays/blog/vue/src/data.ts +82 -0
- package/templates/overlays/blog/vue/src/main.ts +6 -0
- package/templates/overlays/blog/vue/src/pages/About.vue +17 -0
- package/templates/overlays/blog/vue/src/pages/Category.vue +32 -0
- package/templates/overlays/blog/vue/src/pages/Home.vue +14 -0
- package/templates/overlays/blog/vue/src/pages/PostDetail.vue +22 -0
- package/templates/overlays/blog/vue/src/router.ts +19 -0
- package/templates/overlays/blog/vue/src/style.css +288 -0
- package/templates/overlays/crm/angular/src/app/app.component.ts +110 -0
- package/templates/overlays/crm/angular/src/app/app.routes.ts +12 -0
- package/templates/overlays/crm/angular/src/app/components/contacts-table.component.ts +98 -0
- package/templates/overlays/crm/angular/src/app/components/stats-cards.component.ts +63 -0
- package/templates/overlays/crm/angular/src/app/pages/contacts.component.ts +70 -0
- package/templates/overlays/crm/angular/src/app/pages/dashboard-home.component.ts +38 -0
- package/templates/overlays/crm/angular/src/app/pages/deals.component.ts +145 -0
- package/templates/overlays/crm/angular/src/app/pages/settings.component.ts +103 -0
- package/templates/overlays/crm/angular/src/main.ts +8 -0
- package/templates/overlays/crm/nextjs/src/app/components/ContactsTable.tsx +69 -0
- package/templates/overlays/crm/nextjs/src/app/components/Sidebar.tsx +45 -0
- package/templates/overlays/crm/nextjs/src/app/components/StatsCards.tsx +31 -0
- package/templates/overlays/crm/nextjs/src/app/contacts/page.tsx +111 -0
- package/templates/overlays/crm/nextjs/src/app/deals/page.tsx +111 -0
- package/templates/overlays/crm/nextjs/src/app/globals.css +165 -0
- package/templates/overlays/crm/nextjs/src/app/layout.tsx +20 -0
- package/templates/overlays/crm/nextjs/src/app/page.tsx +43 -0
- package/templates/overlays/crm/nextjs/src/app/settings/page.tsx +91 -0
- package/templates/overlays/crm/nuxt/app.vue +27 -0
- package/templates/overlays/crm/nuxt/components/ContactsTable.vue +140 -0
- package/templates/overlays/crm/nuxt/components/CrmSidebar.vue +97 -0
- package/templates/overlays/crm/nuxt/components/StatsCards.vue +63 -0
- package/templates/overlays/crm/nuxt/layouts/default.vue +21 -0
- package/templates/overlays/crm/nuxt/pages/contacts.vue +79 -0
- package/templates/overlays/crm/nuxt/pages/deals.vue +229 -0
- package/templates/overlays/crm/nuxt/pages/index.vue +186 -0
- package/templates/overlays/crm/nuxt/pages/settings.vue +233 -0
- package/templates/overlays/crm/react/src/App.css +49 -20
- package/templates/overlays/crm/react/src/App.tsx +16 -41
- package/templates/overlays/crm/react/src/components/ContactsTable.tsx +8 -8
- package/templates/overlays/crm/react/src/components/Layout.tsx +15 -0
- package/templates/overlays/crm/react/src/components/Sidebar.tsx +20 -14
- package/templates/overlays/crm/react/src/components/StatsCards.tsx +10 -12
- package/templates/overlays/crm/react/src/data/contacts.ts +19 -0
- package/templates/overlays/crm/react/src/pages/Contacts.tsx +32 -0
- package/templates/overlays/crm/react/src/pages/DashboardHome.tsx +44 -0
- package/templates/overlays/crm/react/src/pages/Deals.tsx +48 -0
- package/templates/overlays/crm/react/src/pages/Settings.tsx +35 -0
- package/templates/overlays/crm/vanilla/src/main.ts +95 -0
- package/templates/overlays/crm/vanilla/src/pages/contacts.ts +87 -0
- package/templates/overlays/crm/vanilla/src/pages/dashboard-home.ts +121 -0
- package/templates/overlays/crm/vanilla/src/pages/deals.ts +116 -0
- package/templates/overlays/crm/vanilla/src/pages/settings.ts +129 -0
- package/templates/overlays/crm/vanilla/src/router.ts +33 -0
- package/templates/overlays/crm/vanilla/src/style.css +766 -0
- package/templates/overlays/crm/vue/src/App.vue +25 -0
- package/templates/overlays/crm/vue/src/components/ContactsTable.vue +30 -0
- package/templates/overlays/crm/vue/src/components/CrmSidebar.vue +14 -0
- package/templates/overlays/crm/vue/src/components/StatsCards.vue +23 -0
- package/templates/overlays/crm/vue/src/data.ts +38 -0
- package/templates/overlays/crm/vue/src/main.ts +6 -0
- package/templates/overlays/crm/vue/src/pages/Contacts.vue +25 -0
- package/templates/overlays/crm/vue/src/pages/DashboardHome.vue +19 -0
- package/templates/overlays/crm/vue/src/pages/Deals.vue +34 -0
- package/templates/overlays/crm/vue/src/pages/Settings.vue +33 -0
- package/templates/overlays/crm/vue/src/router.ts +19 -0
- package/templates/overlays/crm/vue/src/style.css +272 -0
- package/templates/overlays/dashboard/angular/src/app/app.component.ts +135 -0
- package/templates/overlays/dashboard/angular/src/app/app.routes.ts +24 -0
- package/templates/overlays/dashboard/angular/src/app/components/chart-placeholder.component.ts +86 -0
- package/templates/overlays/dashboard/angular/src/app/components/data-table.component.ts +140 -0
- package/templates/overlays/dashboard/angular/src/app/components/kpi-cards.component.ts +120 -0
- package/templates/overlays/dashboard/angular/src/app/pages/analytics.component.ts +138 -0
- package/templates/overlays/dashboard/angular/src/app/pages/overview.component.ts +58 -0
- package/templates/overlays/dashboard/angular/src/app/pages/settings.component.ts +128 -0
- package/templates/overlays/dashboard/angular/src/app/pages/users.component.ts +153 -0
- package/templates/overlays/dashboard/angular/src/main.ts +10 -0
- package/templates/overlays/dashboard/nextjs/src/app/analytics/page.tsx +76 -0
- package/templates/overlays/dashboard/nextjs/src/app/components/ChartPlaceholder.tsx +58 -0
- package/templates/overlays/dashboard/nextjs/src/app/components/DataTable.tsx +60 -0
- package/templates/overlays/dashboard/nextjs/src/app/components/KPICards.tsx +31 -0
- package/templates/overlays/dashboard/nextjs/src/app/components/Sidebar.tsx +45 -0
- package/templates/overlays/dashboard/nextjs/src/app/globals.css +150 -0
- package/templates/overlays/dashboard/nextjs/src/app/layout.tsx +20 -0
- package/templates/overlays/dashboard/nextjs/src/app/page.tsx +20 -0
- package/templates/overlays/dashboard/nextjs/src/app/settings/page.tsx +118 -0
- package/templates/overlays/dashboard/nextjs/src/app/users/page.tsx +99 -0
- package/templates/overlays/dashboard/nuxt/app.vue +27 -0
- package/templates/overlays/dashboard/nuxt/components/ChartPlaceholder.vue +73 -0
- package/templates/overlays/dashboard/nuxt/components/DashSidebar.vue +97 -0
- package/templates/overlays/dashboard/nuxt/components/DataTable.vue +126 -0
- package/templates/overlays/dashboard/nuxt/components/KPICards.vue +76 -0
- package/templates/overlays/dashboard/nuxt/layouts/default.vue +21 -0
- package/templates/overlays/dashboard/nuxt/pages/analytics.vue +94 -0
- package/templates/overlays/dashboard/nuxt/pages/index.vue +49 -0
- package/templates/overlays/dashboard/nuxt/pages/settings.vue +239 -0
- package/templates/overlays/dashboard/nuxt/pages/users.vue +227 -0
- package/templates/overlays/dashboard/react/src/App.css +50 -24
- package/templates/overlays/dashboard/react/src/App.tsx +16 -22
- package/templates/overlays/dashboard/react/src/components/ChartPlaceholder.tsx +5 -2
- package/templates/overlays/dashboard/react/src/components/DataTable.tsx +9 -1
- package/templates/overlays/dashboard/react/src/components/KPICards.tsx +4 -4
- package/templates/overlays/dashboard/react/src/components/Layout.tsx +13 -0
- package/templates/overlays/dashboard/react/src/components/Sidebar.tsx +15 -10
- package/templates/overlays/dashboard/react/src/pages/Analytics.tsx +33 -0
- package/templates/overlays/dashboard/react/src/pages/Overview.tsx +23 -0
- package/templates/overlays/dashboard/react/src/pages/Settings.tsx +41 -0
- package/templates/overlays/dashboard/react/src/pages/Users.tsx +57 -0
- package/templates/overlays/dashboard/vanilla/src/main.ts +101 -0
- package/templates/overlays/dashboard/vanilla/src/pages/analytics.ts +99 -0
- package/templates/overlays/dashboard/vanilla/src/pages/overview.ts +60 -0
- package/templates/overlays/dashboard/vanilla/src/pages/settings.ts +118 -0
- package/templates/overlays/dashboard/vanilla/src/pages/users.ts +80 -0
- package/templates/overlays/dashboard/vanilla/src/router.ts +33 -0
- package/templates/overlays/dashboard/vanilla/src/style.css +654 -0
- package/templates/overlays/dashboard/vue/src/App.vue +12 -0
- package/templates/overlays/dashboard/vue/src/components/ChartPlaceholder.vue +34 -0
- package/templates/overlays/dashboard/vue/src/components/DashSidebar.vue +19 -0
- package/templates/overlays/dashboard/vue/src/components/DataTable.vue +34 -0
- package/templates/overlays/dashboard/vue/src/components/KPICards.vue +18 -0
- package/templates/overlays/dashboard/vue/src/main.ts +6 -0
- package/templates/overlays/dashboard/vue/src/pages/Analytics.vue +32 -0
- package/templates/overlays/dashboard/vue/src/pages/Overview.vue +17 -0
- package/templates/overlays/dashboard/vue/src/pages/Settings.vue +65 -0
- package/templates/overlays/dashboard/vue/src/pages/Users.vue +44 -0
- package/templates/overlays/dashboard/vue/src/router.ts +15 -0
- package/templates/overlays/dashboard/vue/src/style.css +447 -0
- package/templates/overlays/ecommerce/angular/src/app/app.component.ts +147 -0
- package/templates/overlays/ecommerce/angular/src/app/app.routes.ts +10 -0
- package/templates/overlays/ecommerce/angular/src/app/components/product-card.component.ts +94 -0
- package/templates/overlays/ecommerce/angular/src/app/data/products.ts +75 -0
- package/templates/overlays/ecommerce/angular/src/app/pages/cart.component.ts +169 -0
- package/templates/overlays/ecommerce/angular/src/app/pages/home.component.ts +96 -0
- package/templates/overlays/ecommerce/angular/src/app/pages/product-detail.component.ts +124 -0
- package/templates/overlays/ecommerce/angular/src/main.ts +10 -0
- package/templates/overlays/ecommerce/nextjs/src/app/cart/page.tsx +74 -0
- package/templates/overlays/ecommerce/nextjs/src/app/components/CartProvider.tsx +80 -0
- package/templates/overlays/ecommerce/nextjs/src/app/components/Footer.tsx +44 -0
- package/templates/overlays/ecommerce/nextjs/src/app/components/Header.tsx +27 -0
- package/templates/overlays/ecommerce/nextjs/src/app/components/ProductCard.tsx +23 -0
- package/templates/overlays/ecommerce/nextjs/src/app/globals.css +144 -0
- package/templates/overlays/ecommerce/nextjs/src/app/layout.tsx +23 -0
- package/templates/overlays/ecommerce/nextjs/src/app/page.tsx +73 -0
- package/templates/overlays/ecommerce/nextjs/src/app/product/[id]/page.tsx +63 -0
- package/templates/overlays/ecommerce/nuxt/app.vue +27 -0
- package/templates/overlays/ecommerce/nuxt/components/ProductCard.vue +77 -0
- package/templates/overlays/ecommerce/nuxt/components/StoreFooter.vue +47 -0
- package/templates/overlays/ecommerce/nuxt/components/StoreHeader.vue +91 -0
- package/templates/overlays/ecommerce/nuxt/layouts/default.vue +43 -0
- package/templates/overlays/ecommerce/nuxt/pages/cart.vue +268 -0
- package/templates/overlays/ecommerce/nuxt/pages/index.vue +154 -0
- package/templates/overlays/ecommerce/nuxt/pages/product/[id].vue +211 -0
- package/templates/overlays/ecommerce/react/src/App.css +71 -59
- package/templates/overlays/ecommerce/react/src/App.tsx +18 -44
- package/templates/overlays/ecommerce/react/src/components/Footer.tsx +2 -2
- package/templates/overlays/ecommerce/react/src/components/Header.tsx +15 -14
- package/templates/overlays/ecommerce/react/src/components/Layout.tsx +20 -0
- package/templates/overlays/ecommerce/react/src/components/ProductCard.tsx +28 -0
- package/templates/overlays/ecommerce/react/src/data/products.ts +23 -0
- package/templates/overlays/ecommerce/react/src/pages/Cart.tsx +51 -0
- package/templates/overlays/ecommerce/react/src/pages/Home.tsx +37 -0
- package/templates/overlays/ecommerce/react/src/pages/ProductDetail.tsx +38 -0
- package/templates/overlays/ecommerce/vanilla/src/main.ts +73 -0
- package/templates/overlays/ecommerce/vanilla/src/pages/cart.ts +73 -0
- package/templates/overlays/ecommerce/vanilla/src/pages/home.ts +71 -0
- package/templates/overlays/ecommerce/vanilla/src/pages/product-detail.ts +81 -0
- package/templates/overlays/ecommerce/vanilla/src/router.ts +33 -0
- package/templates/overlays/ecommerce/vanilla/src/style.css +522 -0
- package/templates/overlays/ecommerce/vue/src/App.vue +17 -32
- package/templates/overlays/ecommerce/vue/src/components/ProductCard.vue +25 -0
- package/templates/overlays/ecommerce/vue/src/components/StoreFooter.vue +6 -12
- package/templates/overlays/ecommerce/vue/src/components/StoreHeader.vue +5 -23
- package/templates/overlays/ecommerce/vue/src/data.ts +23 -0
- package/templates/overlays/ecommerce/vue/src/main.ts +6 -0
- package/templates/overlays/ecommerce/vue/src/pages/Cart.vue +34 -0
- package/templates/overlays/ecommerce/vue/src/pages/Home.vue +27 -0
- package/templates/overlays/ecommerce/vue/src/pages/ProductDetail.vue +27 -0
- package/templates/overlays/ecommerce/vue/src/router.ts +13 -0
- package/templates/overlays/ecommerce/vue/src/style.css +359 -0
- package/templates/overlays/portfolio/angular/src/app/app.component.ts +102 -0
- package/templates/overlays/portfolio/angular/src/app/app.routes.ts +12 -0
- package/templates/overlays/portfolio/angular/src/app/components/project-card.component.ts +86 -0
- package/templates/overlays/portfolio/angular/src/app/components/skills-grid.component.ts +88 -0
- package/templates/overlays/portfolio/angular/src/app/pages/about.component.ts +122 -0
- package/templates/overlays/portfolio/angular/src/app/pages/contact.component.ts +131 -0
- package/templates/overlays/portfolio/angular/src/app/pages/home.component.ts +207 -0
- package/templates/overlays/portfolio/angular/src/app/pages/projects.component.ts +150 -0
- package/templates/overlays/portfolio/angular/src/main.ts +10 -0
- package/templates/overlays/portfolio/nextjs/src/app/about/page.tsx +70 -0
- package/templates/overlays/portfolio/nextjs/src/app/components/Footer.tsx +37 -0
- package/templates/overlays/portfolio/nextjs/src/app/components/Navbar.tsx +37 -0
- package/templates/overlays/portfolio/nextjs/src/app/components/ProjectCard.tsx +35 -0
- package/templates/overlays/portfolio/nextjs/src/app/components/SkillsGrid.tsx +45 -0
- package/templates/overlays/portfolio/nextjs/src/app/contact/page.tsx +138 -0
- package/templates/overlays/portfolio/nextjs/src/app/globals.css +197 -0
- package/templates/overlays/portfolio/nextjs/src/app/layout.tsx +20 -0
- package/templates/overlays/portfolio/nextjs/src/app/page.tsx +60 -0
- package/templates/overlays/portfolio/nextjs/src/app/projects/page.tsx +56 -0
- package/templates/overlays/portfolio/nuxt/app.vue +27 -0
- package/templates/overlays/portfolio/nuxt/components/PortfolioFooter.vue +49 -0
- package/templates/overlays/portfolio/nuxt/components/PortfolioNav.vue +77 -0
- package/templates/overlays/portfolio/nuxt/components/ProjectCard.vue +102 -0
- package/templates/overlays/portfolio/nuxt/components/SkillsGrid.vue +89 -0
- package/templates/overlays/portfolio/nuxt/layouts/default.vue +21 -0
- package/templates/overlays/portfolio/nuxt/pages/about.vue +179 -0
- package/templates/overlays/portfolio/nuxt/pages/contact.vue +278 -0
- package/templates/overlays/portfolio/nuxt/pages/index.vue +160 -0
- package/templates/overlays/portfolio/nuxt/pages/projects.vue +116 -0
- package/templates/overlays/portfolio/react/src/App.css +54 -27
- package/templates/overlays/portfolio/react/src/App.tsx +16 -12
- package/templates/overlays/portfolio/react/src/components/Layout.tsx +17 -0
- package/templates/overlays/portfolio/react/src/components/Navbar.tsx +30 -0
- package/templates/overlays/portfolio/react/src/components/PortfolioFooter.tsx +5 -3
- package/templates/overlays/portfolio/react/src/components/ProjectCard.tsx +24 -0
- package/templates/overlays/portfolio/react/src/components/SkillsGrid.tsx +20 -0
- package/templates/overlays/portfolio/react/src/data/projects.ts +25 -0
- package/templates/overlays/portfolio/react/src/pages/About.tsx +43 -0
- package/templates/overlays/portfolio/react/src/pages/Contact.tsx +48 -0
- package/templates/overlays/portfolio/react/src/pages/Home.tsx +44 -0
- package/templates/overlays/portfolio/react/src/pages/Projects.tsx +36 -0
- package/templates/overlays/portfolio/vanilla/src/main.ts +58 -0
- package/templates/overlays/portfolio/vanilla/src/pages/about.ts +146 -0
- package/templates/overlays/portfolio/vanilla/src/pages/contact.ts +159 -0
- package/templates/overlays/portfolio/vanilla/src/pages/home.ts +123 -0
- package/templates/overlays/portfolio/vanilla/src/pages/projects.ts +89 -0
- package/templates/overlays/portfolio/vanilla/src/router.ts +33 -0
- package/templates/overlays/portfolio/vanilla/src/style.css +909 -0
- package/templates/overlays/portfolio/vue/src/App.vue +25 -0
- package/templates/overlays/portfolio/vue/src/components/PortfolioFooter.vue +14 -0
- package/templates/overlays/portfolio/vue/src/components/PortfolioNav.vue +16 -0
- package/templates/overlays/portfolio/vue/src/components/ProjectCard.vue +18 -0
- package/templates/overlays/portfolio/vue/src/components/SkillsGrid.vue +14 -0
- package/templates/overlays/portfolio/vue/src/data.ts +78 -0
- package/templates/overlays/portfolio/vue/src/main.ts +6 -0
- package/templates/overlays/portfolio/vue/src/pages/About.vue +30 -0
- package/templates/overlays/portfolio/vue/src/pages/Contact.vue +47 -0
- package/templates/overlays/portfolio/vue/src/pages/Home.vue +27 -0
- package/templates/overlays/portfolio/vue/src/pages/Projects.vue +33 -0
- package/templates/overlays/portfolio/vue/src/router.ts +19 -0
- package/templates/overlays/portfolio/vue/src/style.css +404 -0
- package/templates/react/package.json +23 -19
- package/templates/react/tsconfig.json +20 -0
- package/templates/styling/tailwind/deps.json +7 -6
- package/templates/styling/tailwind/nextjs/postcss.config.mjs +7 -0
- package/templates/styling/tailwind/nextjs/src/app/globals.css +1 -0
- package/templates/styling/tailwind/react/src/index.css +1 -0
- package/templates/styling/tailwind/react/vite.config.ts +7 -0
- package/templates/styling/tailwind/vanilla/src/style.css +1 -0
- package/templates/styling/tailwind/vanilla/vite.config.ts +6 -0
- package/templates/styling/tailwind/vue/src/style.css +1 -0
- package/templates/styling/tailwind/vue/vite.config.ts +7 -0
- package/templates/vanilla/package.json +15 -14
- package/templates/vanilla/tsconfig.json +19 -0
- package/templates/vue/package.json +21 -18
- package/templates/vue/tsconfig.json +20 -0
- package/templates/overlays/blog/react/src/components/PostList.tsx +0 -27
- package/templates/overlays/crm/react/src/components/Filters.tsx +0 -22
- package/templates/overlays/ecommerce/react/src/components/Cart.tsx +0 -47
- package/templates/overlays/ecommerce/react/src/components/ProductGrid.tsx +0 -32
- package/templates/overlays/ecommerce/vue/src/components/CartPanel.vue +0 -46
- package/templates/overlays/ecommerce/vue/src/components/ProductGrid.vue +0 -40
- package/templates/overlays/portfolio/react/src/components/ContactForm.tsx +0 -29
- package/templates/overlays/portfolio/react/src/components/HeroSection.tsx +0 -24
- package/templates/overlays/portfolio/react/src/components/Projects.tsx +0 -33
- package/templates/overlays/portfolio/react/src/components/Skills.tsx +0 -27
- package/templates/styling/tailwind/config/postcss.config.js +0 -5
- package/templates/styling/tailwind/config/tailwind.config.js +0 -11
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/* === BLOG TEMPLATE STYLES === */
|
|
2
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
3
|
+
|
|
4
|
+
:root {
|
|
5
|
+
--primary: #4f46e5;
|
|
6
|
+
--primary-hover: #4338ca;
|
|
7
|
+
--dark: #111827;
|
|
8
|
+
--text: #374151;
|
|
9
|
+
--text-light: #6b7280;
|
|
10
|
+
--bg: #f9fafb;
|
|
11
|
+
--white: #ffffff;
|
|
12
|
+
--border: #e5e7eb;
|
|
13
|
+
--radius: 12px;
|
|
14
|
+
--shadow: 0 1px 3px rgba(0,0,0,0.08);
|
|
15
|
+
--shadow-lg: 0 10px 25px rgba(0,0,0,0.1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; color: var(--text); background: var(--bg); line-height: 1.7; }
|
|
19
|
+
a { text-decoration: none; color: inherit; }
|
|
20
|
+
|
|
21
|
+
/* Blog Header */
|
|
22
|
+
.blog-header { background: var(--white); border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 100; }
|
|
23
|
+
.header-container { max-width: 1100px; margin: 0 auto; padding: 0 1.5rem; display: flex; align-items: center; justify-content: space-between; height: 64px; }
|
|
24
|
+
.blog-logo { display: flex; align-items: center; gap: 0.5rem; font-size: 1.25rem; font-weight: 700; color: var(--dark); }
|
|
25
|
+
.logo-icon { font-size: 1.4rem; }
|
|
26
|
+
.blog-nav { display: flex; gap: 1.5rem; }
|
|
27
|
+
.nav-link { color: var(--text); font-weight: 500; transition: color 0.2s; padding: 0.25rem 0; border-bottom: 2px solid transparent; }
|
|
28
|
+
.nav-link:hover { color: var(--primary); }
|
|
29
|
+
.nav-link.active { color: var(--primary); border-bottom-color: var(--primary); }
|
|
30
|
+
|
|
31
|
+
/* Blog Home */
|
|
32
|
+
.blog-home { max-width: 1100px; margin: 0 auto; padding: 2rem 1.5rem; }
|
|
33
|
+
|
|
34
|
+
/* Featured Post */
|
|
35
|
+
.featured-section { margin-bottom: 2.5rem; }
|
|
36
|
+
.post-card.featured { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: center; }
|
|
37
|
+
.post-card.featured .post-image { height: 300px; font-size: 6rem; }
|
|
38
|
+
.post-card.featured .post-title { font-size: 1.5rem; }
|
|
39
|
+
|
|
40
|
+
/* Blog Layout */
|
|
41
|
+
.blog-layout { display: grid; grid-template-columns: 1fr 320px; gap: 2.5rem; align-items: start; }
|
|
42
|
+
|
|
43
|
+
/* Post Card */
|
|
44
|
+
.post-card { display: block; background: var(--white); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); transition: transform 0.2s, box-shadow 0.2s; }
|
|
45
|
+
.post-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
|
|
46
|
+
.post-image { height: 180px; display: flex; align-items: center; justify-content: center; font-size: 3.5rem; background: linear-gradient(135deg, #eef2ff, #e0e7ff); }
|
|
47
|
+
.post-content { padding: 1.25rem; }
|
|
48
|
+
.post-meta { display: flex; align-items: center; gap: 0.75rem; margin-bottom: 0.5rem; }
|
|
49
|
+
.post-category { font-size: 0.75rem; font-weight: 600; color: var(--primary); text-transform: uppercase; letter-spacing: 0.05em; background: #eef2ff; padding: 0.2rem 0.6rem; border-radius: 4px; }
|
|
50
|
+
.post-read-time { font-size: 0.8rem; color: var(--text-light); }
|
|
51
|
+
.post-title { font-size: 1.15rem; font-weight: 700; color: var(--dark); margin-bottom: 0.5rem; line-height: 1.4; }
|
|
52
|
+
.post-excerpt { font-size: 0.9rem; color: var(--text); margin-bottom: 1rem; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
|
53
|
+
.post-author { display: flex; align-items: center; gap: 0.5rem; font-size: 0.85rem; }
|
|
54
|
+
.author-avatar { font-size: 1.2rem; }
|
|
55
|
+
.author-name { font-weight: 600; color: var(--dark); }
|
|
56
|
+
.post-date { color: var(--text-light); }
|
|
57
|
+
|
|
58
|
+
/* Posts Grid */
|
|
59
|
+
.section-title { font-size: 1.35rem; font-weight: 700; color: var(--dark); margin-bottom: 1.25rem; }
|
|
60
|
+
.posts-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 1.5rem; }
|
|
61
|
+
|
|
62
|
+
/* Blog Sidebar */
|
|
63
|
+
.blog-sidebar { position: sticky; top: 80px; }
|
|
64
|
+
.sidebar-widget { background: var(--white); border-radius: var(--radius); padding: 1.25rem; box-shadow: var(--shadow); margin-bottom: 1.25rem; }
|
|
65
|
+
.sidebar-widget h3 { font-size: 1rem; font-weight: 700; color: var(--dark); margin-bottom: 1rem; }
|
|
66
|
+
.category-list { list-style: none; }
|
|
67
|
+
.category-list li { border-bottom: 1px solid var(--border); }
|
|
68
|
+
.category-list li:last-child { border-bottom: none; }
|
|
69
|
+
.category-link { display: flex; justify-content: space-between; padding: 0.6rem 0; font-size: 0.9rem; color: var(--text); transition: color 0.2s; }
|
|
70
|
+
.category-link:hover { color: var(--primary); }
|
|
71
|
+
.category-count { background: var(--bg); padding: 0.1rem 0.5rem; border-radius: 10px; font-size: 0.75rem; font-weight: 600; color: var(--text-light); }
|
|
72
|
+
.popular-list { list-style: none; }
|
|
73
|
+
.popular-link { display: block; padding: 0.6rem 0; border-bottom: 1px solid var(--border); }
|
|
74
|
+
.popular-list li:last-child .popular-link { border-bottom: none; }
|
|
75
|
+
.popular-title { font-size: 0.9rem; font-weight: 600; color: var(--dark); display: block; }
|
|
76
|
+
.popular-date { font-size: 0.75rem; color: var(--text-light); }
|
|
77
|
+
.newsletter-widget p { font-size: 0.85rem; color: var(--text-light); margin-bottom: 0.75rem; }
|
|
78
|
+
.newsletter-input { width: 100%; padding: 0.625rem 0.875rem; border: 1px solid var(--border); border-radius: 8px; font-size: 0.9rem; margin-bottom: 0.75rem; }
|
|
79
|
+
.newsletter-input:focus { outline: none; border-color: var(--primary); }
|
|
80
|
+
|
|
81
|
+
/* Post Detail */
|
|
82
|
+
.post-detail-page { max-width: 1100px; margin: 0 auto; padding: 2rem 1.5rem; }
|
|
83
|
+
.post-article { max-width: 100%; }
|
|
84
|
+
.back-link { display: inline-block; color: var(--primary); font-weight: 500; margin-bottom: 1.5rem; }
|
|
85
|
+
.back-link:hover { text-decoration: underline; }
|
|
86
|
+
.post-detail-header { margin-bottom: 2rem; }
|
|
87
|
+
.post-detail-header h1 { font-size: 2rem; font-weight: 800; color: var(--dark); margin: 0.75rem 0; line-height: 1.3; }
|
|
88
|
+
.post-detail-meta { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; }
|
|
89
|
+
.post-hero-image { height: 300px; display: flex; align-items: center; justify-content: center; font-size: 6rem; background: linear-gradient(135deg, #eef2ff, #e0e7ff); border-radius: var(--radius); margin-bottom: 2rem; }
|
|
90
|
+
.post-body { font-size: 1.05rem; line-height: 1.8; }
|
|
91
|
+
.post-body p { margin-bottom: 1.25rem; }
|
|
92
|
+
.post-tags { display: flex; gap: 0.5rem; margin-top: 2rem; padding-top: 1.5rem; border-top: 1px solid var(--border); }
|
|
93
|
+
.tag { background: #eef2ff; color: var(--primary); padding: 0.3rem 0.75rem; border-radius: 20px; font-size: 0.8rem; font-weight: 500; }
|
|
94
|
+
|
|
95
|
+
/* Category Page */
|
|
96
|
+
.category-page { max-width: 1100px; margin: 0 auto; padding: 2rem 1.5rem; }
|
|
97
|
+
.category-header { margin-bottom: 2rem; }
|
|
98
|
+
.category-header h1 { font-size: 1.75rem; font-weight: 700; color: var(--dark); margin: 0.5rem 0 0.25rem; }
|
|
99
|
+
.category-header p { color: var(--text-light); }
|
|
100
|
+
|
|
101
|
+
/* About Page */
|
|
102
|
+
.about-page { max-width: 800px; margin: 0 auto; padding: 2rem 1.5rem; }
|
|
103
|
+
.about-hero { text-align: center; margin-bottom: 3rem; }
|
|
104
|
+
.about-hero h1 { font-size: 2rem; font-weight: 800; color: var(--dark); margin-bottom: 0.75rem; }
|
|
105
|
+
.about-hero p { font-size: 1.1rem; color: var(--text-light); max-width: 600px; margin: 0 auto; }
|
|
106
|
+
.about-section { margin-bottom: 2.5rem; }
|
|
107
|
+
.about-section h2 { font-size: 1.35rem; font-weight: 700; color: var(--dark); margin-bottom: 1rem; }
|
|
108
|
+
.about-section p { font-size: 1rem; color: var(--text); margin-bottom: 0.75rem; }
|
|
109
|
+
.team-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1.5rem; }
|
|
110
|
+
.team-card { background: var(--white); padding: 1.5rem; border-radius: var(--radius); box-shadow: var(--shadow); text-align: center; }
|
|
111
|
+
.team-avatar { font-size: 3rem; margin-bottom: 0.75rem; }
|
|
112
|
+
.team-card h3 { font-size: 1rem; font-weight: 700; color: var(--dark); }
|
|
113
|
+
.team-role { font-size: 0.8rem; color: var(--primary); font-weight: 600; margin-bottom: 0.5rem; }
|
|
114
|
+
.team-bio { font-size: 0.85rem; color: var(--text-light); }
|
|
115
|
+
.contact-info { display: flex; gap: 2rem; margin-top: 1rem; }
|
|
116
|
+
.contact-item { display: flex; align-items: center; gap: 0.5rem; font-size: 0.95rem; }
|
|
117
|
+
|
|
118
|
+
/* Empty / Not Found */
|
|
119
|
+
.not-found, .empty-state { text-align: center; padding: 3rem 1.5rem; }
|
|
120
|
+
.not-found h2 { color: var(--dark); margin-bottom: 0.5rem; }
|
|
121
|
+
.empty-state p { color: var(--text-light); margin-bottom: 1rem; }
|
|
122
|
+
|
|
123
|
+
/* Buttons */
|
|
124
|
+
.btn { display: inline-block; padding: 0.625rem 1.5rem; border-radius: 8px; font-weight: 600; cursor: pointer; border: none; transition: all 0.2s; font-size: 0.9rem; }
|
|
125
|
+
.btn-primary { background: var(--primary); color: var(--white); }
|
|
126
|
+
.btn-primary:hover { background: var(--primary-hover); }
|
|
127
|
+
.btn-full { width: 100%; text-align: center; }
|
|
128
|
+
|
|
129
|
+
/* Footer */
|
|
130
|
+
.blog-footer { background: var(--dark); color: #d1d5db; padding: 3rem 1.5rem 1.5rem; margin-top: 4rem; }
|
|
131
|
+
.footer-container { max-width: 1100px; margin: 0 auto; }
|
|
132
|
+
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 2rem; margin-bottom: 2rem; }
|
|
133
|
+
.footer-section h3 { color: var(--white); font-size: 1.15rem; margin-bottom: 0.75rem; }
|
|
134
|
+
.footer-section h4 { color: var(--white); font-size: 0.95rem; margin-bottom: 0.75rem; }
|
|
135
|
+
.footer-section p { font-size: 0.85rem; line-height: 1.6; }
|
|
136
|
+
.footer-section ul { list-style: none; }
|
|
137
|
+
.footer-section li { padding: 0.2rem 0; font-size: 0.85rem; cursor: pointer; }
|
|
138
|
+
.footer-section li:hover, .footer-section a:hover { color: var(--white); }
|
|
139
|
+
.social-links { display: flex; gap: 1rem; font-size: 1.4rem; }
|
|
140
|
+
.footer-bottom { border-top: 1px solid #374151; padding-top: 1.5rem; text-align: center; font-size: 0.8rem; }
|
|
141
|
+
|
|
142
|
+
/* Responsive */
|
|
143
|
+
@media (max-width: 768px) {
|
|
144
|
+
.blog-layout { grid-template-columns: 1fr; }
|
|
145
|
+
.post-card.featured { grid-template-columns: 1fr; }
|
|
146
|
+
.post-card.featured .post-image { height: 200px; font-size: 4rem; }
|
|
147
|
+
.posts-grid { grid-template-columns: 1fr; }
|
|
148
|
+
.post-detail-header h1 { font-size: 1.5rem; }
|
|
149
|
+
.post-hero-image { height: 200px; font-size: 4rem; }
|
|
150
|
+
.footer-grid { grid-template-columns: 1fr 1fr; }
|
|
151
|
+
.team-grid { grid-template-columns: 1fr; }
|
|
152
|
+
.contact-info { flex-direction: column; gap: 0.75rem; }
|
|
153
|
+
.blog-nav { gap: 0.75rem; }
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@media (max-width: 480px) {
|
|
157
|
+
.footer-grid { grid-template-columns: 1fr; }
|
|
158
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import './globals.css';
|
|
2
|
+
import { BlogHeader } from './components/BlogHeader';
|
|
3
|
+
import { BlogFooter } from './components/BlogFooter';
|
|
4
|
+
|
|
5
|
+
export const metadata = {
|
|
6
|
+
title: '{{projectName}} - Blog',
|
|
7
|
+
description: 'Latest articles and insights from {{projectName}}',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
11
|
+
return (
|
|
12
|
+
<html lang="en">
|
|
13
|
+
<body>
|
|
14
|
+
<BlogHeader />
|
|
15
|
+
<main>{children}</main>
|
|
16
|
+
<BlogFooter />
|
|
17
|
+
</body>
|
|
18
|
+
</html>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { PostCard, Post } from './components/PostCard';
|
|
2
|
+
import { BlogSidebar } from './components/BlogSidebar';
|
|
3
|
+
|
|
4
|
+
const posts: Post[] = [
|
|
5
|
+
{ id: 1, title: 'Getting Started with Next.js 15', excerpt: 'Learn the fundamentals of Next.js 15 App Router, server components, and file-based routing in this comprehensive guide.', content: '', author: 'Alex Rivera', date: 'Jan 15, 2025', category: 'Technology', readTime: '8 min read', image: '⚛️', authorAvatar: '👨💻' },
|
|
6
|
+
{ id: 2, title: 'Building Better User Interfaces', excerpt: 'Explore modern UI patterns and best practices for creating intuitive, accessible, and beautiful user interfaces.', content: '', author: 'Priya Sharma', date: 'Jan 12, 2025', category: 'Design', readTime: '6 min read', image: '🎨', authorAvatar: '👩🎨' },
|
|
7
|
+
{ id: 3, title: 'Design Systems That Scale', excerpt: 'How to build and maintain design systems that grow with your organization while maintaining consistency.', content: '', author: 'Marcus Chen', date: 'Jan 10, 2025', category: 'Design', readTime: '10 min read', image: '📐', authorAvatar: '👨' },
|
|
8
|
+
{ id: 4, title: 'TypeScript Tips and Tricks', excerpt: 'Advanced TypeScript patterns that will make your code more type-safe, readable, and maintainable.', content: '', author: 'Sofia Andersen', date: 'Jan 8, 2025', category: 'Technology', readTime: '7 min read', image: '📘', authorAvatar: '👩' },
|
|
9
|
+
{ id: 5, title: 'The Future of Web Development', excerpt: 'A look at emerging trends and technologies that are shaping the future of how we build for the web.', content: '', author: 'Alex Rivera', date: 'Jan 3, 2025', category: 'Technology', readTime: '12 min read', image: '🌐', authorAvatar: '👨💻' },
|
|
10
|
+
{ id: 6, title: 'Mastering CSS Grid Layout', excerpt: 'A deep dive into CSS Grid with practical examples for creating complex, responsive layouts with ease.', content: '', author: 'Priya Sharma', date: 'Dec 28, 2024', category: 'Tutorial', readTime: '9 min read', image: '📏', authorAvatar: '👩🎨' },
|
|
11
|
+
];
|
|
12
|
+
|
|
13
|
+
export default function BlogHomePage() {
|
|
14
|
+
const featuredPost = posts[0];
|
|
15
|
+
const remainingPosts = posts.slice(1);
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<div className="blog-home">
|
|
19
|
+
<section className="featured-section">
|
|
20
|
+
<PostCard post={featuredPost} featured />
|
|
21
|
+
</section>
|
|
22
|
+
|
|
23
|
+
<div className="blog-layout">
|
|
24
|
+
<section className="posts-list">
|
|
25
|
+
<h2 className="section-title">Latest Articles</h2>
|
|
26
|
+
<div className="posts-grid">
|
|
27
|
+
{remainingPosts.map((post) => (
|
|
28
|
+
<PostCard key={post.id} post={post} />
|
|
29
|
+
))}
|
|
30
|
+
</div>
|
|
31
|
+
</section>
|
|
32
|
+
<BlogSidebar />
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useParams } from 'next/navigation';
|
|
4
|
+
import Link from 'next/link';
|
|
5
|
+
import { BlogSidebar } from '../../components/BlogSidebar';
|
|
6
|
+
|
|
7
|
+
interface Post {
|
|
8
|
+
id: number;
|
|
9
|
+
title: string;
|
|
10
|
+
excerpt: string;
|
|
11
|
+
content: string;
|
|
12
|
+
author: string;
|
|
13
|
+
date: string;
|
|
14
|
+
category: string;
|
|
15
|
+
readTime: string;
|
|
16
|
+
image: string;
|
|
17
|
+
authorAvatar: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const posts: Post[] = [
|
|
21
|
+
{ id: 1, title: 'Getting Started with Next.js 15', excerpt: 'Learn the fundamentals of Next.js 15 App Router.', content: 'Next.js 15 introduces powerful features that make building web applications easier than ever. The App Router provides a new way to structure your application with file-based routing, server components, and streaming.\n\nThe App Router uses a file-system based approach where folders define routes. Each folder represents a route segment that maps to a URL segment. Special files like page.tsx, layout.tsx, and loading.tsx provide the UI for each route.\n\nServer Components are the default in the App Router. They allow you to render components on the server, reducing the JavaScript bundle sent to the client. This results in faster page loads and better performance.\n\nFile-based routing is intuitive and powerful. Simply create a page.tsx file in a folder, and it becomes a route. Dynamic routes use bracket notation like [id], and you can nest routes by nesting folders.\n\nStreaming allows you to progressively render UI from the server. Work is split into chunks and streamed to the client as it becomes ready. This means users can see parts of the page before the entire content has finished loading.', author: 'Alex Rivera', date: 'Jan 15, 2025', category: 'Technology', readTime: '8 min read', image: '⚛️', authorAvatar: '👨💻' },
|
|
22
|
+
{ id: 2, title: 'Building Better User Interfaces', excerpt: 'Explore modern UI patterns and best practices.', content: 'Creating great user interfaces is both an art and a science. It requires understanding user psychology, visual design principles, and modern web technologies.\n\nStart with user research to understand who your users are and what they need. Create personas and user journeys to guide your design decisions. Every interface element should serve a purpose.\n\nConsistency is key to a good UI. Use a design system with defined colors, typography, spacing, and components. This ensures a cohesive experience across your entire application.\n\nAccessibility should be built in from the start, not added as an afterthought. Use semantic HTML, provide alt text for images, ensure sufficient color contrast, and make sure all interactive elements are keyboard accessible.\n\nPerformance directly impacts user experience. Optimize images, minimize JavaScript, and use loading states to keep users informed. A fast interface feels more responsive and professional.', author: 'Priya Sharma', date: 'Jan 12, 2025', category: 'Design', readTime: '6 min read', image: '🎨', authorAvatar: '👩🎨' },
|
|
23
|
+
{ id: 3, title: 'Design Systems That Scale', excerpt: 'Build and maintain design systems that grow.', content: 'A design system is more than a component library. It is a complete set of standards, documentation, and tools that help teams build consistent digital products.\n\nStart small and grow organically. Do not try to design every component upfront. Begin with the most commonly used elements: buttons, inputs, typography, and spacing. Add new components as needs arise.\n\nDocumentation is crucial. Each component should have clear usage guidelines, code examples, and accessibility notes. Good documentation reduces questions and ensures proper usage.\n\nVersion your design system carefully. Use semantic versioning so consumers know what to expect with each update. Provide migration guides for breaking changes.\n\nMeasure adoption and gather feedback. Track which components are most used, identify pain points, and continuously improve based on real-world usage data.', author: 'Marcus Chen', date: 'Jan 10, 2025', category: 'Design', readTime: '10 min read', image: '📐', authorAvatar: '👨' },
|
|
24
|
+
{ id: 4, title: 'TypeScript Tips and Tricks', excerpt: 'Advanced TypeScript patterns for better code.', content: 'TypeScript adds static typing to JavaScript, catching errors at compile time and improving developer experience. Here are some advanced patterns to level up your TypeScript code.\n\nUtility types like Partial, Required, Pick, and Omit let you transform existing types without repeating yourself. They are essential for creating flexible, reusable type definitions.\n\nConditional types allow you to create types that depend on conditions. Combined with generics, they enable powerful type-level programming that can express complex relationships.\n\nTemplate literal types let you create string types from patterns. They are perfect for defining valid CSS values, API endpoints, or any structured string format.\n\nThe satisfies operator, introduced in TypeScript 4.9, lets you validate that an expression matches a type without changing the inferred type. This is useful for catching errors while preserving narrow types.', author: 'Sofia Andersen', date: 'Jan 8, 2025', category: 'Technology', readTime: '7 min read', image: '📘', authorAvatar: '👩' },
|
|
25
|
+
{ id: 5, title: 'The Future of Web Development', excerpt: 'Emerging trends and technologies shaping the web.', content: 'The web is constantly evolving, and staying ahead of trends is crucial for developers. Here is a look at what is shaping the future of web development.\n\nEdge computing is bringing server-side logic closer to users. Frameworks like Next.js and platforms like Vercel and Cloudflare Workers enable code to run at the edge, reducing latency and improving performance.\n\nAI-powered development tools are changing how we write code. From code completion to automated testing, AI assistants are becoming integral to the development workflow.\n\nWeb Components are gaining traction as a framework-agnostic way to build reusable UI components. They work everywhere HTML works and can be used alongside any framework.\n\nWebAssembly continues to expand the capabilities of the web. Languages like Rust and Go can now run in the browser at near-native speed, enabling complex applications that were previously desktop-only.', author: 'Alex Rivera', date: 'Jan 3, 2025', category: 'Technology', readTime: '12 min read', image: '🌐', authorAvatar: '👨💻' },
|
|
26
|
+
{ id: 6, title: 'Mastering CSS Grid Layout', excerpt: 'A deep dive into CSS Grid with practical examples.', content: 'CSS Grid is one of the most powerful layout systems available in CSS. It allows you to create complex, responsive layouts with clean, readable code.\n\nGrid works in two dimensions: rows and columns. Unlike Flexbox which is one-dimensional, Grid lets you control both axes simultaneously. This makes it perfect for page-level layouts.\n\nThe fr unit is unique to Grid and represents a fraction of available space. It is more flexible than percentages because it accounts for gaps and fixed-size tracks automatically.\n\nGrid areas let you name regions of your layout and place items into them by name. This makes your CSS more readable and easier to maintain, especially for complex layouts.\n\nThe minmax function combined with auto-fill or auto-fit creates responsive grids without media queries. The grid automatically adjusts the number of columns based on available space.', author: 'Priya Sharma', date: 'Dec 28, 2024', category: 'Tutorial', readTime: '9 min read', image: '📏', authorAvatar: '👩🎨' },
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
export default function PostDetailPage() {
|
|
30
|
+
const params = useParams();
|
|
31
|
+
const post = posts.find((p) => p.id === Number(params.id));
|
|
32
|
+
|
|
33
|
+
if (!post) {
|
|
34
|
+
return (
|
|
35
|
+
<div className="not-found">
|
|
36
|
+
<h2>Post Not Found</h2>
|
|
37
|
+
<p>The article you are looking for does not exist.</p>
|
|
38
|
+
<Link href="/" className="btn btn-primary">Back to Blog</Link>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<div className="post-detail-page">
|
|
45
|
+
<div className="blog-layout">
|
|
46
|
+
<article className="post-article">
|
|
47
|
+
<Link href="/" className="back-link">← Back to Blog</Link>
|
|
48
|
+
<div className="post-detail-header">
|
|
49
|
+
<Link href={`/category/${post.category.toLowerCase()}`} className="post-category">
|
|
50
|
+
{post.category}
|
|
51
|
+
</Link>
|
|
52
|
+
<h1>{post.title}</h1>
|
|
53
|
+
<div className="post-detail-meta">
|
|
54
|
+
<div className="post-author">
|
|
55
|
+
<span className="author-avatar">{post.authorAvatar}</span>
|
|
56
|
+
<span className="author-name">{post.author}</span>
|
|
57
|
+
</div>
|
|
58
|
+
<span className="post-date">{post.date}</span>
|
|
59
|
+
<span className="post-read-time">{post.readTime}</span>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
<div className="post-hero-image">{post.image}</div>
|
|
63
|
+
<div className="post-body">
|
|
64
|
+
{post.content.split('\n\n').map((paragraph, i) => (
|
|
65
|
+
<p key={i}>{paragraph}</p>
|
|
66
|
+
))}
|
|
67
|
+
</div>
|
|
68
|
+
<div className="post-tags">
|
|
69
|
+
<span className="tag">#{post.category.toLowerCase()}</span>
|
|
70
|
+
<span className="tag">#webdev</span>
|
|
71
|
+
<span className="tag">#programming</span>
|
|
72
|
+
</div>
|
|
73
|
+
</article>
|
|
74
|
+
<BlogSidebar />
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
);
|
|
78
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<NuxtLayout>
|
|
3
|
+
<NuxtPage />
|
|
4
|
+
</NuxtLayout>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<style>
|
|
8
|
+
*,
|
|
9
|
+
*::before,
|
|
10
|
+
*::after {
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
box-sizing: border-box;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
body {
|
|
17
|
+
font-family: 'Georgia', 'Times New Roman', serif;
|
|
18
|
+
color: #374151;
|
|
19
|
+
background-color: #f9fafb;
|
|
20
|
+
line-height: 1.8;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
a {
|
|
24
|
+
text-decoration: none;
|
|
25
|
+
color: inherit;
|
|
26
|
+
}
|
|
27
|
+
</style>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<footer class="blog-footer">
|
|
3
|
+
<div class="footer-inner">
|
|
4
|
+
<p>© 2024 {{projectName}}. All rights reserved.</p>
|
|
5
|
+
<div class="footer-links">
|
|
6
|
+
<NuxtLink to="/">Home</NuxtLink>
|
|
7
|
+
<NuxtLink to="/about">About</NuxtLink>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
</footer>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<style scoped>
|
|
14
|
+
.blog-footer {
|
|
15
|
+
background: #111827;
|
|
16
|
+
color: #9ca3af;
|
|
17
|
+
padding: 1.5rem 1rem;
|
|
18
|
+
margin-top: auto;
|
|
19
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.footer-inner {
|
|
23
|
+
max-width: 1100px;
|
|
24
|
+
margin: 0 auto;
|
|
25
|
+
display: flex;
|
|
26
|
+
align-items: center;
|
|
27
|
+
justify-content: space-between;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.footer-inner p {
|
|
31
|
+
font-size: 0.875rem;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.footer-links {
|
|
35
|
+
display: flex;
|
|
36
|
+
gap: 1.25rem;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.footer-links a {
|
|
40
|
+
color: #9ca3af;
|
|
41
|
+
font-size: 0.875rem;
|
|
42
|
+
transition: color 0.2s;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.footer-links a:hover {
|
|
46
|
+
color: white;
|
|
47
|
+
}
|
|
48
|
+
</style>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<header class="blog-header">
|
|
3
|
+
<div class="header-inner">
|
|
4
|
+
<NuxtLink to="/" class="logo">📝 {{projectName}}</NuxtLink>
|
|
5
|
+
<nav class="header-nav">
|
|
6
|
+
<NuxtLink to="/" class="nav-link">Home</NuxtLink>
|
|
7
|
+
<NuxtLink to="/about" class="nav-link">About</NuxtLink>
|
|
8
|
+
</nav>
|
|
9
|
+
</div>
|
|
10
|
+
</header>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<style scoped>
|
|
14
|
+
.blog-header {
|
|
15
|
+
background: #111827;
|
|
16
|
+
color: white;
|
|
17
|
+
padding: 0 1rem;
|
|
18
|
+
position: sticky;
|
|
19
|
+
top: 0;
|
|
20
|
+
z-index: 100;
|
|
21
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.header-inner {
|
|
25
|
+
max-width: 1100px;
|
|
26
|
+
margin: 0 auto;
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
justify-content: space-between;
|
|
30
|
+
height: 64px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.logo {
|
|
34
|
+
font-size: 1.35rem;
|
|
35
|
+
font-weight: 700;
|
|
36
|
+
color: white;
|
|
37
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.header-nav {
|
|
41
|
+
display: flex;
|
|
42
|
+
gap: 1.5rem;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.nav-link {
|
|
46
|
+
color: #d1d5db;
|
|
47
|
+
font-weight: 500;
|
|
48
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
49
|
+
transition: color 0.2s;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.nav-link:hover {
|
|
53
|
+
color: white;
|
|
54
|
+
}
|
|
55
|
+
</style>
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const categories = [
|
|
3
|
+
{ name: 'Technology', slug: 'technology', count: 3 },
|
|
4
|
+
{ name: 'Design', slug: 'design', count: 2 },
|
|
5
|
+
{ name: 'Business', slug: 'business', count: 2 },
|
|
6
|
+
{ name: 'Lifestyle', slug: 'lifestyle', count: 1 },
|
|
7
|
+
];
|
|
8
|
+
|
|
9
|
+
const email = ref('');
|
|
10
|
+
|
|
11
|
+
function handleSubscribe() {
|
|
12
|
+
if (email.value) {
|
|
13
|
+
alert('Thanks for subscribing!');
|
|
14
|
+
email.value = '';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<template>
|
|
20
|
+
<aside class="blog-sidebar">
|
|
21
|
+
<div class="sidebar-card">
|
|
22
|
+
<h3 class="sidebar-title">Categories</h3>
|
|
23
|
+
<ul class="category-list">
|
|
24
|
+
<li v-for="cat in categories" :key="cat.slug">
|
|
25
|
+
<NuxtLink :to="`/category/${cat.slug}`" class="category-link">
|
|
26
|
+
<span>{{ cat.name }}</span>
|
|
27
|
+
<span class="category-count">{{ cat.count }}</span>
|
|
28
|
+
</NuxtLink>
|
|
29
|
+
</li>
|
|
30
|
+
</ul>
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<div class="sidebar-card">
|
|
34
|
+
<h3 class="sidebar-title">Newsletter</h3>
|
|
35
|
+
<p class="newsletter-desc">Get the latest posts delivered to your inbox.</p>
|
|
36
|
+
<form class="newsletter-form" @submit.prevent="handleSubscribe">
|
|
37
|
+
<input
|
|
38
|
+
v-model="email"
|
|
39
|
+
type="email"
|
|
40
|
+
placeholder="your@email.com"
|
|
41
|
+
class="newsletter-input"
|
|
42
|
+
required
|
|
43
|
+
/>
|
|
44
|
+
<button type="submit" class="newsletter-btn">Subscribe</button>
|
|
45
|
+
</form>
|
|
46
|
+
</div>
|
|
47
|
+
</aside>
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
<style scoped>
|
|
51
|
+
.blog-sidebar {
|
|
52
|
+
display: flex;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
gap: 1.25rem;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.sidebar-card {
|
|
58
|
+
background: white;
|
|
59
|
+
border-radius: 10px;
|
|
60
|
+
padding: 1.5rem;
|
|
61
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.sidebar-title {
|
|
65
|
+
font-size: 1.1rem;
|
|
66
|
+
color: #111827;
|
|
67
|
+
margin-bottom: 1rem;
|
|
68
|
+
padding-bottom: 0.75rem;
|
|
69
|
+
border-bottom: 2px solid #e5e7eb;
|
|
70
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.category-list {
|
|
74
|
+
list-style: none;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.category-link {
|
|
78
|
+
display: flex;
|
|
79
|
+
justify-content: space-between;
|
|
80
|
+
align-items: center;
|
|
81
|
+
padding: 0.5rem 0;
|
|
82
|
+
color: #374151;
|
|
83
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
84
|
+
font-size: 0.95rem;
|
|
85
|
+
transition: color 0.2s;
|
|
86
|
+
border-bottom: 1px solid #f3f4f6;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.category-link:hover {
|
|
90
|
+
color: #4f46e5;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.category-count {
|
|
94
|
+
background: #f3f4f6;
|
|
95
|
+
color: #6b7280;
|
|
96
|
+
font-size: 0.75rem;
|
|
97
|
+
font-weight: 600;
|
|
98
|
+
padding: 0.15rem 0.5rem;
|
|
99
|
+
border-radius: 10px;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.newsletter-desc {
|
|
103
|
+
font-size: 0.9rem;
|
|
104
|
+
color: #6b7280;
|
|
105
|
+
margin-bottom: 1rem;
|
|
106
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.newsletter-form {
|
|
110
|
+
display: flex;
|
|
111
|
+
flex-direction: column;
|
|
112
|
+
gap: 0.5rem;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.newsletter-input {
|
|
116
|
+
padding: 0.65rem 0.875rem;
|
|
117
|
+
border: 1px solid #d1d5db;
|
|
118
|
+
border-radius: 8px;
|
|
119
|
+
font-size: 0.9rem;
|
|
120
|
+
outline: none;
|
|
121
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.newsletter-input:focus {
|
|
125
|
+
border-color: #4f46e5;
|
|
126
|
+
box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.newsletter-btn {
|
|
130
|
+
background: #4f46e5;
|
|
131
|
+
color: white;
|
|
132
|
+
border: none;
|
|
133
|
+
padding: 0.65rem;
|
|
134
|
+
border-radius: 8px;
|
|
135
|
+
font-weight: 600;
|
|
136
|
+
cursor: pointer;
|
|
137
|
+
font-family: 'Segoe UI', system-ui, sans-serif;
|
|
138
|
+
transition: background 0.2s;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.newsletter-btn:hover {
|
|
142
|
+
background: #4338ca;
|
|
143
|
+
}
|
|
144
|
+
</style>
|