@beknurakhmed/webforge-cli 0.1.1 → 0.1.2
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/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,10 @@
|
|
|
1
|
+
import { bootstrapApplication } from '@angular/platform-browser';
|
|
2
|
+
import { provideRouter } from '@angular/router';
|
|
3
|
+
import { AppComponent } from './app/app.component';
|
|
4
|
+
import { routes } from './app/app.routes';
|
|
5
|
+
|
|
6
|
+
bootstrapApplication(AppComponent, {
|
|
7
|
+
providers: [
|
|
8
|
+
provideRouter(routes),
|
|
9
|
+
],
|
|
10
|
+
}).catch((err: unknown) => console.error(err));
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import Link from 'next/link';
|
|
4
|
+
import { useCart } from '../components/CartProvider';
|
|
5
|
+
|
|
6
|
+
export default function CartPage() {
|
|
7
|
+
const { items, removeFromCart, updateQuantity, clearCart, totalPrice } = useCart();
|
|
8
|
+
|
|
9
|
+
if (items.length === 0) {
|
|
10
|
+
return (
|
|
11
|
+
<div className="cart-empty">
|
|
12
|
+
<div className="cart-empty-icon">🛒</div>
|
|
13
|
+
<h2>Your cart is empty</h2>
|
|
14
|
+
<p>Looks like you have not added any items to your cart yet.</p>
|
|
15
|
+
<Link href="/" className="btn btn-primary">Continue Shopping</Link>
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div className="cart-page">
|
|
22
|
+
<div className="cart-header">
|
|
23
|
+
<h1>Shopping Cart</h1>
|
|
24
|
+
<button className="btn btn-outline" onClick={clearCart}>Clear Cart</button>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<div className="cart-layout">
|
|
28
|
+
<div className="cart-items">
|
|
29
|
+
{items.map((item) => (
|
|
30
|
+
<div key={item.id} className="cart-item">
|
|
31
|
+
<div className="cart-item-image">{item.image}</div>
|
|
32
|
+
<div className="cart-item-info">
|
|
33
|
+
<h3>{item.name}</h3>
|
|
34
|
+
<p className="cart-item-category">{item.category}</p>
|
|
35
|
+
<p className="cart-item-price">${item.price.toFixed(2)}</p>
|
|
36
|
+
</div>
|
|
37
|
+
<div className="cart-item-actions">
|
|
38
|
+
<div className="quantity-control">
|
|
39
|
+
<button onClick={() => updateQuantity(item.id, item.quantity - 1)}>−</button>
|
|
40
|
+
<span>{item.quantity}</span>
|
|
41
|
+
<button onClick={() => updateQuantity(item.id, item.quantity + 1)}>+</button>
|
|
42
|
+
</div>
|
|
43
|
+
<p className="cart-item-total">${(item.price * item.quantity).toFixed(2)}</p>
|
|
44
|
+
<button className="btn-remove" onClick={() => removeFromCart(item.id)}>🗑️</button>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
))}
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div className="cart-summary">
|
|
51
|
+
<h2>Order Summary</h2>
|
|
52
|
+
<div className="summary-row">
|
|
53
|
+
<span>Subtotal</span>
|
|
54
|
+
<span>${totalPrice.toFixed(2)}</span>
|
|
55
|
+
</div>
|
|
56
|
+
<div className="summary-row">
|
|
57
|
+
<span>Shipping</span>
|
|
58
|
+
<span>{totalPrice > 50 ? 'Free' : '$9.99'}</span>
|
|
59
|
+
</div>
|
|
60
|
+
<div className="summary-row">
|
|
61
|
+
<span>Tax</span>
|
|
62
|
+
<span>${(totalPrice * 0.08).toFixed(2)}</span>
|
|
63
|
+
</div>
|
|
64
|
+
<div className="summary-row total">
|
|
65
|
+
<span>Total</span>
|
|
66
|
+
<span>${(totalPrice + (totalPrice > 50 ? 0 : 9.99) + totalPrice * 0.08).toFixed(2)}</span>
|
|
67
|
+
</div>
|
|
68
|
+
<button className="btn btn-primary btn-lg btn-full">Proceed to Checkout</button>
|
|
69
|
+
<Link href="/" className="continue-link">← Continue Shopping</Link>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, useState, ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
export interface Product {
|
|
6
|
+
id: number;
|
|
7
|
+
name: string;
|
|
8
|
+
price: number;
|
|
9
|
+
image: string;
|
|
10
|
+
category: string;
|
|
11
|
+
rating: number;
|
|
12
|
+
description: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface CartItem extends Product {
|
|
16
|
+
quantity: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface CartContextType {
|
|
20
|
+
items: CartItem[];
|
|
21
|
+
addToCart: (product: Product) => void;
|
|
22
|
+
removeFromCart: (id: number) => void;
|
|
23
|
+
updateQuantity: (id: number, quantity: number) => void;
|
|
24
|
+
clearCart: () => void;
|
|
25
|
+
totalItems: number;
|
|
26
|
+
totalPrice: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const CartContext = createContext<CartContextType | undefined>(undefined);
|
|
30
|
+
|
|
31
|
+
export function CartProvider({ children }: { children: ReactNode }) {
|
|
32
|
+
const [items, setItems] = useState<CartItem[]>([]);
|
|
33
|
+
|
|
34
|
+
const addToCart = (product: Product) => {
|
|
35
|
+
setItems((prev) => {
|
|
36
|
+
const existing = prev.find((item) => item.id === product.id);
|
|
37
|
+
if (existing) {
|
|
38
|
+
return prev.map((item) =>
|
|
39
|
+
item.id === product.id ? { ...item, quantity: item.quantity + 1 } : item
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
return [...prev, { ...product, quantity: 1 }];
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const removeFromCart = (id: number) => {
|
|
47
|
+
setItems((prev) => prev.filter((item) => item.id !== id));
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const updateQuantity = (id: number, quantity: number) => {
|
|
51
|
+
if (quantity <= 0) {
|
|
52
|
+
removeFromCart(id);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
setItems((prev) =>
|
|
56
|
+
prev.map((item) => (item.id === id ? { ...item, quantity } : item))
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const clearCart = () => setItems([]);
|
|
61
|
+
|
|
62
|
+
const totalItems = items.reduce((sum, item) => sum + item.quantity, 0);
|
|
63
|
+
const totalPrice = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
|
|
64
|
+
|
|
65
|
+
return (
|
|
66
|
+
<CartContext.Provider
|
|
67
|
+
value={{ items, addToCart, removeFromCart, updateQuantity, clearCart, totalItems, totalPrice }}
|
|
68
|
+
>
|
|
69
|
+
{children}
|
|
70
|
+
</CartContext.Provider>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function useCart() {
|
|
75
|
+
const context = useContext(CartContext);
|
|
76
|
+
if (!context) {
|
|
77
|
+
throw new Error('useCart must be used within a CartProvider');
|
|
78
|
+
}
|
|
79
|
+
return context;
|
|
80
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export function Footer() {
|
|
2
|
+
return (
|
|
3
|
+
<footer className="footer">
|
|
4
|
+
<div className="footer-container">
|
|
5
|
+
<div className="footer-grid">
|
|
6
|
+
<div className="footer-section">
|
|
7
|
+
<h3>🛍️ {'{{projectName}}'}</h3>
|
|
8
|
+
<p>Your one-stop shop for quality products at great prices.</p>
|
|
9
|
+
</div>
|
|
10
|
+
<div className="footer-section">
|
|
11
|
+
<h4>Shop</h4>
|
|
12
|
+
<ul>
|
|
13
|
+
<li>New Arrivals</li>
|
|
14
|
+
<li>Best Sellers</li>
|
|
15
|
+
<li>Sale Items</li>
|
|
16
|
+
<li>Gift Cards</li>
|
|
17
|
+
</ul>
|
|
18
|
+
</div>
|
|
19
|
+
<div className="footer-section">
|
|
20
|
+
<h4>Support</h4>
|
|
21
|
+
<ul>
|
|
22
|
+
<li>Help Center</li>
|
|
23
|
+
<li>Shipping Info</li>
|
|
24
|
+
<li>Returns</li>
|
|
25
|
+
<li>Contact Us</li>
|
|
26
|
+
</ul>
|
|
27
|
+
</div>
|
|
28
|
+
<div className="footer-section">
|
|
29
|
+
<h4>Follow Us</h4>
|
|
30
|
+
<div className="social-links">
|
|
31
|
+
<span>📘</span>
|
|
32
|
+
<span>🐦</span>
|
|
33
|
+
<span>📷</span>
|
|
34
|
+
<span>📌</span>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
<div className="footer-bottom">
|
|
39
|
+
<p>© 2025 {'{{projectName}}'}. All rights reserved.</p>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
</footer>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import Link from 'next/link';
|
|
4
|
+
import { useCart } from './CartProvider';
|
|
5
|
+
|
|
6
|
+
export function Header() {
|
|
7
|
+
const { totalItems } = useCart();
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<header className="header">
|
|
11
|
+
<div className="header-container">
|
|
12
|
+
<Link href="/" className="logo">
|
|
13
|
+
<span className="logo-icon">🛍️</span>
|
|
14
|
+
<span>{'{{projectName}}'}</span>
|
|
15
|
+
</Link>
|
|
16
|
+
<nav className="nav">
|
|
17
|
+
<Link href="/" className="nav-link">Home</Link>
|
|
18
|
+
<Link href="/cart" className="nav-link cart-link">
|
|
19
|
+
<span>🛒</span>
|
|
20
|
+
<span>Cart</span>
|
|
21
|
+
{totalItems > 0 && <span className="cart-badge">{totalItems}</span>}
|
|
22
|
+
</Link>
|
|
23
|
+
</nav>
|
|
24
|
+
</div>
|
|
25
|
+
</header>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Link from 'next/link';
|
|
2
|
+
import { Product } from './CartProvider';
|
|
3
|
+
|
|
4
|
+
interface ProductCardProps {
|
|
5
|
+
product: Product;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function ProductCard({ product }: ProductCardProps) {
|
|
9
|
+
return (
|
|
10
|
+
<Link href={`/product/${product.id}`} className="product-card">
|
|
11
|
+
<div className="product-image">{product.image}</div>
|
|
12
|
+
<div className="product-info">
|
|
13
|
+
<span className="product-category">{product.category}</span>
|
|
14
|
+
<h3 className="product-name">{product.name}</h3>
|
|
15
|
+
<div className="product-rating">
|
|
16
|
+
{'⭐'.repeat(Math.floor(product.rating))}
|
|
17
|
+
<span className="rating-text">{product.rating}</span>
|
|
18
|
+
</div>
|
|
19
|
+
<p className="product-price">${product.price.toFixed(2)}</p>
|
|
20
|
+
</div>
|
|
21
|
+
</Link>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/* === E-COMMERCE 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.1);
|
|
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.6; }
|
|
19
|
+
a { text-decoration: none; color: inherit; }
|
|
20
|
+
|
|
21
|
+
/* Header */
|
|
22
|
+
.header { background: var(--white); border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 100; }
|
|
23
|
+
.header-container { max-width: 1200px; margin: 0 auto; padding: 0 1.5rem; display: flex; align-items: center; justify-content: space-between; height: 64px; }
|
|
24
|
+
.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.5rem; }
|
|
26
|
+
.nav { display: flex; align-items: center; gap: 1.5rem; }
|
|
27
|
+
.nav-link { color: var(--text); font-weight: 500; transition: color 0.2s; }
|
|
28
|
+
.nav-link:hover { color: var(--primary); }
|
|
29
|
+
.cart-link { display: flex; align-items: center; gap: 0.35rem; position: relative; }
|
|
30
|
+
.cart-badge { background: var(--primary); color: var(--white); font-size: 0.7rem; font-weight: 700; width: 20px; height: 20px; border-radius: 50%; display: flex; align-items: center; justify-content: center; position: absolute; top: -8px; right: -10px; }
|
|
31
|
+
|
|
32
|
+
/* Hero */
|
|
33
|
+
.hero { background: linear-gradient(135deg, var(--primary), #7c3aed); color: var(--white); text-align: center; padding: 4rem 1.5rem; }
|
|
34
|
+
.hero h1 { font-size: 2.5rem; font-weight: 800; margin-bottom: 0.5rem; }
|
|
35
|
+
.hero p { font-size: 1.15rem; opacity: 0.9; margin-bottom: 2rem; }
|
|
36
|
+
.search-bar { max-width: 500px; margin: 0 auto; display: flex; align-items: center; background: var(--white); border-radius: 50px; padding: 0.5rem 1rem; }
|
|
37
|
+
.search-icon { font-size: 1.2rem; margin-right: 0.5rem; }
|
|
38
|
+
.search-bar input { border: none; outline: none; width: 100%; font-size: 1rem; color: var(--text); background: transparent; }
|
|
39
|
+
|
|
40
|
+
/* Products Section */
|
|
41
|
+
.products-section { max-width: 1200px; margin: 0 auto; padding: 2rem 1.5rem; }
|
|
42
|
+
.categories { display: flex; gap: 0.5rem; margin-bottom: 2rem; flex-wrap: wrap; }
|
|
43
|
+
.category-btn { padding: 0.5rem 1.25rem; border: 2px solid var(--border); border-radius: 50px; background: var(--white); cursor: pointer; font-weight: 500; color: var(--text); transition: all 0.2s; }
|
|
44
|
+
.category-btn:hover, .category-btn.active { background: var(--primary); color: var(--white); border-color: var(--primary); }
|
|
45
|
+
.product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1.5rem; }
|
|
46
|
+
|
|
47
|
+
/* Product Card */
|
|
48
|
+
.product-card { background: var(--white); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); transition: transform 0.2s, box-shadow 0.2s; display: block; }
|
|
49
|
+
.product-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
|
|
50
|
+
.product-image { height: 200px; display: flex; align-items: center; justify-content: center; font-size: 4rem; background: #f3f4f6; }
|
|
51
|
+
.product-info { padding: 1rem; }
|
|
52
|
+
.product-category { font-size: 0.75rem; font-weight: 600; color: var(--primary); text-transform: uppercase; letter-spacing: 0.05em; }
|
|
53
|
+
.product-name { font-size: 1.05rem; font-weight: 600; color: var(--dark); margin: 0.25rem 0; }
|
|
54
|
+
.product-rating { display: flex; align-items: center; gap: 0.35rem; font-size: 0.85rem; margin-bottom: 0.5rem; }
|
|
55
|
+
.rating-text { color: var(--text-light); }
|
|
56
|
+
.product-price { font-size: 1.25rem; font-weight: 700; color: var(--primary); }
|
|
57
|
+
|
|
58
|
+
/* Product Detail */
|
|
59
|
+
.product-detail { max-width: 1000px; margin: 0 auto; padding: 2rem 1.5rem; }
|
|
60
|
+
.back-link { display: inline-block; color: var(--primary); font-weight: 500; margin-bottom: 1.5rem; }
|
|
61
|
+
.back-link:hover { text-decoration: underline; }
|
|
62
|
+
.product-detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 3rem; align-items: start; }
|
|
63
|
+
.product-detail-image { height: 400px; display: flex; align-items: center; justify-content: center; font-size: 8rem; background: var(--white); border-radius: var(--radius); box-shadow: var(--shadow); }
|
|
64
|
+
.product-detail-info h1 { font-size: 2rem; color: var(--dark); margin: 0.5rem 0; }
|
|
65
|
+
.product-detail-price { font-size: 2rem; font-weight: 700; color: var(--primary); margin: 1rem 0; }
|
|
66
|
+
.product-description { color: var(--text); line-height: 1.7; margin-bottom: 1.5rem; }
|
|
67
|
+
.product-features { margin-top: 2rem; }
|
|
68
|
+
.product-features h3 { font-size: 1.1rem; color: var(--dark); margin-bottom: 0.75rem; }
|
|
69
|
+
.product-features li { list-style: none; padding: 0.3rem 0; color: var(--text); }
|
|
70
|
+
|
|
71
|
+
/* Cart Page */
|
|
72
|
+
.cart-page { max-width: 1000px; margin: 0 auto; padding: 2rem 1.5rem; }
|
|
73
|
+
.cart-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem; }
|
|
74
|
+
.cart-header h1 { font-size: 1.75rem; color: var(--dark); }
|
|
75
|
+
.cart-layout { display: grid; grid-template-columns: 1fr 360px; gap: 2rem; align-items: start; }
|
|
76
|
+
.cart-items { display: flex; flex-direction: column; gap: 1rem; }
|
|
77
|
+
.cart-item { display: flex; align-items: center; gap: 1rem; background: var(--white); padding: 1rem; border-radius: var(--radius); box-shadow: var(--shadow); }
|
|
78
|
+
.cart-item-image { font-size: 2.5rem; width: 70px; height: 70px; display: flex; align-items: center; justify-content: center; background: #f3f4f6; border-radius: 8px; }
|
|
79
|
+
.cart-item-info { flex: 1; }
|
|
80
|
+
.cart-item-info h3 { font-size: 1rem; color: var(--dark); }
|
|
81
|
+
.cart-item-category { font-size: 0.8rem; color: var(--text-light); }
|
|
82
|
+
.cart-item-price { font-weight: 600; color: var(--primary); }
|
|
83
|
+
.cart-item-actions { display: flex; align-items: center; gap: 1rem; }
|
|
84
|
+
.quantity-control { display: flex; align-items: center; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
|
|
85
|
+
.quantity-control button { width: 32px; height: 32px; border: none; background: var(--bg); cursor: pointer; font-size: 1rem; }
|
|
86
|
+
.quantity-control span { width: 36px; text-align: center; font-weight: 600; }
|
|
87
|
+
.cart-item-total { font-weight: 700; color: var(--dark); min-width: 70px; text-align: right; }
|
|
88
|
+
.btn-remove { background: none; border: none; cursor: pointer; font-size: 1.2rem; }
|
|
89
|
+
|
|
90
|
+
/* Cart Summary */
|
|
91
|
+
.cart-summary { background: var(--white); padding: 1.5rem; border-radius: var(--radius); box-shadow: var(--shadow); position: sticky; top: 80px; }
|
|
92
|
+
.cart-summary h2 { font-size: 1.25rem; color: var(--dark); margin-bottom: 1rem; }
|
|
93
|
+
.summary-row { display: flex; justify-content: space-between; padding: 0.5rem 0; color: var(--text); }
|
|
94
|
+
.summary-row.total { border-top: 2px solid var(--border); margin-top: 0.5rem; padding-top: 1rem; font-size: 1.15rem; font-weight: 700; color: var(--dark); }
|
|
95
|
+
.continue-link { display: block; text-align: center; margin-top: 1rem; color: var(--primary); font-weight: 500; }
|
|
96
|
+
|
|
97
|
+
/* Cart Empty */
|
|
98
|
+
.cart-empty { text-align: center; padding: 4rem 1.5rem; }
|
|
99
|
+
.cart-empty-icon { font-size: 4rem; margin-bottom: 1rem; }
|
|
100
|
+
.cart-empty h2 { color: var(--dark); margin-bottom: 0.5rem; }
|
|
101
|
+
.cart-empty p { color: var(--text-light); margin-bottom: 1.5rem; }
|
|
102
|
+
|
|
103
|
+
/* Not Found */
|
|
104
|
+
.not-found { text-align: center; padding: 4rem 1.5rem; }
|
|
105
|
+
.no-results { text-align: center; padding: 3rem; color: var(--text-light); font-size: 1.1rem; }
|
|
106
|
+
|
|
107
|
+
/* Buttons */
|
|
108
|
+
.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.95rem; }
|
|
109
|
+
.btn-primary { background: var(--primary); color: var(--white); }
|
|
110
|
+
.btn-primary:hover { background: var(--primary-hover); }
|
|
111
|
+
.btn-outline { background: transparent; color: var(--text); border: 2px solid var(--border); }
|
|
112
|
+
.btn-outline:hover { border-color: var(--primary); color: var(--primary); }
|
|
113
|
+
.btn-lg { padding: 0.875rem 2rem; font-size: 1.05rem; }
|
|
114
|
+
.btn-full { width: 100%; text-align: center; }
|
|
115
|
+
|
|
116
|
+
/* Footer */
|
|
117
|
+
.footer { background: var(--dark); color: #d1d5db; padding: 3rem 1.5rem 1.5rem; margin-top: 4rem; }
|
|
118
|
+
.footer-container { max-width: 1200px; margin: 0 auto; }
|
|
119
|
+
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 2rem; margin-bottom: 2rem; }
|
|
120
|
+
.footer-section h3 { color: var(--white); font-size: 1.2rem; margin-bottom: 0.75rem; }
|
|
121
|
+
.footer-section h4 { color: var(--white); font-size: 1rem; margin-bottom: 0.75rem; }
|
|
122
|
+
.footer-section p { font-size: 0.9rem; line-height: 1.6; }
|
|
123
|
+
.footer-section ul { list-style: none; }
|
|
124
|
+
.footer-section li { padding: 0.25rem 0; font-size: 0.9rem; cursor: pointer; }
|
|
125
|
+
.footer-section li:hover { color: var(--white); }
|
|
126
|
+
.social-links { display: flex; gap: 1rem; font-size: 1.5rem; }
|
|
127
|
+
.footer-bottom { border-top: 1px solid #374151; padding-top: 1.5rem; text-align: center; font-size: 0.85rem; }
|
|
128
|
+
|
|
129
|
+
/* Responsive */
|
|
130
|
+
@media (max-width: 768px) {
|
|
131
|
+
.hero h1 { font-size: 1.75rem; }
|
|
132
|
+
.product-detail-grid { grid-template-columns: 1fr; gap: 1.5rem; }
|
|
133
|
+
.product-detail-image { height: 250px; font-size: 5rem; }
|
|
134
|
+
.cart-layout { grid-template-columns: 1fr; }
|
|
135
|
+
.cart-item { flex-wrap: wrap; }
|
|
136
|
+
.cart-item-actions { width: 100%; justify-content: space-between; }
|
|
137
|
+
.footer-grid { grid-template-columns: 1fr 1fr; }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@media (max-width: 480px) {
|
|
141
|
+
.header-container { padding: 0 1rem; }
|
|
142
|
+
.product-grid { grid-template-columns: 1fr; }
|
|
143
|
+
.footer-grid { grid-template-columns: 1fr; }
|
|
144
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import './globals.css';
|
|
2
|
+
import { Header } from './components/Header';
|
|
3
|
+
import { Footer } from './components/Footer';
|
|
4
|
+
import { CartProvider } from './components/CartProvider';
|
|
5
|
+
|
|
6
|
+
export const metadata = {
|
|
7
|
+
title: '{{projectName}} - Online Store',
|
|
8
|
+
description: 'Shop the latest products at {{projectName}}',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
12
|
+
return (
|
|
13
|
+
<html lang="en">
|
|
14
|
+
<body>
|
|
15
|
+
<CartProvider>
|
|
16
|
+
<Header />
|
|
17
|
+
<main>{children}</main>
|
|
18
|
+
<Footer />
|
|
19
|
+
</CartProvider>
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
|
22
|
+
);
|
|
23
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { ProductCard } from './components/ProductCard';
|
|
5
|
+
import { Product } from './components/CartProvider';
|
|
6
|
+
|
|
7
|
+
const products: Product[] = [
|
|
8
|
+
{ id: 1, name: 'Wireless Headphones', price: 79.99, image: '🎧', category: 'Electronics', rating: 4.5, description: 'Premium wireless headphones with noise cancellation and 30-hour battery life. Crystal-clear sound quality for music lovers.' },
|
|
9
|
+
{ id: 2, name: 'Smart Watch', price: 199.99, image: '⌚', category: 'Electronics', rating: 4.7, description: 'Feature-packed smartwatch with health monitoring, GPS tracking, and a vibrant AMOLED display.' },
|
|
10
|
+
{ id: 3, name: 'Running Shoes', price: 129.99, image: '👟', category: 'Sports', rating: 4.3, description: 'Lightweight running shoes with responsive cushioning and breathable mesh upper for maximum comfort.' },
|
|
11
|
+
{ id: 4, name: 'Backpack', price: 59.99, image: '🎒', category: 'Accessories', rating: 4.6, description: 'Durable travel backpack with laptop compartment, water-resistant fabric, and ergonomic design.' },
|
|
12
|
+
{ id: 5, name: 'Coffee Maker', price: 89.99, image: '☕', category: 'Home', rating: 4.4, description: 'Programmable coffee maker with thermal carafe, brew-strength control, and auto-shutoff feature.' },
|
|
13
|
+
{ id: 6, name: 'Desk Lamp', price: 45.99, image: '💡', category: 'Home', rating: 4.2, description: 'Adjustable LED desk lamp with multiple brightness levels, color temperatures, and USB charging port.' },
|
|
14
|
+
{ id: 7, name: 'Yoga Mat', price: 34.99, image: '🧘', category: 'Sports', rating: 4.8, description: 'Non-slip yoga mat with alignment marks, eco-friendly material, and carrying strap included.' },
|
|
15
|
+
{ id: 8, name: 'Sunglasses', price: 149.99, image: '🕶️', category: 'Accessories', rating: 4.1, description: 'Polarized sunglasses with UV400 protection, lightweight titanium frame, and scratch-resistant lenses.' },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
const categories = ['All', ...Array.from(new Set(products.map((p) => p.category)))];
|
|
19
|
+
|
|
20
|
+
export default function HomePage() {
|
|
21
|
+
const [search, setSearch] = useState('');
|
|
22
|
+
const [activeCategory, setActiveCategory] = useState('All');
|
|
23
|
+
|
|
24
|
+
const filtered = products.filter((p) => {
|
|
25
|
+
const matchesSearch = p.name.toLowerCase().includes(search.toLowerCase());
|
|
26
|
+
const matchesCategory = activeCategory === 'All' || p.category === activeCategory;
|
|
27
|
+
return matchesSearch && matchesCategory;
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<div className="home-page">
|
|
32
|
+
<section className="hero">
|
|
33
|
+
<h1>Welcome to {'{{projectName}}'}</h1>
|
|
34
|
+
<p>Discover amazing products at unbeatable prices</p>
|
|
35
|
+
<div className="search-bar">
|
|
36
|
+
<span className="search-icon">🔍</span>
|
|
37
|
+
<input
|
|
38
|
+
type="text"
|
|
39
|
+
placeholder="Search products..."
|
|
40
|
+
value={search}
|
|
41
|
+
onChange={(e) => setSearch(e.target.value)}
|
|
42
|
+
/>
|
|
43
|
+
</div>
|
|
44
|
+
</section>
|
|
45
|
+
|
|
46
|
+
<section className="products-section">
|
|
47
|
+
<div className="categories">
|
|
48
|
+
{categories.map((cat) => (
|
|
49
|
+
<button
|
|
50
|
+
key={cat}
|
|
51
|
+
className={`category-btn ${activeCategory === cat ? 'active' : ''}`}
|
|
52
|
+
onClick={() => setActiveCategory(cat)}
|
|
53
|
+
>
|
|
54
|
+
{cat}
|
|
55
|
+
</button>
|
|
56
|
+
))}
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
<div className="product-grid">
|
|
60
|
+
{filtered.map((product) => (
|
|
61
|
+
<ProductCard key={product.id} product={product} />
|
|
62
|
+
))}
|
|
63
|
+
</div>
|
|
64
|
+
|
|
65
|
+
{filtered.length === 0 && (
|
|
66
|
+
<div className="no-results">
|
|
67
|
+
<p>😕 No products found. Try a different search.</p>
|
|
68
|
+
</div>
|
|
69
|
+
)}
|
|
70
|
+
</section>
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useParams } from 'next/navigation';
|
|
4
|
+
import Link from 'next/link';
|
|
5
|
+
import { useCart, Product } from '../../components/CartProvider';
|
|
6
|
+
|
|
7
|
+
const products: Product[] = [
|
|
8
|
+
{ id: 1, name: 'Wireless Headphones', price: 79.99, image: '🎧', category: 'Electronics', rating: 4.5, description: 'Premium wireless headphones with noise cancellation and 30-hour battery life. Crystal-clear sound quality for music lovers.' },
|
|
9
|
+
{ id: 2, name: 'Smart Watch', price: 199.99, image: '⌚', category: 'Electronics', rating: 4.7, description: 'Feature-packed smartwatch with health monitoring, GPS tracking, and a vibrant AMOLED display.' },
|
|
10
|
+
{ id: 3, name: 'Running Shoes', price: 129.99, image: '👟', category: 'Sports', rating: 4.3, description: 'Lightweight running shoes with responsive cushioning and breathable mesh upper for maximum comfort.' },
|
|
11
|
+
{ id: 4, name: 'Backpack', price: 59.99, image: '🎒', category: 'Accessories', rating: 4.6, description: 'Durable travel backpack with laptop compartment, water-resistant fabric, and ergonomic design.' },
|
|
12
|
+
{ id: 5, name: 'Coffee Maker', price: 89.99, image: '☕', category: 'Home', rating: 4.4, description: 'Programmable coffee maker with thermal carafe, brew-strength control, and auto-shutoff feature.' },
|
|
13
|
+
{ id: 6, name: 'Desk Lamp', price: 45.99, image: '💡', category: 'Home', rating: 4.2, description: 'Adjustable LED desk lamp with multiple brightness levels, color temperatures, and USB charging port.' },
|
|
14
|
+
{ id: 7, name: 'Yoga Mat', price: 34.99, image: '🧘', category: 'Sports', rating: 4.8, description: 'Non-slip yoga mat with alignment marks, eco-friendly material, and carrying strap included.' },
|
|
15
|
+
{ id: 8, name: 'Sunglasses', price: 149.99, image: '🕶️', category: 'Accessories', rating: 4.1, description: 'Polarized sunglasses with UV400 protection, lightweight titanium frame, and scratch-resistant lenses.' },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
export default function ProductDetailPage() {
|
|
19
|
+
const params = useParams();
|
|
20
|
+
const { addToCart } = useCart();
|
|
21
|
+
const product = products.find((p) => p.id === Number(params.id));
|
|
22
|
+
|
|
23
|
+
if (!product) {
|
|
24
|
+
return (
|
|
25
|
+
<div className="not-found">
|
|
26
|
+
<h2>Product Not Found</h2>
|
|
27
|
+
<p>The product you are looking for does not exist.</p>
|
|
28
|
+
<Link href="/" className="btn btn-primary">Back to Shop</Link>
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<div className="product-detail">
|
|
35
|
+
<Link href="/" className="back-link">← Back to Shop</Link>
|
|
36
|
+
<div className="product-detail-grid">
|
|
37
|
+
<div className="product-detail-image">{product.image}</div>
|
|
38
|
+
<div className="product-detail-info">
|
|
39
|
+
<span className="product-category">{product.category}</span>
|
|
40
|
+
<h1>{product.name}</h1>
|
|
41
|
+
<div className="product-rating">
|
|
42
|
+
{'⭐'.repeat(Math.floor(product.rating))}
|
|
43
|
+
<span className="rating-text">{product.rating} / 5.0</span>
|
|
44
|
+
</div>
|
|
45
|
+
<p className="product-detail-price">${product.price.toFixed(2)}</p>
|
|
46
|
+
<p className="product-description">{product.description}</p>
|
|
47
|
+
<button className="btn btn-primary btn-lg" onClick={() => addToCart(product)}>
|
|
48
|
+
🛒 Add to Cart
|
|
49
|
+
</button>
|
|
50
|
+
<div className="product-features">
|
|
51
|
+
<h3>Features</h3>
|
|
52
|
+
<ul>
|
|
53
|
+
<li>✅ Free shipping on orders over $50</li>
|
|
54
|
+
<li>✅ 30-day return policy</li>
|
|
55
|
+
<li>✅ 1-year warranty</li>
|
|
56
|
+
<li>✅ Secure checkout</li>
|
|
57
|
+
</ul>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
);
|
|
63
|
+
}
|
|
@@ -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: 'Segoe UI', system-ui, -apple-system, sans-serif;
|
|
18
|
+
color: #374151;
|
|
19
|
+
background-color: #f9fafb;
|
|
20
|
+
line-height: 1.6;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
a {
|
|
24
|
+
text-decoration: none;
|
|
25
|
+
color: inherit;
|
|
26
|
+
}
|
|
27
|
+
</style>
|