@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
|
@@ -1,41 +1,81 @@
|
|
|
1
|
+
/* Blog Layout */
|
|
1
2
|
.blog { min-height: 100vh; display: flex; flex-direction: column; }
|
|
3
|
+
.blog-main { flex: 1; max-width: 1100px; margin: 0 auto; padding: 2rem; width: 100%; box-sizing: border-box; }
|
|
2
4
|
|
|
5
|
+
/* Header */
|
|
3
6
|
.blog-header { border-bottom: 1px solid #e5e7eb; }
|
|
4
|
-
.
|
|
5
|
-
.blog-title { font-size: 1.5rem; color: #111827; margin: 0; }
|
|
7
|
+
.header-content { max-width: 1100px; margin: 0 auto; padding: 1.25rem 2rem; display: flex; justify-content: space-between; align-items: center; }
|
|
8
|
+
.blog-title { font-size: 1.5rem; font-weight: 700; color: #111827; margin: 0; text-decoration: none; }
|
|
6
9
|
.blog-nav { display: flex; gap: 1.5rem; }
|
|
7
|
-
.blog-nav a { text-decoration: none; color: #6b7280; font-weight: 500; }
|
|
8
|
-
.blog-nav a:hover,
|
|
10
|
+
.blog-nav a { text-decoration: none; color: #6b7280; font-weight: 500; transition: color 0.15s; }
|
|
11
|
+
.blog-nav a:hover,
|
|
12
|
+
.blog-nav a.active { color: #4f46e5; }
|
|
9
13
|
|
|
10
|
-
|
|
14
|
+
/* Blog Layout Grid */
|
|
15
|
+
.blog-layout { display: grid; grid-template-columns: 1fr 300px; gap: 3rem; }
|
|
11
16
|
|
|
17
|
+
/* Post Cards */
|
|
18
|
+
.post-list { display: flex; flex-direction: column; }
|
|
12
19
|
.post-card { display: flex; gap: 1.5rem; padding: 1.5rem 0; border-bottom: 1px solid #f3f4f6; }
|
|
13
20
|
.post-image { font-size: 3rem; width: 80px; text-align: center; flex-shrink: 0; }
|
|
14
|
-
.post-
|
|
21
|
+
.post-body { flex: 1; }
|
|
22
|
+
.post-category { font-size: 0.75rem; color: #4f46e5; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; text-decoration: none; }
|
|
23
|
+
.post-category:hover { color: #4338ca; }
|
|
24
|
+
.post-title-link { text-decoration: none; }
|
|
15
25
|
.post-title { font-size: 1.25rem; font-weight: 700; color: #111827; margin: 0.25rem 0 0.5rem; }
|
|
26
|
+
.post-title-link:hover .post-title { color: #4f46e5; }
|
|
16
27
|
.post-excerpt { color: #6b7280; line-height: 1.6; margin-bottom: 0.75rem; }
|
|
17
28
|
.post-meta { display: flex; gap: 1rem; font-size: 0.8rem; color: #9ca3af; }
|
|
18
29
|
|
|
30
|
+
/* Sidebar */
|
|
19
31
|
.blog-sidebar { display: flex; flex-direction: column; gap: 2rem; }
|
|
20
32
|
.sidebar-section { background: #f9fafb; padding: 1.5rem; border-radius: 12px; }
|
|
21
33
|
.sidebar-section h3 { font-size: 1rem; font-weight: 600; margin-bottom: 0.75rem; color: #111827; }
|
|
22
34
|
.sidebar-section p { color: #6b7280; font-size: 0.9rem; line-height: 1.5; margin-bottom: 0.75rem; }
|
|
23
35
|
.category-list { display: flex; flex-wrap: wrap; gap: 0.5rem; }
|
|
24
|
-
.category-tag { background: white; border: 1px solid #e5e7eb; padding: 0.25rem 0.75rem; border-radius: 20px; font-size: 0.8rem; color: #374151; text-decoration: none; }
|
|
36
|
+
.category-tag { background: white; border: 1px solid #e5e7eb; padding: 0.25rem 0.75rem; border-radius: 20px; font-size: 0.8rem; color: #374151; text-decoration: none; transition: all 0.15s; }
|
|
25
37
|
.category-tag:hover { border-color: #4f46e5; color: #4f46e5; }
|
|
26
|
-
.newsletter-input { width: 100%; padding: 0.5rem 0.75rem; border: 1px solid #d1d5db; border-radius: 6px; font-size: 0.9rem; margin-bottom: 0.5rem; }
|
|
38
|
+
.newsletter-input { width: 100%; padding: 0.5rem 0.75rem; border: 1px solid #d1d5db; border-radius: 6px; font-size: 0.9rem; margin-bottom: 0.5rem; box-sizing: border-box; }
|
|
27
39
|
.newsletter-btn { width: 100%; background: #4f46e5; color: white; border: none; padding: 0.5rem; border-radius: 6px; cursor: pointer; font-weight: 600; }
|
|
40
|
+
.newsletter-btn:hover { background: #4338ca; }
|
|
28
41
|
|
|
29
|
-
|
|
42
|
+
/* Post Detail */
|
|
43
|
+
.post-detail { max-width: 720px; margin: 0 auto; }
|
|
44
|
+
.back-link { display: inline-block; color: #4f46e5; text-decoration: none; font-size: 0.9rem; margin-bottom: 1.5rem; }
|
|
45
|
+
.back-link:hover { text-decoration: underline; }
|
|
46
|
+
.post-detail-image { font-size: 4rem; display: block; margin-bottom: 1rem; }
|
|
47
|
+
.post-detail-title { font-size: 2rem; font-weight: 800; color: #111827; margin: 0.5rem 0 1rem; }
|
|
48
|
+
.post-detail-content { color: #374151; line-height: 1.8; font-size: 1.05rem; margin: 2rem 0; }
|
|
49
|
+
.author-bio { background: #f9fafb; border-radius: 12px; padding: 1.5rem; margin-top: 2rem; }
|
|
50
|
+
.author-bio h3 { font-size: 1rem; color: #111827; margin-bottom: 0.5rem; }
|
|
51
|
+
.author-bio p { color: #6b7280; line-height: 1.6; }
|
|
52
|
+
|
|
53
|
+
/* Category Page */
|
|
54
|
+
.category-page { max-width: 720px; margin: 0 auto; }
|
|
55
|
+
.category-heading { font-size: 1.75rem; font-weight: 700; color: #111827; margin-bottom: 1.5rem; }
|
|
56
|
+
.no-posts { color: #6b7280; }
|
|
30
57
|
|
|
31
|
-
|
|
58
|
+
/* About Page */
|
|
59
|
+
.about-page { max-width: 720px; margin: 0 auto; }
|
|
60
|
+
.about-title { font-size: 2rem; font-weight: 800; color: #111827; margin-bottom: 1rem; }
|
|
61
|
+
.about-description { color: #374151; line-height: 1.7; font-size: 1.05rem; margin-bottom: 2rem; }
|
|
62
|
+
.author-card { display: flex; gap: 1.5rem; background: #f9fafb; border-radius: 12px; padding: 2rem; margin-bottom: 2rem; }
|
|
63
|
+
.author-avatar { font-size: 3rem; }
|
|
64
|
+
.author-info h2 { font-size: 1.25rem; color: #111827; margin: 0 0 0.25rem; }
|
|
65
|
+
.author-role { color: #4f46e5; font-weight: 600; margin-bottom: 0.5rem; }
|
|
66
|
+
.author-info p { color: #6b7280; line-height: 1.6; }
|
|
67
|
+
.contact-info-section h2 { font-size: 1.25rem; color: #111827; margin-bottom: 0.5rem; }
|
|
68
|
+
.contact-info-section p { color: #6b7280; margin-bottom: 1rem; }
|
|
69
|
+
.contact-links { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 0.5rem; color: #374151; }
|
|
70
|
+
|
|
71
|
+
/* Footer */
|
|
72
|
+
.blog-footer { border-top: 1px solid #e5e7eb; padding: 2rem; text-align: center; color: #9ca3af; font-size: 0.875rem; }
|
|
32
73
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
.blog-
|
|
36
|
-
.post-card {
|
|
37
|
-
.
|
|
38
|
-
.
|
|
39
|
-
.
|
|
40
|
-
.blog-footer { border-color: #374151; }
|
|
74
|
+
/* Responsive */
|
|
75
|
+
@media (max-width: 768px) {
|
|
76
|
+
.blog-layout { grid-template-columns: 1fr; }
|
|
77
|
+
.post-card { flex-direction: column; }
|
|
78
|
+
.header-content { flex-direction: column; gap: 0.75rem; }
|
|
79
|
+
.author-card { flex-direction: column; text-align: center; }
|
|
80
|
+
.post-detail-title { font-size: 1.5rem; }
|
|
41
81
|
}
|
|
@@ -1,38 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
|
2
|
+
import Layout from './components/Layout';
|
|
3
|
+
import Home from './pages/Home';
|
|
4
|
+
import PostDetail from './pages/PostDetail';
|
|
5
|
+
import Category from './pages/Category';
|
|
6
|
+
import About from './pages/About';
|
|
5
7
|
import './App.css';
|
|
6
8
|
|
|
7
|
-
export interface Post {
|
|
8
|
-
id: number;
|
|
9
|
-
title: string;
|
|
10
|
-
excerpt: string;
|
|
11
|
-
author: string;
|
|
12
|
-
date: string;
|
|
13
|
-
category: string;
|
|
14
|
-
readTime: string;
|
|
15
|
-
image: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const posts: Post[] = [
|
|
19
|
-
{ id: 1, title: 'Getting Started with Modern Web Development', excerpt: 'Learn the fundamentals of modern web development including frameworks, build tools, and best practices.', author: 'Beknur', date: 'Feb 20, 2025', category: 'Tutorial', readTime: '5 min', image: '📘' },
|
|
20
|
-
{ id: 2, title: 'Understanding TypeScript Generics', excerpt: 'A deep dive into TypeScript generics and how they can make your code more reusable and type-safe.', author: 'Beknur', date: 'Feb 18, 2025', category: 'TypeScript', readTime: '8 min', image: '📗' },
|
|
21
|
-
{ id: 3, title: 'CSS Grid vs Flexbox: When to Use Which', excerpt: 'A practical comparison of CSS Grid and Flexbox with real-world examples and use cases.', author: 'Beknur', date: 'Feb 15, 2025', category: 'CSS', readTime: '6 min', image: '📙' },
|
|
22
|
-
{ id: 4, title: 'Building Accessible Web Applications', excerpt: 'Best practices for building web applications that are accessible to everyone.', author: 'Beknur', date: 'Feb 12, 2025', category: 'Accessibility', readTime: '7 min', image: '📕' },
|
|
23
|
-
{ id: 5, title: 'State Management in 2025', excerpt: 'An overview of state management solutions and when to use them in modern applications.', author: 'Beknur', date: 'Feb 10, 2025', category: 'Architecture', readTime: '10 min', image: '📓' },
|
|
24
|
-
];
|
|
25
|
-
|
|
26
9
|
function App() {
|
|
27
10
|
return (
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
11
|
+
<BrowserRouter>
|
|
12
|
+
<Routes>
|
|
13
|
+
<Route path="/" element={<Layout />}>
|
|
14
|
+
<Route index element={<Home />} />
|
|
15
|
+
<Route path="post/:id" element={<PostDetail />} />
|
|
16
|
+
<Route path="category/:slug" element={<Category />} />
|
|
17
|
+
<Route path="about" element={<About />} />
|
|
18
|
+
</Route>
|
|
19
|
+
</Routes>
|
|
20
|
+
</BrowserRouter>
|
|
36
21
|
);
|
|
37
22
|
}
|
|
38
23
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
function BlogFooter() {
|
|
2
2
|
return (
|
|
3
3
|
<footer className="blog-footer">
|
|
4
|
-
<p>© 2025 {{projectName}}. Built with passion for the web.</p>
|
|
4
|
+
<p>© 2025 {'{{projectName}}'}. Built with passion for the web.</p>
|
|
5
5
|
</footer>
|
|
6
6
|
);
|
|
7
7
|
}
|
|
8
|
+
|
|
9
|
+
export default BlogFooter;
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
import { NavLink } from 'react-router-dom';
|
|
2
|
+
|
|
3
|
+
function BlogHeader() {
|
|
2
4
|
return (
|
|
3
5
|
<header className="blog-header">
|
|
4
6
|
<div className="header-content">
|
|
5
|
-
<
|
|
7
|
+
<NavLink to="/" className="blog-title">{'{{projectName}}'}</NavLink>
|
|
6
8
|
<nav className="blog-nav">
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
<
|
|
9
|
+
<NavLink to="/" end className={({ isActive }) => isActive ? 'active' : ''}>
|
|
10
|
+
Home
|
|
11
|
+
</NavLink>
|
|
12
|
+
<NavLink to="/about" className={({ isActive }) => isActive ? 'active' : ''}>
|
|
13
|
+
About
|
|
14
|
+
</NavLink>
|
|
11
15
|
</nav>
|
|
12
16
|
</div>
|
|
13
17
|
</header>
|
|
14
18
|
);
|
|
15
19
|
}
|
|
20
|
+
|
|
21
|
+
export default BlogHeader;
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
import { Link } from 'react-router-dom';
|
|
2
|
+
import { categories } from '../data/posts';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
function BlogSidebar() {
|
|
4
5
|
return (
|
|
5
6
|
<aside className="blog-sidebar">
|
|
6
|
-
<div className="sidebar-section">
|
|
7
|
-
<h3>About</h3>
|
|
8
|
-
<p>A blog about modern web development, best practices, and software engineering.</p>
|
|
9
|
-
</div>
|
|
10
7
|
<div className="sidebar-section">
|
|
11
8
|
<h3>Categories</h3>
|
|
12
9
|
<div className="category-list">
|
|
13
|
-
{categories.map((cat
|
|
14
|
-
<
|
|
10
|
+
{categories.map((cat) => (
|
|
11
|
+
<Link key={cat} to={`/category/${cat.toLowerCase()}`} className="category-tag">
|
|
12
|
+
{cat}
|
|
13
|
+
</Link>
|
|
15
14
|
))}
|
|
16
15
|
</div>
|
|
17
16
|
</div>
|
|
@@ -24,3 +23,5 @@ export function BlogSidebar() {
|
|
|
24
23
|
</aside>
|
|
25
24
|
);
|
|
26
25
|
}
|
|
26
|
+
|
|
27
|
+
export default BlogSidebar;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Outlet } from 'react-router-dom';
|
|
2
|
+
import BlogHeader from './BlogHeader';
|
|
3
|
+
import BlogFooter from './BlogFooter';
|
|
4
|
+
|
|
5
|
+
function Layout() {
|
|
6
|
+
return (
|
|
7
|
+
<div className="blog">
|
|
8
|
+
<BlogHeader />
|
|
9
|
+
<main className="blog-main">
|
|
10
|
+
<Outlet />
|
|
11
|
+
</main>
|
|
12
|
+
<BlogFooter />
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export default Layout;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Link } from 'react-router-dom';
|
|
2
|
+
import type { Post } from '../data/posts';
|
|
3
|
+
|
|
4
|
+
interface PostCardProps {
|
|
5
|
+
post: Post;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function PostCard({ post }: PostCardProps) {
|
|
9
|
+
return (
|
|
10
|
+
<article className="post-card">
|
|
11
|
+
<div className="post-image">{post.image}</div>
|
|
12
|
+
<div className="post-body">
|
|
13
|
+
<Link to={`/category/${post.category.toLowerCase()}`} className="post-category">
|
|
14
|
+
{post.category}
|
|
15
|
+
</Link>
|
|
16
|
+
<Link to={`/post/${post.id}`} className="post-title-link">
|
|
17
|
+
<h2 className="post-title">{post.title}</h2>
|
|
18
|
+
</Link>
|
|
19
|
+
<p className="post-excerpt">{post.excerpt}</p>
|
|
20
|
+
<div className="post-meta">
|
|
21
|
+
<span>By {post.author}</span>
|
|
22
|
+
<span>{post.date}</span>
|
|
23
|
+
<span>{post.readTime} read</span>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</article>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default PostCard;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface Post {
|
|
2
|
+
id: number;
|
|
3
|
+
title: string;
|
|
4
|
+
excerpt: string;
|
|
5
|
+
content: string;
|
|
6
|
+
category: string;
|
|
7
|
+
author: string;
|
|
8
|
+
date: string;
|
|
9
|
+
readTime: string;
|
|
10
|
+
image: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const posts: Post[] = [
|
|
14
|
+
{ id: 1, title: 'Getting Started with React 19', excerpt: 'Learn the new features and improvements in the latest React release.', content: 'React 19 introduces several exciting features including the new use hook, server components improvements, and better concurrent rendering. These changes simplify how we build modern web applications and improve both developer experience and end-user performance.', category: 'React', author: 'Jane Developer', date: '2024-12-15', readTime: '5 min', image: '⚛️' },
|
|
15
|
+
{ id: 2, title: 'TypeScript Best Practices in 2025', excerpt: 'Essential patterns and tips for writing clean TypeScript code.', content: 'TypeScript continues to evolve with powerful type inference, template literal types, and satisfies operator. Following best practices ensures your codebase remains maintainable and type-safe as it grows in complexity.', category: 'TypeScript', author: 'Alex Coder', date: '2024-12-10', readTime: '7 min', image: '📘' },
|
|
16
|
+
{ id: 3, title: 'Modern CSS Layout Techniques', excerpt: 'Master CSS Grid and Flexbox for responsive layouts.', content: 'CSS has come a long way with powerful layout tools. Container queries, subgrid, and the :has() selector open up new possibilities for creating responsive, maintainable designs without JavaScript.', category: 'CSS', author: 'Jane Developer', date: '2024-12-05', readTime: '6 min', image: '🎨' },
|
|
17
|
+
{ id: 4, title: 'JavaScript Performance Optimization', excerpt: 'Techniques to make your JavaScript applications faster.', content: 'Performance optimization starts with understanding the browser rendering pipeline. Learn about code splitting, tree shaking, lazy loading, and efficient DOM manipulation to build blazing fast web applications.', category: 'JavaScript', author: 'Mike Engineer', date: '2024-11-28', readTime: '8 min', image: '⚡' },
|
|
18
|
+
{ id: 5, title: 'Building REST APIs with Node.js', excerpt: 'A comprehensive guide to creating robust backend services.', content: 'Node.js provides an excellent foundation for building REST APIs. We cover Express.js setup, middleware patterns, authentication, validation, error handling, and deployment strategies for production-ready APIs.', category: 'Node.js', author: 'Alex Coder', date: '2024-11-20', readTime: '10 min', image: '🖥️' },
|
|
19
|
+
{ id: 6, title: 'CI/CD Pipelines for Frontend Projects', excerpt: 'Automate your build, test, and deployment workflows.', content: 'Setting up CI/CD pipelines transforms your development workflow. Learn how to configure GitHub Actions, automate testing, implement staging environments, and deploy with confidence using modern DevOps practices.', category: 'DevOps', author: 'Mike Engineer', date: '2024-11-15', readTime: '9 min', image: '🚀' },
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export const categories = ['React', 'TypeScript', 'CSS', 'JavaScript', 'Node.js', 'DevOps'];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
function About() {
|
|
2
|
+
return (
|
|
3
|
+
<div className="about-page">
|
|
4
|
+
<h1 className="about-title">About This Blog</h1>
|
|
5
|
+
<p className="about-description">
|
|
6
|
+
A blog dedicated to modern web development, covering topics from frontend frameworks
|
|
7
|
+
to backend architectures and everything in between.
|
|
8
|
+
</p>
|
|
9
|
+
<div className="author-card">
|
|
10
|
+
<div className="author-avatar">✍️</div>
|
|
11
|
+
<div className="author-info">
|
|
12
|
+
<h2>Jane Developer</h2>
|
|
13
|
+
<p className="author-role">Senior Software Engineer</p>
|
|
14
|
+
<p>
|
|
15
|
+
With over 8 years of experience building web applications, I write about
|
|
16
|
+
the tools, techniques, and practices that help developers build better software.
|
|
17
|
+
</p>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<div className="contact-info-section">
|
|
21
|
+
<h2>Get in Touch</h2>
|
|
22
|
+
<p>Have a question or want to collaborate? Reach out anytime.</p>
|
|
23
|
+
<ul className="contact-links">
|
|
24
|
+
<li>Email: hello@devblog.com</li>
|
|
25
|
+
<li>GitHub: @janedev</li>
|
|
26
|
+
<li>Twitter: @janedev</li>
|
|
27
|
+
</ul>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default About;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useParams, Link } from 'react-router-dom';
|
|
2
|
+
import PostCard from '../components/PostCard';
|
|
3
|
+
import { posts } from '../data/posts';
|
|
4
|
+
|
|
5
|
+
function Category() {
|
|
6
|
+
const { slug } = useParams();
|
|
7
|
+
const filtered = posts.filter(
|
|
8
|
+
(p) => p.category.toLowerCase() === slug?.toLowerCase()
|
|
9
|
+
);
|
|
10
|
+
const categoryName = filtered.length > 0 ? filtered[0].category : slug;
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div className="category-page">
|
|
14
|
+
<Link to="/" className="back-link">← Back to Home</Link>
|
|
15
|
+
<h1 className="category-heading">Category: {categoryName}</h1>
|
|
16
|
+
{filtered.length === 0 ? (
|
|
17
|
+
<p className="no-posts">No posts found in this category.</p>
|
|
18
|
+
) : (
|
|
19
|
+
<div className="post-list">
|
|
20
|
+
{filtered.map((post) => (
|
|
21
|
+
<PostCard key={post.id} post={post} />
|
|
22
|
+
))}
|
|
23
|
+
</div>
|
|
24
|
+
)}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export default Category;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import PostCard from '../components/PostCard';
|
|
2
|
+
import BlogSidebar from '../components/BlogSidebar';
|
|
3
|
+
import { posts } from '../data/posts';
|
|
4
|
+
|
|
5
|
+
function Home() {
|
|
6
|
+
return (
|
|
7
|
+
<div className="blog-layout">
|
|
8
|
+
<div className="post-list">
|
|
9
|
+
{posts.map((post) => (
|
|
10
|
+
<PostCard key={post.id} post={post} />
|
|
11
|
+
))}
|
|
12
|
+
</div>
|
|
13
|
+
<BlogSidebar />
|
|
14
|
+
</div>
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default Home;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useParams, Link } from 'react-router-dom';
|
|
2
|
+
import { posts } from '../data/posts';
|
|
3
|
+
|
|
4
|
+
function PostDetail() {
|
|
5
|
+
const { id } = useParams();
|
|
6
|
+
const post = posts.find((p) => p.id === Number(id));
|
|
7
|
+
|
|
8
|
+
if (!post) {
|
|
9
|
+
return <div className="post-detail"><p>Post not found.</p><Link to="/">Back to Home</Link></div>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<div className="post-detail">
|
|
14
|
+
<Link to="/" className="back-link">← Back to Posts</Link>
|
|
15
|
+
<div className="post-detail-header">
|
|
16
|
+
<span className="post-detail-image">{post.image}</span>
|
|
17
|
+
<Link to={`/category/${post.category.toLowerCase()}`} className="post-category">
|
|
18
|
+
{post.category}
|
|
19
|
+
</Link>
|
|
20
|
+
<h1 className="post-detail-title">{post.title}</h1>
|
|
21
|
+
<div className="post-meta">
|
|
22
|
+
<span>By {post.author}</span>
|
|
23
|
+
<span>{post.date}</span>
|
|
24
|
+
<span>{post.readTime} read</span>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<div className="post-detail-content">
|
|
28
|
+
<p>{post.content}</p>
|
|
29
|
+
</div>
|
|
30
|
+
<div className="author-bio">
|
|
31
|
+
<h3>About {post.author}</h3>
|
|
32
|
+
<p>A passionate developer writing about web technologies, best practices, and software engineering.</p>
|
|
33
|
+
</div>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default PostDetail;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { createRouter } from './router';
|
|
2
|
+
import { renderHome } from './pages/home';
|
|
3
|
+
import { renderPostDetail } from './pages/post-detail';
|
|
4
|
+
import { renderCategory } from './pages/category';
|
|
5
|
+
import { renderAbout } from './pages/about';
|
|
6
|
+
import './style.css';
|
|
7
|
+
|
|
8
|
+
export interface Post {
|
|
9
|
+
id: number;
|
|
10
|
+
title: string;
|
|
11
|
+
excerpt: string;
|
|
12
|
+
content: string;
|
|
13
|
+
author: string;
|
|
14
|
+
authorAvatar: string;
|
|
15
|
+
date: string;
|
|
16
|
+
category: string;
|
|
17
|
+
readTime: string;
|
|
18
|
+
image: string;
|
|
19
|
+
tags: string[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const posts: Post[] = [
|
|
23
|
+
{
|
|
24
|
+
id: 1,
|
|
25
|
+
title: 'Getting Started with TypeScript in 2024',
|
|
26
|
+
excerpt: 'Learn the fundamentals of TypeScript and how it can improve your JavaScript development workflow with type safety and better tooling.',
|
|
27
|
+
content: 'TypeScript has become an essential tool in modern web development. In this comprehensive guide, we will explore the core concepts of TypeScript, from basic types to advanced generics. Whether you are a beginner or an experienced developer, understanding TypeScript will significantly improve your code quality and development experience.\n\nTypeScript adds static typing to JavaScript, which means you can catch errors at compile time rather than runtime. This leads to more robust and maintainable code. Let us dive into the key features that make TypeScript a must-learn language in 2024.\n\nFirst, let us talk about type annotations. Type annotations allow you to explicitly specify the type of a variable, function parameter, or return value. This makes your code self-documenting and easier to understand.\n\nNext, we will explore interfaces and type aliases, which let you define custom types that describe the shape of objects. These are incredibly powerful for creating contracts between different parts of your application.',
|
|
28
|
+
author: 'Sarah Chen',
|
|
29
|
+
authorAvatar: '👩',
|
|
30
|
+
date: 'Mar 15, 2024',
|
|
31
|
+
category: 'Technology',
|
|
32
|
+
readTime: '8 min read',
|
|
33
|
+
image: '💻',
|
|
34
|
+
tags: ['TypeScript', 'JavaScript', 'Web Development'],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 2,
|
|
38
|
+
title: 'The Art of Responsive Web Design',
|
|
39
|
+
excerpt: 'Master the principles of responsive design and create websites that look great on every device, from mobile phones to large desktop screens.',
|
|
40
|
+
content: 'Responsive web design is no longer optional, it is a fundamental requirement. With users accessing websites from a myriad of devices, ensuring your site looks and functions well across all screen sizes is crucial for user experience and SEO.\n\nIn this article, we explore modern CSS techniques including Flexbox, Grid, and container queries that make responsive design easier than ever. We will also discuss best practices for mobile-first design and progressive enhancement.',
|
|
41
|
+
author: 'Mike Johnson',
|
|
42
|
+
authorAvatar: '👨',
|
|
43
|
+
date: 'Mar 12, 2024',
|
|
44
|
+
category: 'Design',
|
|
45
|
+
readTime: '6 min read',
|
|
46
|
+
image: '🎨',
|
|
47
|
+
tags: ['CSS', 'Responsive', 'Design'],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 3,
|
|
51
|
+
title: 'Building RESTful APIs with Node.js',
|
|
52
|
+
excerpt: 'A practical guide to creating robust and scalable REST APIs using Node.js, Express, and modern best practices for API design.',
|
|
53
|
+
content: 'RESTful APIs are the backbone of modern web applications. In this tutorial, we walk through building a complete API from scratch using Node.js and Express. You will learn about routing, middleware, error handling, authentication, and database integration.\n\nWe will cover everything from project setup to deployment, including testing strategies and documentation with Swagger/OpenAPI.',
|
|
54
|
+
author: 'Emily Davis',
|
|
55
|
+
authorAvatar: '👩💼',
|
|
56
|
+
date: 'Mar 10, 2024',
|
|
57
|
+
category: 'Technology',
|
|
58
|
+
readTime: '12 min read',
|
|
59
|
+
image: '🔧',
|
|
60
|
+
tags: ['Node.js', 'API', 'Backend'],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: 4,
|
|
64
|
+
title: 'UX Design Principles Every Developer Should Know',
|
|
65
|
+
excerpt: 'Understanding core UX principles can help developers create more intuitive and user-friendly applications from the ground up.',
|
|
66
|
+
content: 'Great user experience does not happen by accident. It is the result of thoughtful design decisions based on understanding how users think and behave. As a developer, knowing these principles can significantly improve the quality of your work.\n\nWe will explore key concepts like cognitive load, Fitts law, Hick law, and the principles of visual hierarchy. These fundamentals will help you make better design decisions in your daily work.',
|
|
67
|
+
author: 'Alex Rivera',
|
|
68
|
+
authorAvatar: '🧑',
|
|
69
|
+
date: 'Mar 8, 2024',
|
|
70
|
+
category: 'Design',
|
|
71
|
+
readTime: '7 min read',
|
|
72
|
+
image: '✨',
|
|
73
|
+
tags: ['UX', 'Design', 'Psychology'],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: 5,
|
|
77
|
+
title: 'State Management Patterns in Modern Apps',
|
|
78
|
+
excerpt: 'Compare different state management approaches and learn which pattern works best for your application architecture.',
|
|
79
|
+
content: 'State management is one of the most debated topics in frontend development. From simple local state to complex global stores, there are many ways to handle application state. This article compares popular approaches and helps you choose the right one.\n\nWe will look at patterns like Flux, Redux, MobX, and newer approaches like Zustand and Jotai, discussing their trade-offs and ideal use cases.',
|
|
80
|
+
author: 'Jordan Lee',
|
|
81
|
+
authorAvatar: '👨💻',
|
|
82
|
+
date: 'Mar 5, 2024',
|
|
83
|
+
category: 'Technology',
|
|
84
|
+
readTime: '10 min read',
|
|
85
|
+
image: '🧩',
|
|
86
|
+
tags: ['State Management', 'Architecture', 'Frontend'],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 6,
|
|
90
|
+
title: 'A Complete Guide to CSS Grid Layout',
|
|
91
|
+
excerpt: 'Master CSS Grid with practical examples and learn how to create complex layouts with minimal code and maximum flexibility.',
|
|
92
|
+
content: 'CSS Grid Layout is one of the most powerful layout systems available in CSS. It allows you to create two-dimensional layouts with rows and columns, giving you unprecedented control over your page structure.\n\nIn this guide, we cover everything from basic grid setup to advanced techniques like named grid areas, auto-fill, auto-fit, and subgrid.',
|
|
93
|
+
author: 'Taylor Kim',
|
|
94
|
+
authorAvatar: '🧑🎨',
|
|
95
|
+
date: 'Mar 2, 2024',
|
|
96
|
+
category: 'Tutorial',
|
|
97
|
+
readTime: '9 min read',
|
|
98
|
+
image: '📐',
|
|
99
|
+
tags: ['CSS', 'Grid', 'Layout'],
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
export const categories = ['All', 'Technology', 'Design', 'Tutorial'];
|
|
104
|
+
|
|
105
|
+
const app = document.querySelector<HTMLElement>('#app')!;
|
|
106
|
+
|
|
107
|
+
createRouter([
|
|
108
|
+
{ path: '/', render: renderHome },
|
|
109
|
+
{ path: '/post/:id', render: renderPostDetail },
|
|
110
|
+
{ path: '/category/:name', render: renderCategory },
|
|
111
|
+
{ path: '/about', render: renderAbout },
|
|
112
|
+
], app);
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { posts, categories } from '../main';
|
|
2
|
+
|
|
3
|
+
export function renderAbout(): string {
|
|
4
|
+
const authors = [
|
|
5
|
+
{ name: 'Sarah Chen', avatar: '👩', role: 'Lead Writer', bio: 'Full-stack developer with a passion for TypeScript and modern web technologies.' },
|
|
6
|
+
{ name: 'Mike Johnson', avatar: '👨', role: 'Design Editor', bio: 'UI/UX designer who loves creating beautiful and accessible web experiences.' },
|
|
7
|
+
{ name: 'Emily Davis', avatar: '👩💼', role: 'Backend Expert', bio: 'Backend engineer specializing in Node.js, APIs, and cloud architecture.' },
|
|
8
|
+
{ name: 'Alex Rivera', avatar: '🧑', role: 'UX Researcher', bio: 'Dedicated to understanding users and improving digital product experiences.' },
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
return `
|
|
12
|
+
<header class="blog-header">
|
|
13
|
+
<div class="header-container">
|
|
14
|
+
<a href="#/" class="blog-logo">📝 {{projectName}}</a>
|
|
15
|
+
<nav class="blog-nav">
|
|
16
|
+
<a href="#/">Home</a>
|
|
17
|
+
${categories.filter(c => c !== 'All').map(c => `
|
|
18
|
+
<a href="#/category/${c}">${c}</a>
|
|
19
|
+
`).join('')}
|
|
20
|
+
<a href="#/about" class="active">About</a>
|
|
21
|
+
</nav>
|
|
22
|
+
</div>
|
|
23
|
+
</header>
|
|
24
|
+
|
|
25
|
+
<main class="blog-main">
|
|
26
|
+
<section class="about-hero">
|
|
27
|
+
<h1>About {{projectName}}</h1>
|
|
28
|
+
<p>We are a community of developers, designers, and creators sharing our knowledge and experiences through thoughtful, well-crafted articles.</p>
|
|
29
|
+
</section>
|
|
30
|
+
|
|
31
|
+
<section class="about-section">
|
|
32
|
+
<div class="about-grid">
|
|
33
|
+
<div class="about-content">
|
|
34
|
+
<h2>Our Mission</h2>
|
|
35
|
+
<p>At {{projectName}}, we believe that knowledge should be accessible to everyone. Our mission is to provide high-quality, practical content that helps developers and designers grow their skills and advance their careers.</p>
|
|
36
|
+
<p>Whether you are just starting out or are a seasoned professional, you will find articles that challenge your thinking and expand your horizons. We cover everything from fundamental concepts to cutting-edge technologies.</p>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="about-stats">
|
|
39
|
+
<div class="about-stat">
|
|
40
|
+
<h3>${posts.length}+</h3>
|
|
41
|
+
<p>Articles Published</p>
|
|
42
|
+
</div>
|
|
43
|
+
<div class="about-stat">
|
|
44
|
+
<h3>10K+</h3>
|
|
45
|
+
<p>Monthly Readers</p>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="about-stat">
|
|
48
|
+
<h3>${categories.length - 1}</h3>
|
|
49
|
+
<p>Categories</p>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="about-stat">
|
|
52
|
+
<h3>4</h3>
|
|
53
|
+
<p>Writers</p>
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</section>
|
|
58
|
+
|
|
59
|
+
<section class="about-section">
|
|
60
|
+
<h2>Our Team</h2>
|
|
61
|
+
<div class="team-grid">
|
|
62
|
+
${authors.map(a => `
|
|
63
|
+
<div class="team-card">
|
|
64
|
+
<div class="team-avatar">${a.avatar}</div>
|
|
65
|
+
<h3>${a.name}</h3>
|
|
66
|
+
<p class="team-role">${a.role}</p>
|
|
67
|
+
<p class="team-bio">${a.bio}</p>
|
|
68
|
+
</div>
|
|
69
|
+
`).join('')}
|
|
70
|
+
</div>
|
|
71
|
+
</section>
|
|
72
|
+
|
|
73
|
+
<section class="about-section">
|
|
74
|
+
<div class="about-cta">
|
|
75
|
+
<h2>Want to Contribute?</h2>
|
|
76
|
+
<p>We are always looking for passionate writers who want to share their expertise. If you have insights to share, we would love to hear from you.</p>
|
|
77
|
+
<a href="#/" class="btn-primary">Get in Touch</a>
|
|
78
|
+
</div>
|
|
79
|
+
</section>
|
|
80
|
+
</main>
|
|
81
|
+
|
|
82
|
+
<footer class="blog-footer">
|
|
83
|
+
<div class="footer-content">
|
|
84
|
+
<div class="footer-section">
|
|
85
|
+
<h4>{{projectName}}</h4>
|
|
86
|
+
<p>Sharing knowledge and insights about web development, design, and technology.</p>
|
|
87
|
+
</div>
|
|
88
|
+
<div class="footer-section">
|
|
89
|
+
<h4>Categories</h4>
|
|
90
|
+
${categories.filter(c => c !== 'All').map(c => `
|
|
91
|
+
<a href="#/category/${c}">${c}</a>
|
|
92
|
+
`).join('')}
|
|
93
|
+
</div>
|
|
94
|
+
<div class="footer-section">
|
|
95
|
+
<h4>Follow Us</h4>
|
|
96
|
+
<a href="#">🐦 Twitter</a>
|
|
97
|
+
<a href="#">💼 LinkedIn</a>
|
|
98
|
+
<a href="#">🐙 GitHub</a>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
<div class="footer-bottom">
|
|
102
|
+
<p>© 2024 {{projectName}}. All rights reserved.</p>
|
|
103
|
+
</div>
|
|
104
|
+
</footer>
|
|
105
|
+
`;
|
|
106
|
+
}
|