@promakeai/cli 0.5.5 → 0.5.7

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.
Files changed (133) hide show
  1. package/README.md +71 -71
  2. package/dist/index.js +251 -251
  3. package/dist/registry/about-page.json +3 -3
  4. package/dist/registry/about-section.json +4 -4
  5. package/dist/registry/animations.json +2 -2
  6. package/dist/registry/announcement-bar.json +4 -4
  7. package/dist/registry/api.json +1 -1
  8. package/dist/registry/auth-core.json +3 -3
  9. package/dist/registry/bento-grid-section.json +4 -4
  10. package/dist/registry/blog-core.json +5 -5
  11. package/dist/registry/blog-list-page.json +4 -4
  12. package/dist/registry/blog-section.json +4 -4
  13. package/dist/registry/cards-carousel-section.json +4 -4
  14. package/dist/registry/cart-drawer.json +4 -4
  15. package/dist/registry/cart-page.json +4 -4
  16. package/dist/registry/case-study-page.json +3 -3
  17. package/dist/registry/category-section.json +4 -4
  18. package/dist/registry/checkout-page.json +4 -4
  19. package/dist/registry/coming-soon-page-minimal.json +4 -4
  20. package/dist/registry/coming-soon-page.json +4 -4
  21. package/dist/registry/contact-info-grid.json +4 -4
  22. package/dist/registry/contact-page-centered.json +4 -4
  23. package/dist/registry/contact-page-map-overlay.json +3 -3
  24. package/dist/registry/contact-page-map-split.json +3 -3
  25. package/dist/registry/contact-page-split.json +4 -4
  26. package/dist/registry/contact-page.json +4 -4
  27. package/dist/registry/content-section.json +4 -4
  28. package/dist/registry/cookie-consent.json +4 -4
  29. package/dist/registry/cookies-page.json +3 -3
  30. package/dist/registry/cta-section.json +3 -3
  31. package/dist/registry/ecommerce-core.json +8 -8
  32. package/dist/registry/empty-page.json +3 -3
  33. package/dist/registry/faq-categorized.json +4 -4
  34. package/dist/registry/faq-simple.json +4 -4
  35. package/dist/registry/favorites-blog-block.json +1 -1
  36. package/dist/registry/favorites-blog-page.json +4 -4
  37. package/dist/registry/favorites-ecommerce-block.json +1 -1
  38. package/dist/registry/favorites-ecommerce-page.json +4 -4
  39. package/dist/registry/feature-section.json +3 -3
  40. package/dist/registry/featured-products.json +4 -4
  41. package/dist/registry/footer-detailed.json +4 -4
  42. package/dist/registry/footer-minimal.json +3 -3
  43. package/dist/registry/footer.json +3 -3
  44. package/dist/registry/forgot-password-page-split.json +4 -4
  45. package/dist/registry/forgot-password-page.json +4 -4
  46. package/dist/registry/google-adsense.json +4 -4
  47. package/dist/registry/google-map.json +2 -2
  48. package/dist/registry/header-centered-pill.json +4 -4
  49. package/dist/registry/header-ecommerce.json +4 -4
  50. package/dist/registry/header-mega.json +4 -4
  51. package/dist/registry/header-minimal.json +4 -4
  52. package/dist/registry/header-simple.json +3 -3
  53. package/dist/registry/hero-carousel.json +3 -3
  54. package/dist/registry/hero-cta.json +4 -4
  55. package/dist/registry/hero-gradient.json +4 -4
  56. package/dist/registry/hero-grid.json +4 -4
  57. package/dist/registry/hero-profile.json +3 -3
  58. package/dist/registry/hero.json +3 -3
  59. package/dist/registry/index.json +103 -103
  60. package/dist/registry/landing-page-app.json +3 -3
  61. package/dist/registry/landing-page-saas.json +3 -3
  62. package/dist/registry/login-page-split.json +4 -4
  63. package/dist/registry/login-page.json +4 -4
  64. package/dist/registry/logo-cloud.json +4 -4
  65. package/dist/registry/masonry-grid.json +3 -3
  66. package/dist/registry/my-orders-page.json +4 -4
  67. package/dist/registry/newsletter-section.json +4 -4
  68. package/dist/registry/order-card-compact.json +1 -1
  69. package/dist/registry/order-confirmation-page.json +4 -4
  70. package/dist/registry/order-detail-block.json +1 -1
  71. package/dist/registry/orders-list-block.json +1 -1
  72. package/dist/registry/payment-success-block.json +2 -2
  73. package/dist/registry/portfolio-page.json +4 -4
  74. package/dist/registry/post-card.json +4 -4
  75. package/dist/registry/post-detail-block.json +2 -2
  76. package/dist/registry/post-detail-page.json +4 -4
  77. package/dist/registry/pricing-card.json +3 -3
  78. package/dist/registry/pricing-page.json +4 -4
  79. package/dist/registry/pricing-section.json +4 -4
  80. package/dist/registry/privacy-page.json +3 -3
  81. package/dist/registry/product-card-detailed.json +4 -4
  82. package/dist/registry/product-card-hover.json +4 -4
  83. package/dist/registry/product-card.json +4 -4
  84. package/dist/registry/product-detail-block.json +2 -2
  85. package/dist/registry/product-detail-page.json +4 -4
  86. package/dist/registry/product-detail-section.json +4 -4
  87. package/dist/registry/product-quick-view.json +4 -4
  88. package/dist/registry/products-page.json +4 -4
  89. package/dist/registry/reading-progress.json +4 -4
  90. package/dist/registry/register-page-split.json +4 -4
  91. package/dist/registry/register-page.json +4 -4
  92. package/dist/registry/related-posts-block.json +1 -1
  93. package/dist/registry/related-products-block.json +2 -2
  94. package/dist/registry/reset-password-page-split.json +4 -4
  95. package/dist/registry/reset-password-page.json +4 -4
  96. package/dist/registry/service-card.json +1 -1
  97. package/dist/registry/share-buttons.json +4 -4
  98. package/dist/registry/skill-card.json +1 -1
  99. package/dist/registry/team-page.json +4 -4
  100. package/dist/registry/terms-page.json +3 -3
  101. package/dist/registry/testimonials-carousel.json +4 -4
  102. package/dist/registry/testimonials-grid.json +4 -4
  103. package/dist/registry/timeline-section.json +4 -4
  104. package/dist/registry/video-hero.json +4 -4
  105. package/dist/registry/youtube-embed.json +4 -4
  106. package/package.json +56 -56
  107. package/template/.env +6 -6
  108. package/template/README.md +54 -54
  109. package/template/eslint.config.js +41 -41
  110. package/template/package.json +95 -95
  111. package/template/public/_redirects +1 -1
  112. package/template/public/robots.txt +14 -14
  113. package/template/scripts/init-db.ts +18 -18
  114. package/template/src/App.tsx +19 -19
  115. package/template/src/components/FormField.tsx +48 -48
  116. package/template/src/components/FormFileInput.tsx +75 -75
  117. package/template/src/components/GoogleAnalytics.tsx +34 -34
  118. package/template/src/components/LanguageSwitcher.tsx +53 -53
  119. package/template/src/{PasswordInput.tsx → components/PasswordInput.tsx} +60 -60
  120. package/template/src/components/ScriptInjector.tsx +62 -62
  121. package/template/src/components/Stack.tsx +39 -39
  122. package/template/src/constants/constants.json +67 -67
  123. package/template/src/db/index.ts +20 -20
  124. package/template/src/db/provider.tsx +78 -78
  125. package/template/src/db/schema.json +258 -258
  126. package/template/src/db/types.ts +195 -195
  127. package/template/src/hooks/use-debounced-value.ts +12 -12
  128. package/template/src/lang/index.ts +90 -90
  129. package/template/src/lib/api.ts +345 -345
  130. package/template/src/lib/env.ts +19 -19
  131. package/template/src/router.tsx +14 -14
  132. package/template/src/vite-env.d.ts +1 -1
  133. package/template/vite.config.ts +64 -64
@@ -14,25 +14,25 @@
14
14
  "path": "header-ecommerce/index.ts",
15
15
  "type": "registry:index",
16
16
  "target": "$modules$/header-ecommerce/index.ts",
17
- "content": "export * from './header-ecommerce';\r\n"
17
+ "content": "export * from './header-ecommerce';\n"
18
18
  },
19
19
  {
20
20
  "path": "header-ecommerce/header-ecommerce.tsx",
21
21
  "type": "registry:component",
22
22
  "target": "$modules$/header-ecommerce/header-ecommerce.tsx",
23
- "content": "import { useState, useMemo } from \"react\";\r\nimport { useDebouncedValue } from \"@/hooks/use-debounced-value\";\r\nimport { Link, useNavigate } from \"react-router\";\r\nimport { ShoppingCart, Menu, Search, Heart, Package, User, LogOut } from \"lucide-react\";\r\nimport { Button } from \"@/components/ui/button\";\r\nimport { Input } from \"@/components/ui/input\";\r\nimport { Badge } from \"@/components/ui/badge\";\r\nimport {\r\n Sheet,\r\n SheetHeader,\r\n SheetTitle,\r\n SheetContent,\r\n SheetTrigger,\r\n} from \"@/components/ui/sheet\";\r\nimport {\r\n Dialog,\r\n DialogContent,\r\n DialogHeader,\r\n DialogTitle,\r\n DialogTrigger,\r\n} from \"@/components/ui/dialog\";\r\nimport {\r\n DropdownMenu,\r\n DropdownMenuContent,\r\n DropdownMenuItem,\r\n DropdownMenuLabel,\r\n DropdownMenuSeparator,\r\n DropdownMenuTrigger,\r\n} from \"@/components/ui/dropdown-menu\";\r\nimport { Logo } from \"@/components/Logo\";\r\nimport { useAuth } from \"@/modules/auth-core\";\r\nimport { CartDrawer } from \"@/modules/cart-drawer\";\r\nimport { toast } from \"sonner\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport constants from \"@/constants/constants.json\";\r\nimport type { Product, Category } from \"@/modules/ecommerce-core/types\";\r\nimport {\r\n useCart,\r\n useFavorites,\r\n formatPrice,\r\n} from \"@/modules/ecommerce-core\";\r\nimport { useDbList } from \"@/db\";\r\n\r\nexport function HeaderEcommerce() {\r\n const [mobileMenuOpen, setMobileMenuOpen] = useState(false);\r\n const [mobileSearchOpen, setMobileSearchOpen] = useState(false);\r\n const [desktopSearchOpen, setDesktopSearchOpen] = useState(false);\r\n const [showResults, setShowResults] = useState(false);\r\n const { itemCount, state } = useCart();\r\n const { favoriteCount } = useFavorites();\r\n const { isAuthenticated, user, logout } = useAuth();\r\n const navigate = useNavigate();\r\n const { t } = useTranslation(\"header-ecommerce\");\r\n\r\n const handleLogout = () => {\r\n logout();\r\n toast.success(t(\"logoutToastTitle\", \"Goodbye!\"), {\r\n description: t(\"logoutToastDesc\", \"You have been logged out successfully.\"),\r\n });\r\n };\r\n\r\n const [searchTerm, setSearchTerm] = useState(\"\");\r\n const debouncedTerm = useDebouncedValue(searchTerm, 300);\r\n const { data: productCategories = [] } = useDbList<Category>(\"product_categories\");\r\n const categoryMap = useMemo(() => new Map(productCategories.map(c => [c.id, c])), [productCategories]);\r\n\r\n const { data: searchResults = [] } = useDbList<Product>(\"products\", {\r\n where: debouncedTerm ? { name: { $like: `%${debouncedTerm}%` } } : {},\r\n limit: 20,\r\n enabled: debouncedTerm.length > 0,\r\n });\r\n\r\n const clearSearch = () => { setSearchTerm(\"\"); };\r\n\r\n const handleSearchSubmit = (e: React.FormEvent) => {\r\n e.preventDefault();\r\n if (searchTerm.trim()) {\r\n navigate(`/products?search=${encodeURIComponent(searchTerm)}`);\r\n setShowResults(false);\r\n setDesktopSearchOpen(false);\r\n clearSearch();\r\n }\r\n };\r\n\r\n const handleSearchFocus = () => {\r\n setShowResults(true);\r\n };\r\n\r\n const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n setSearchTerm(e.target.value);\r\n setShowResults(true);\r\n };\r\n\r\n const navigation = [\r\n { name: t(\"home\"), href: \"/\" },\r\n { name: t(\"products\"), href: \"/products\" },\r\n { name: t(\"about\"), href: \"/about\" },\r\n { name: t(\"contact\"), href: \"/contact\" },\r\n ];\r\n\r\n return (\r\n <header className=\"sticky top-0 z-50 w-full border-b border-border/20 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60\">\r\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-3 sm:px-4 lg:px-8\">\r\n <div className=\"flex h-14 sm:h-16 md:h-20 items-center justify-between gap-2\">\r\n {/* Logo */}\r\n <div className=\"flex-shrink-0 min-w-0\">\r\n <Logo size=\"sm\" className=\"text-base sm:text-xl lg:text-2xl\" />\r\n </div>\r\n\r\n {/* Desktop Navigation - Centered */}\r\n <nav className=\"hidden lg:flex items-center space-x-12 absolute left-1/2 transform -translate-x-1/2\">\r\n {navigation.map((item) => (\r\n <Link\r\n key={item.name}\r\n to={item.href}\r\n className=\"text-base font-medium transition-colors hover:text-primary relative group py-2\"\r\n >\r\n {item.name}\r\n <span className=\"absolute -bottom-1 left-0 w-0 h-0.5 bg-primary transition-all duration-300 group-hover:w-full\"></span>\r\n </Link>\r\n ))}\r\n </nav>\r\n\r\n {/* Search & Actions - Right Aligned */}\r\n <div className=\"flex items-center space-x-1 sm:space-x-2 lg:space-x-4 flex-shrink-0\">\r\n {/* Desktop Search - Modal */}\r\n <Dialog\r\n open={desktopSearchOpen}\r\n onOpenChange={setDesktopSearchOpen}\r\n >\r\n <DialogTrigger asChild>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"hidden lg:flex h-10 w-10\"\r\n >\r\n <Search className=\"h-5 w-5\" />\r\n </Button>\r\n </DialogTrigger>\r\n <DialogContent className=\"sm:max-w-2xl\">\r\n <DialogHeader>\r\n <DialogTitle>\r\n {t(\"searchProducts\", \"Search Products\")}\r\n </DialogTitle>\r\n </DialogHeader>\r\n <div className=\"space-y-4\">\r\n <form onSubmit={handleSearchSubmit}>\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-5 w-5\" />\r\n <Input\r\n type=\"search\"\r\n placeholder={t(\r\n \"searchPlaceholder\",\r\n \"Search for products...\"\r\n )}\r\n value={searchTerm}\r\n onChange={handleSearchChange}\r\n className=\"pl-11 h-12 text-base\"\r\n autoFocus\r\n />\r\n </div>\r\n </form>\r\n\r\n {/* Desktop Search Results */}\r\n {searchTerm.trim() && (\r\n <div className=\"max-h-[400px] overflow-y-auto rounded-lg border bg-card\">\r\n {searchResults.length > 0 ? (\r\n <div className=\"divide-y\">\r\n <div className=\"px-4 py-3 bg-muted/50\">\r\n <p className=\"text-sm font-medium text-muted-foreground\">\r\n {searchResults.length}{\" \"}\r\n {searchResults.length === 1\r\n ? \"result\"\r\n : \"results\"}{\" \"}\r\n found\r\n </p>\r\n </div>\r\n {searchResults.slice(0, 8).map((product: Product) => (\r\n <div key={product.id} className=\"contents\" data-db-table=\"products\" data-db-id={product.id}>\r\n <Link\r\n to={`/products/${product.slug}`}\r\n onClick={() => {\r\n setDesktopSearchOpen(false);\r\n clearSearch();\r\n }}\r\n className=\"flex items-center gap-4 p-4 hover:bg-muted/50 transition-colors\"\r\n >\r\n <img\r\n src={\r\n product.images?.length ? product.images?.[0] : \"/images/placeholder.png\"\r\n }\r\n alt={product.name}\r\n className=\"w-16 h-16 object-cover rounded flex-shrink-0\"\r\n />\r\n <div className=\"flex-1 min-w-0\">\r\n <h4 className=\"font-medium text-base line-clamp-1\">\r\n {product.name}\r\n </h4>\r\n <p className=\"text-sm text-muted-foreground capitalize\">\r\n {categoryMap.get(product.categories?.[0] as number)?.name}\r\n </p>\r\n <p className=\"text-base font-semibold text-primary mt-1\">\r\n {formatPrice(\r\n product.price,\r\n constants.site.currency\r\n )}\r\n </p>\r\n </div>\r\n </Link>\r\n </div>\r\n ))}\r\n {searchResults.length > 8 && (\r\n <div className=\"px-4 py-3 bg-muted/30 text-center\">\r\n <button\r\n onClick={() => {\r\n navigate(\r\n `/products?search=${encodeURIComponent(\r\n searchTerm\r\n )}`\r\n );\r\n setDesktopSearchOpen(false);\r\n clearSearch();\r\n }}\r\n className=\"text-sm font-medium text-primary hover:underline\"\r\n >\r\n {t(\r\n \"viewAllResults\",\r\n `View all ${searchResults.length} results`\r\n )}\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"p-8 text-center\">\r\n <Search className=\"h-12 w-12 text-muted-foreground mx-auto mb-3 opacity-50\" />\r\n <p className=\"text-base text-muted-foreground\">\r\n {t(\"noResults\", \"No products found\")}\r\n </p>\r\n <p className=\"text-sm text-muted-foreground mt-1\">\r\n {t(\r\n \"tryDifferentKeywords\",\r\n \"Try different keywords\"\r\n )}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n </DialogContent>\r\n </Dialog>\r\n\r\n {/* Search - Mobile (Hidden - moved to hamburger menu) */}\r\n <Dialog open={mobileSearchOpen} onOpenChange={setMobileSearchOpen}>\r\n <DialogTrigger asChild>\r\n <Button variant=\"ghost\" size=\"icon\" className=\"hidden\">\r\n <Search className=\"h-4 w-4 sm:h-5 sm:w-5\" />\r\n </Button>\r\n </DialogTrigger>\r\n <DialogContent className=\"sm:max-w-md\">\r\n <DialogHeader>\r\n <DialogTitle>{t(\"searchProducts\")}</DialogTitle>\r\n </DialogHeader>\r\n <form\r\n onSubmit={(e) => {\r\n e.preventDefault();\r\n if (searchTerm.trim()) {\r\n navigate(\r\n `/products?search=${encodeURIComponent(searchTerm)}`\r\n );\r\n setMobileSearchOpen(false);\r\n clearSearch();\r\n }\r\n }}\r\n className=\"space-y-4\"\r\n >\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-4 w-4\" />\r\n <Input\r\n type=\"search\"\r\n placeholder={t(\"searchPlaceholder\")}\r\n value={searchTerm}\r\n onChange={(e) => setSearchTerm(e.target.value)}\r\n className=\"pl-10\"\r\n autoFocus\r\n />\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <Button type=\"submit\" className=\"flex-1\">\r\n {t(\"searchButton\", \"Search\")}\r\n </Button>\r\n <Button\r\n type=\"button\"\r\n variant=\"outline\"\r\n onClick={() => {\r\n clearSearch();\r\n setMobileSearchOpen(false);\r\n }}\r\n >\r\n {t(\"cancel\", \"Cancel\")}\r\n </Button>\r\n </div>\r\n </form>\r\n\r\n {/* Mobile Search Results */}\r\n {searchTerm.trim() && (\r\n <div className=\"mt-4 max-h-64 overflow-y-auto\">\r\n {searchResults.length > 0 ? (\r\n <div className=\"space-y-2\">\r\n <p className=\"text-sm text-muted-foreground mb-2\">\r\n {searchResults.length} result\r\n {searchResults.length !== 1 ? \"s\" : \"\"} found\r\n </p>\r\n {searchResults.slice(0, 5).map((product: Product) => (\r\n <div key={product.id} className=\"contents\" data-db-table=\"products\" data-db-id={product.id}>\r\n <Link\r\n to={`/products/${product.slug}`}\r\n onClick={() => {\r\n setMobileSearchOpen(false);\r\n clearSearch();\r\n }}\r\n className=\"block p-2 rounded hover:bg-muted/50 transition-colors\"\r\n >\r\n <div className=\"flex items-center gap-3\">\r\n <img\r\n src={\r\n product.images?.length ? product.images?.[0] : \"/images/placeholder.png\"\r\n }\r\n alt={product.name}\r\n className=\"w-10 h-10 object-cover rounded\"\r\n />\r\n <div className=\"flex-1\">\r\n <h4 className=\"font-medium text-sm\">\r\n {product.name}\r\n </h4>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {categoryMap.get(product.categories?.[0] as number)?.name}\r\n </p>\r\n <p className=\"text-sm font-medium\">\r\n {formatPrice(\r\n product.price,\r\n constants.site.currency\r\n )}\r\n </p>\r\n </div>\r\n </div>\r\n </Link>\r\n </div>\r\n ))}\r\n </div>\r\n ) : (\r\n <p className=\"text-sm text-muted-foreground\">\r\n {t(\"noResults\")}\r\n </p>\r\n )}\r\n </div>\r\n )}\r\n </DialogContent>\r\n </Dialog>\r\n\r\n {/* Wishlist - Desktop Only */}\r\n <Link to=\"/favorites\" className=\"hidden lg:block\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"relative h-10 w-10\"\r\n >\r\n <Heart className=\"h-5 w-5\" />\r\n {favoriteCount > 0 && (\r\n <Badge\r\n variant=\"destructive\"\r\n className=\"absolute -top-1 -right-1 h-4 w-4 flex items-center justify-center p-0 text-[10px]\"\r\n >\r\n {favoriteCount}\r\n </Badge>\r\n )}\r\n </Button>\r\n </Link>\r\n\r\n {/* Cart - Desktop Only (Goes to Cart Page) */}\r\n <Link to=\"/cart\" className=\"hidden lg:block\">\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"relative h-10 w-10\"\r\n >\r\n <ShoppingCart className=\"h-5 w-5\" />\r\n {itemCount > 0 && (\r\n <Badge\r\n variant=\"destructive\"\r\n className=\"absolute -top-1 -right-1 h-4 w-4 flex items-center justify-center p-0 text-[10px]\"\r\n >\r\n {itemCount}\r\n </Badge>\r\n )}\r\n </Button>\r\n </Link>\r\n\r\n {/* Auth - Desktop Only */}\r\n <div className=\"hidden lg:flex\">\r\n {isAuthenticated ? (\r\n <DropdownMenu>\r\n <DropdownMenuTrigger asChild>\r\n <Button variant=\"ghost\" size=\"icon\" className=\"h-10 w-10\">\r\n <User className=\"h-5 w-5\" />\r\n </Button>\r\n </DropdownMenuTrigger>\r\n <DropdownMenuContent align=\"end\" className=\"w-56\">\r\n <DropdownMenuLabel className=\"font-normal\">\r\n <div className=\"flex flex-col space-y-1\">\r\n <p className=\"text-sm font-medium\">{user?.username}</p>\r\n {user?.email && (\r\n <p className=\"text-xs text-muted-foreground\">{user.email}</p>\r\n )}\r\n </div>\r\n </DropdownMenuLabel>\r\n <DropdownMenuSeparator />\r\n <DropdownMenuItem asChild className=\"cursor-pointer\">\r\n <Link to=\"/my-orders\" className=\"flex items-center\">\r\n <Package className=\"mr-2 h-4 w-4\" />\r\n {t(\"myOrders\", \"My Orders\")}\r\n </Link>\r\n </DropdownMenuItem>\r\n <DropdownMenuSeparator />\r\n <DropdownMenuItem\r\n onClick={handleLogout}\r\n className=\"text-red-600 focus:text-red-600 focus:bg-red-50 cursor-pointer\"\r\n >\r\n <LogOut className=\"mr-2 h-4 w-4\" />\r\n {t(\"logout\", \"Logout\")}\r\n </DropdownMenuItem>\r\n </DropdownMenuContent>\r\n </DropdownMenu>\r\n ) : (\r\n <Link to=\"/login\">\r\n <Button variant=\"ghost\" size=\"icon\" className=\"h-10 w-10\">\r\n <User className=\"h-5 w-5\" />\r\n </Button>\r\n </Link>\r\n )}\r\n </div>\r\n\r\n {/* Mobile Menu */}\r\n <Sheet open={mobileMenuOpen} onOpenChange={setMobileMenuOpen}>\r\n <SheetTrigger asChild>\r\n <Button\r\n variant=\"ghost\"\r\n size=\"icon\"\r\n className=\"lg:hidden h-8 w-8 sm:h-10 sm:w-10\"\r\n >\r\n <Menu className=\"h-4 w-4 sm:h-5 sm:w-5\" />\r\n </Button>\r\n </SheetTrigger>\r\n <SheetContent side=\"right\" className=\"w-[300px] sm:w-[400px] px-6\">\r\n <SheetHeader>\r\n <SheetTitle>{t(\"menu\")}</SheetTitle>\r\n </SheetHeader>\r\n\r\n {/* Mobile Search in Hamburger */}\r\n <div className=\"mt-6 pb-4 border-b\">\r\n <form onSubmit={handleSearchSubmit}>\r\n <div className=\"relative\">\r\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-4 w-4\" />\r\n <Input\r\n type=\"search\"\r\n placeholder={t(\"searchPlaceholder\")}\r\n value={searchTerm}\r\n onChange={handleSearchChange}\r\n onFocus={handleSearchFocus}\r\n className=\"pl-10 h-11\"\r\n />\r\n </div>\r\n </form>\r\n\r\n {/* Search Results in Hamburger */}\r\n {showResults && searchTerm && (\r\n <div className=\"mt-3 max-h-[300px] overflow-y-auto rounded-lg border bg-card\">\r\n {searchResults.length > 0 ? (\r\n <div className=\"divide-y\">\r\n <div className=\"px-3 py-2 bg-muted/50\">\r\n <p className=\"text-xs font-medium text-muted-foreground\">\r\n {searchResults.length}{\" \"}\r\n {searchResults.length === 1\r\n ? \"result\"\r\n : \"results\"}\r\n </p>\r\n </div>\r\n {searchResults.slice(0, 5).map((product: Product) => (\r\n <div key={product.id} className=\"contents\" data-db-table=\"products\" data-db-id={product.id}>\r\n <Link\r\n to={`/products/${product.slug}`}\r\n onClick={() => {\r\n setMobileMenuOpen(false);\r\n clearSearch();\r\n setShowResults(false);\r\n }}\r\n className=\"flex items-center gap-3 p-3 hover:bg-muted/50 transition-colors\"\r\n >\r\n <img\r\n src={\r\n product.images?.length ? product.images?.[0] : \"/images/placeholder.png\"\r\n }\r\n alt={product.name}\r\n className=\"w-14 h-14 object-cover rounded flex-shrink-0\"\r\n />\r\n <div className=\"flex-1 min-w-0\">\r\n <h4 className=\"font-medium text-sm line-clamp-1\">\r\n {product.name}\r\n </h4>\r\n <p className=\"text-xs text-muted-foreground capitalize\">\r\n {categoryMap.get(product.categories?.[0] as number)?.name}\r\n </p>\r\n <p className=\"text-sm font-semibold text-primary mt-1\">\r\n {formatPrice(\r\n product.price,\r\n constants.site.currency\r\n )}\r\n </p>\r\n </div>\r\n </Link>\r\n </div>\r\n ))}\r\n {searchResults.length > 5 && (\r\n <div className=\"px-3 py-2 bg-muted/30 text-center\">\r\n <button\r\n onClick={() => {\r\n navigate(\r\n `/products?search=${encodeURIComponent(\r\n searchTerm\r\n )}`\r\n );\r\n setMobileMenuOpen(false);\r\n clearSearch();\r\n setShowResults(false);\r\n }}\r\n className=\"text-xs font-medium text-primary hover:underline\"\r\n >\r\n {t(\r\n \"viewAllResults\",\r\n `View all ${searchResults.length} results`\r\n )}\r\n </button>\r\n </div>\r\n )}\r\n </div>\r\n ) : (\r\n <div className=\"p-6 text-center\">\r\n <Search className=\"h-8 w-8 text-muted-foreground mx-auto mb-2 opacity-50\" />\r\n <p className=\"text-sm text-muted-foreground\">\r\n {t(\"noResults\", \"No results found\")}\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n\r\n <div className=\"flex flex-col space-y-4 mt-6\">\r\n {navigation.map((item) => (\r\n <Link\r\n key={item.name}\r\n to={item.href}\r\n className=\"text-lg font-medium hover:text-primary transition-colors\"\r\n onClick={() => setMobileMenuOpen(false)}\r\n >\r\n {item.name}\r\n </Link>\r\n ))}\r\n <div className=\"border-t pt-4 space-y-4\">\r\n <Link\r\n to=\"/favorites\"\r\n className=\"flex items-center justify-between text-lg font-medium hover:text-primary transition-colors\"\r\n onClick={() => setMobileMenuOpen(false)}\r\n >\r\n <div className=\"flex items-center space-x-2\">\r\n <Heart className=\"h-5 w-5\" />\r\n <span>{t(\"favorites\")}</span>\r\n </div>\r\n <Badge variant=\"secondary\">{favoriteCount}</Badge>\r\n </Link>\r\n <Link\r\n to=\"/cart\"\r\n className=\"flex items-center justify-between w-full text-lg font-medium hover:text-primary transition-colors\"\r\n onClick={() => setMobileMenuOpen(false)}\r\n >\r\n <div className=\"flex items-center space-x-2\">\r\n <ShoppingCart className=\"h-5 w-5\" />\r\n <span>{t(\"cart\")}</span>\r\n </div>\r\n <div className=\"flex flex-col items-end\">\r\n <Badge variant=\"secondary\">{itemCount}</Badge>\r\n <span className=\"text-xs text-muted-foreground\">\r\n {formatPrice(state.total, constants.site.currency)}\r\n </span>\r\n </div>\r\n </Link>\r\n\r\n {/* Auth - Mobile */}\r\n {isAuthenticated ? (\r\n <div className=\"space-y-3\">\r\n <div className=\"flex items-center space-x-3 p-3 bg-muted/50 rounded-lg\">\r\n <div className=\"h-10 w-10 rounded-full bg-primary/10 flex items-center justify-center\">\r\n <User className=\"h-5 w-5 text-primary\" />\r\n </div>\r\n <div className=\"flex-1 min-w-0\">\r\n <p className=\"text-sm font-medium truncate\">{user?.username}</p>\r\n {user?.email && (\r\n <p className=\"text-xs text-muted-foreground truncate\">{user.email}</p>\r\n )}\r\n </div>\r\n </div>\r\n <Link\r\n to=\"/my-orders\"\r\n className=\"flex items-center space-x-2 text-lg font-medium hover:text-primary transition-colors\"\r\n onClick={() => setMobileMenuOpen(false)}\r\n >\r\n <Package className=\"h-5 w-5\" />\r\n <span>{t(\"myOrders\", \"My Orders\")}</span>\r\n </Link>\r\n <button\r\n onClick={() => {\r\n handleLogout();\r\n setMobileMenuOpen(false);\r\n }}\r\n className=\"flex items-center space-x-2 text-lg font-medium text-red-600 hover:text-red-700 transition-colors w-full\"\r\n >\r\n <LogOut className=\"h-5 w-5\" />\r\n <span>{t(\"logout\", \"Logout\")}</span>\r\n </button>\r\n </div>\r\n ) : (\r\n <Link\r\n to=\"/login\"\r\n className=\"flex items-center space-x-2 text-lg font-medium hover:text-primary transition-colors\"\r\n onClick={() => setMobileMenuOpen(false)}\r\n >\r\n <User className=\"h-5 w-5\" />\r\n <span>{t(\"login\", \"Login\")}</span>\r\n </Link>\r\n )}\r\n </div>\r\n </div>\r\n </SheetContent>\r\n </Sheet>\r\n </div>\r\n </div>\r\n </div>\r\n {/* Cart Drawer */}\r\n <CartDrawer showTrigger={false} />\r\n </header>\r\n );\r\n}\r\n"
23
+ "content": "import { useState, useMemo } from \"react\";\nimport { useDebouncedValue } from \"@/hooks/use-debounced-value\";\nimport { Link, useNavigate } from \"react-router\";\nimport { ShoppingCart, Menu, Search, Heart, Package, User, LogOut } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Badge } from \"@/components/ui/badge\";\nimport {\n Sheet,\n SheetHeader,\n SheetTitle,\n SheetContent,\n SheetTrigger,\n} from \"@/components/ui/sheet\";\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/components/ui/dialog\";\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport { Logo } from \"@/components/Logo\";\nimport { useAuth } from \"@/modules/auth-core\";\nimport { CartDrawer } from \"@/modules/cart-drawer\";\nimport { toast } from \"sonner\";\nimport { useTranslation } from \"react-i18next\";\nimport constants from \"@/constants/constants.json\";\nimport type { Product, Category } from \"@/modules/ecommerce-core/types\";\nimport {\n useCart,\n useFavorites,\n formatPrice,\n} from \"@/modules/ecommerce-core\";\nimport { useDbList } from \"@/db\";\n\nexport function HeaderEcommerce() {\n const [mobileMenuOpen, setMobileMenuOpen] = useState(false);\n const [mobileSearchOpen, setMobileSearchOpen] = useState(false);\n const [desktopSearchOpen, setDesktopSearchOpen] = useState(false);\n const [showResults, setShowResults] = useState(false);\n const { itemCount, state } = useCart();\n const { favoriteCount } = useFavorites();\n const { isAuthenticated, user, logout } = useAuth();\n const navigate = useNavigate();\n const { t } = useTranslation(\"header-ecommerce\");\n\n const handleLogout = () => {\n logout();\n toast.success(t(\"logoutToastTitle\", \"Goodbye!\"), {\n description: t(\"logoutToastDesc\", \"You have been logged out successfully.\"),\n });\n };\n\n const [searchTerm, setSearchTerm] = useState(\"\");\n const debouncedTerm = useDebouncedValue(searchTerm, 300);\n const { data: productCategories = [] } = useDbList<Category>(\"product_categories\");\n const categoryMap = useMemo(() => new Map(productCategories.map(c => [c.id, c])), [productCategories]);\n\n const { data: searchResults = [] } = useDbList<Product>(\"products\", {\n where: debouncedTerm ? { name: { $like: `%${debouncedTerm}%` } } : {},\n limit: 20,\n enabled: debouncedTerm.length > 0,\n });\n\n const clearSearch = () => { setSearchTerm(\"\"); };\n\n const handleSearchSubmit = (e: React.FormEvent) => {\n e.preventDefault();\n if (searchTerm.trim()) {\n navigate(`/products?search=${encodeURIComponent(searchTerm)}`);\n setShowResults(false);\n setDesktopSearchOpen(false);\n clearSearch();\n }\n };\n\n const handleSearchFocus = () => {\n setShowResults(true);\n };\n\n const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n setSearchTerm(e.target.value);\n setShowResults(true);\n };\n\n const navigation = [\n { name: t(\"home\"), href: \"/\" },\n { name: t(\"products\"), href: \"/products\" },\n { name: t(\"about\"), href: \"/about\" },\n { name: t(\"contact\"), href: \"/contact\" },\n ];\n\n return (\n <header className=\"sticky top-0 z-50 w-full border-b border-border/20 bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60\">\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-3 sm:px-4 lg:px-8\">\n <div className=\"flex h-14 sm:h-16 md:h-20 items-center justify-between gap-2\">\n {/* Logo */}\n <div className=\"flex-shrink-0 min-w-0\">\n <Logo size=\"sm\" className=\"text-base sm:text-xl lg:text-2xl\" />\n </div>\n\n {/* Desktop Navigation - Centered */}\n <nav className=\"hidden lg:flex items-center space-x-12 absolute left-1/2 transform -translate-x-1/2\">\n {navigation.map((item) => (\n <Link\n key={item.name}\n to={item.href}\n className=\"text-base font-medium transition-colors hover:text-primary relative group py-2\"\n >\n {item.name}\n <span className=\"absolute -bottom-1 left-0 w-0 h-0.5 bg-primary transition-all duration-300 group-hover:w-full\"></span>\n </Link>\n ))}\n </nav>\n\n {/* Search & Actions - Right Aligned */}\n <div className=\"flex items-center space-x-1 sm:space-x-2 lg:space-x-4 flex-shrink-0\">\n {/* Desktop Search - Modal */}\n <Dialog\n open={desktopSearchOpen}\n onOpenChange={setDesktopSearchOpen}\n >\n <DialogTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"hidden lg:flex h-10 w-10\"\n >\n <Search className=\"h-5 w-5\" />\n </Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-2xl\">\n <DialogHeader>\n <DialogTitle>\n {t(\"searchProducts\", \"Search Products\")}\n </DialogTitle>\n </DialogHeader>\n <div className=\"space-y-4\">\n <form onSubmit={handleSearchSubmit}>\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-5 w-5\" />\n <Input\n type=\"search\"\n placeholder={t(\n \"searchPlaceholder\",\n \"Search for products...\"\n )}\n value={searchTerm}\n onChange={handleSearchChange}\n className=\"pl-11 h-12 text-base\"\n autoFocus\n />\n </div>\n </form>\n\n {/* Desktop Search Results */}\n {searchTerm.trim() && (\n <div className=\"max-h-[400px] overflow-y-auto rounded-lg border bg-card\">\n {searchResults.length > 0 ? (\n <div className=\"divide-y\">\n <div className=\"px-4 py-3 bg-muted/50\">\n <p className=\"text-sm font-medium text-muted-foreground\">\n {searchResults.length}{\" \"}\n {searchResults.length === 1\n ? \"result\"\n : \"results\"}{\" \"}\n found\n </p>\n </div>\n {searchResults.slice(0, 8).map((product: Product) => (\n <div key={product.id} className=\"contents\" data-db-table=\"products\" data-db-id={product.id}>\n <Link\n to={`/products/${product.slug}`}\n onClick={() => {\n setDesktopSearchOpen(false);\n clearSearch();\n }}\n className=\"flex items-center gap-4 p-4 hover:bg-muted/50 transition-colors\"\n >\n <img\n src={\n product.images?.length ? product.images?.[0] : \"/images/placeholder.png\"\n }\n alt={product.name}\n className=\"w-16 h-16 object-cover rounded flex-shrink-0\"\n />\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-base line-clamp-1\">\n {product.name}\n </h4>\n <p className=\"text-sm text-muted-foreground capitalize\">\n {categoryMap.get(product.categories?.[0] as number)?.name}\n </p>\n <p className=\"text-base font-semibold text-primary mt-1\">\n {formatPrice(\n product.price,\n constants.site.currency\n )}\n </p>\n </div>\n </Link>\n </div>\n ))}\n {searchResults.length > 8 && (\n <div className=\"px-4 py-3 bg-muted/30 text-center\">\n <button\n onClick={() => {\n navigate(\n `/products?search=${encodeURIComponent(\n searchTerm\n )}`\n );\n setDesktopSearchOpen(false);\n clearSearch();\n }}\n className=\"text-sm font-medium text-primary hover:underline\"\n >\n {t(\n \"viewAllResults\",\n `View all ${searchResults.length} results`\n )}\n </button>\n </div>\n )}\n </div>\n ) : (\n <div className=\"p-8 text-center\">\n <Search className=\"h-12 w-12 text-muted-foreground mx-auto mb-3 opacity-50\" />\n <p className=\"text-base text-muted-foreground\">\n {t(\"noResults\", \"No products found\")}\n </p>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {t(\n \"tryDifferentKeywords\",\n \"Try different keywords\"\n )}\n </p>\n </div>\n )}\n </div>\n )}\n </div>\n </DialogContent>\n </Dialog>\n\n {/* Search - Mobile (Hidden - moved to hamburger menu) */}\n <Dialog open={mobileSearchOpen} onOpenChange={setMobileSearchOpen}>\n <DialogTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"hidden\">\n <Search className=\"h-4 w-4 sm:h-5 sm:w-5\" />\n </Button>\n </DialogTrigger>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>{t(\"searchProducts\")}</DialogTitle>\n </DialogHeader>\n <form\n onSubmit={(e) => {\n e.preventDefault();\n if (searchTerm.trim()) {\n navigate(\n `/products?search=${encodeURIComponent(searchTerm)}`\n );\n setMobileSearchOpen(false);\n clearSearch();\n }\n }}\n className=\"space-y-4\"\n >\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-4 w-4\" />\n <Input\n type=\"search\"\n placeholder={t(\"searchPlaceholder\")}\n value={searchTerm}\n onChange={(e) => setSearchTerm(e.target.value)}\n className=\"pl-10\"\n autoFocus\n />\n </div>\n <div className=\"flex gap-2\">\n <Button type=\"submit\" className=\"flex-1\">\n {t(\"searchButton\", \"Search\")}\n </Button>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => {\n clearSearch();\n setMobileSearchOpen(false);\n }}\n >\n {t(\"cancel\", \"Cancel\")}\n </Button>\n </div>\n </form>\n\n {/* Mobile Search Results */}\n {searchTerm.trim() && (\n <div className=\"mt-4 max-h-64 overflow-y-auto\">\n {searchResults.length > 0 ? (\n <div className=\"space-y-2\">\n <p className=\"text-sm text-muted-foreground mb-2\">\n {searchResults.length} result\n {searchResults.length !== 1 ? \"s\" : \"\"} found\n </p>\n {searchResults.slice(0, 5).map((product: Product) => (\n <div key={product.id} className=\"contents\" data-db-table=\"products\" data-db-id={product.id}>\n <Link\n to={`/products/${product.slug}`}\n onClick={() => {\n setMobileSearchOpen(false);\n clearSearch();\n }}\n className=\"block p-2 rounded hover:bg-muted/50 transition-colors\"\n >\n <div className=\"flex items-center gap-3\">\n <img\n src={\n product.images?.length ? product.images?.[0] : \"/images/placeholder.png\"\n }\n alt={product.name}\n className=\"w-10 h-10 object-cover rounded\"\n />\n <div className=\"flex-1\">\n <h4 className=\"font-medium text-sm\">\n {product.name}\n </h4>\n <p className=\"text-xs text-muted-foreground\">\n {categoryMap.get(product.categories?.[0] as number)?.name}\n </p>\n <p className=\"text-sm font-medium\">\n {formatPrice(\n product.price,\n constants.site.currency\n )}\n </p>\n </div>\n </div>\n </Link>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t(\"noResults\")}\n </p>\n )}\n </div>\n )}\n </DialogContent>\n </Dialog>\n\n {/* Wishlist - Desktop Only */}\n <Link to=\"/favorites\" className=\"hidden lg:block\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"relative h-10 w-10\"\n >\n <Heart className=\"h-5 w-5\" />\n {favoriteCount > 0 && (\n <Badge\n variant=\"destructive\"\n className=\"absolute -top-1 -right-1 h-4 w-4 flex items-center justify-center p-0 text-[10px]\"\n >\n {favoriteCount}\n </Badge>\n )}\n </Button>\n </Link>\n\n {/* Cart - Desktop Only (Goes to Cart Page) */}\n <Link to=\"/cart\" className=\"hidden lg:block\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"relative h-10 w-10\"\n >\n <ShoppingCart className=\"h-5 w-5\" />\n {itemCount > 0 && (\n <Badge\n variant=\"destructive\"\n className=\"absolute -top-1 -right-1 h-4 w-4 flex items-center justify-center p-0 text-[10px]\"\n >\n {itemCount}\n </Badge>\n )}\n </Button>\n </Link>\n\n {/* Auth - Desktop Only */}\n <div className=\"hidden lg:flex\">\n {isAuthenticated ? (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-10 w-10\">\n <User className=\"h-5 w-5\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-56\">\n <DropdownMenuLabel className=\"font-normal\">\n <div className=\"flex flex-col space-y-1\">\n <p className=\"text-sm font-medium\">{user?.username}</p>\n {user?.email && (\n <p className=\"text-xs text-muted-foreground\">{user.email}</p>\n )}\n </div>\n </DropdownMenuLabel>\n <DropdownMenuSeparator />\n <DropdownMenuItem asChild className=\"cursor-pointer\">\n <Link to=\"/my-orders\" className=\"flex items-center\">\n <Package className=\"mr-2 h-4 w-4\" />\n {t(\"myOrders\", \"My Orders\")}\n </Link>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={handleLogout}\n className=\"text-red-600 focus:text-red-600 focus:bg-red-50 cursor-pointer\"\n >\n <LogOut className=\"mr-2 h-4 w-4\" />\n {t(\"logout\", \"Logout\")}\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n ) : (\n <Link to=\"/login\">\n <Button variant=\"ghost\" size=\"icon\" className=\"h-10 w-10\">\n <User className=\"h-5 w-5\" />\n </Button>\n </Link>\n )}\n </div>\n\n {/* Mobile Menu */}\n <Sheet open={mobileMenuOpen} onOpenChange={setMobileMenuOpen}>\n <SheetTrigger asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"lg:hidden h-8 w-8 sm:h-10 sm:w-10\"\n >\n <Menu className=\"h-4 w-4 sm:h-5 sm:w-5\" />\n </Button>\n </SheetTrigger>\n <SheetContent side=\"right\" className=\"w-[300px] sm:w-[400px] px-6\">\n <SheetHeader>\n <SheetTitle>{t(\"menu\")}</SheetTitle>\n </SheetHeader>\n\n {/* Mobile Search in Hamburger */}\n <div className=\"mt-6 pb-4 border-b\">\n <form onSubmit={handleSearchSubmit}>\n <div className=\"relative\">\n <Search className=\"absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground h-4 w-4\" />\n <Input\n type=\"search\"\n placeholder={t(\"searchPlaceholder\")}\n value={searchTerm}\n onChange={handleSearchChange}\n onFocus={handleSearchFocus}\n className=\"pl-10 h-11\"\n />\n </div>\n </form>\n\n {/* Search Results in Hamburger */}\n {showResults && searchTerm && (\n <div className=\"mt-3 max-h-[300px] overflow-y-auto rounded-lg border bg-card\">\n {searchResults.length > 0 ? (\n <div className=\"divide-y\">\n <div className=\"px-3 py-2 bg-muted/50\">\n <p className=\"text-xs font-medium text-muted-foreground\">\n {searchResults.length}{\" \"}\n {searchResults.length === 1\n ? \"result\"\n : \"results\"}\n </p>\n </div>\n {searchResults.slice(0, 5).map((product: Product) => (\n <div key={product.id} className=\"contents\" data-db-table=\"products\" data-db-id={product.id}>\n <Link\n to={`/products/${product.slug}`}\n onClick={() => {\n setMobileMenuOpen(false);\n clearSearch();\n setShowResults(false);\n }}\n className=\"flex items-center gap-3 p-3 hover:bg-muted/50 transition-colors\"\n >\n <img\n src={\n product.images?.length ? product.images?.[0] : \"/images/placeholder.png\"\n }\n alt={product.name}\n className=\"w-14 h-14 object-cover rounded flex-shrink-0\"\n />\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-medium text-sm line-clamp-1\">\n {product.name}\n </h4>\n <p className=\"text-xs text-muted-foreground capitalize\">\n {categoryMap.get(product.categories?.[0] as number)?.name}\n </p>\n <p className=\"text-sm font-semibold text-primary mt-1\">\n {formatPrice(\n product.price,\n constants.site.currency\n )}\n </p>\n </div>\n </Link>\n </div>\n ))}\n {searchResults.length > 5 && (\n <div className=\"px-3 py-2 bg-muted/30 text-center\">\n <button\n onClick={() => {\n navigate(\n `/products?search=${encodeURIComponent(\n searchTerm\n )}`\n );\n setMobileMenuOpen(false);\n clearSearch();\n setShowResults(false);\n }}\n className=\"text-xs font-medium text-primary hover:underline\"\n >\n {t(\n \"viewAllResults\",\n `View all ${searchResults.length} results`\n )}\n </button>\n </div>\n )}\n </div>\n ) : (\n <div className=\"p-6 text-center\">\n <Search className=\"h-8 w-8 text-muted-foreground mx-auto mb-2 opacity-50\" />\n <p className=\"text-sm text-muted-foreground\">\n {t(\"noResults\", \"No results found\")}\n </p>\n </div>\n )}\n </div>\n )}\n </div>\n\n <div className=\"flex flex-col space-y-4 mt-6\">\n {navigation.map((item) => (\n <Link\n key={item.name}\n to={item.href}\n className=\"text-lg font-medium hover:text-primary transition-colors\"\n onClick={() => setMobileMenuOpen(false)}\n >\n {item.name}\n </Link>\n ))}\n <div className=\"border-t pt-4 space-y-4\">\n <Link\n to=\"/favorites\"\n className=\"flex items-center justify-between text-lg font-medium hover:text-primary transition-colors\"\n onClick={() => setMobileMenuOpen(false)}\n >\n <div className=\"flex items-center space-x-2\">\n <Heart className=\"h-5 w-5\" />\n <span>{t(\"favorites\")}</span>\n </div>\n <Badge variant=\"secondary\">{favoriteCount}</Badge>\n </Link>\n <Link\n to=\"/cart\"\n className=\"flex items-center justify-between w-full text-lg font-medium hover:text-primary transition-colors\"\n onClick={() => setMobileMenuOpen(false)}\n >\n <div className=\"flex items-center space-x-2\">\n <ShoppingCart className=\"h-5 w-5\" />\n <span>{t(\"cart\")}</span>\n </div>\n <div className=\"flex flex-col items-end\">\n <Badge variant=\"secondary\">{itemCount}</Badge>\n <span className=\"text-xs text-muted-foreground\">\n {formatPrice(state.total, constants.site.currency)}\n </span>\n </div>\n </Link>\n\n {/* Auth - Mobile */}\n {isAuthenticated ? (\n <div className=\"space-y-3\">\n <div className=\"flex items-center space-x-3 p-3 bg-muted/50 rounded-lg\">\n <div className=\"h-10 w-10 rounded-full bg-primary/10 flex items-center justify-center\">\n <User className=\"h-5 w-5 text-primary\" />\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"text-sm font-medium truncate\">{user?.username}</p>\n {user?.email && (\n <p className=\"text-xs text-muted-foreground truncate\">{user.email}</p>\n )}\n </div>\n </div>\n <Link\n to=\"/my-orders\"\n className=\"flex items-center space-x-2 text-lg font-medium hover:text-primary transition-colors\"\n onClick={() => setMobileMenuOpen(false)}\n >\n <Package className=\"h-5 w-5\" />\n <span>{t(\"myOrders\", \"My Orders\")}</span>\n </Link>\n <button\n onClick={() => {\n handleLogout();\n setMobileMenuOpen(false);\n }}\n className=\"flex items-center space-x-2 text-lg font-medium text-red-600 hover:text-red-700 transition-colors w-full\"\n >\n <LogOut className=\"h-5 w-5\" />\n <span>{t(\"logout\", \"Logout\")}</span>\n </button>\n </div>\n ) : (\n <Link\n to=\"/login\"\n className=\"flex items-center space-x-2 text-lg font-medium hover:text-primary transition-colors\"\n onClick={() => setMobileMenuOpen(false)}\n >\n <User className=\"h-5 w-5\" />\n <span>{t(\"login\", \"Login\")}</span>\n </Link>\n )}\n </div>\n </div>\n </SheetContent>\n </Sheet>\n </div>\n </div>\n </div>\n {/* Cart Drawer */}\n <CartDrawer showTrigger={false} />\n </header>\n );\n}\n"
24
24
  },
25
25
  {
26
26
  "path": "header-ecommerce/lang/en.json",
27
27
  "type": "registry:lang",
28
28
  "target": "$modules$/header-ecommerce/lang/en.json",
29
- "content": "{\r\n \"menu\": \"Menu\",\r\n \"home\": \"Home\",\r\n \"products\": \"Products\",\r\n \"about\": \"About\",\r\n \"contact\": \"Contact\",\r\n \"cart\": \"Cart\",\r\n \"favorites\": \"Favorites\",\r\n \"searchProducts\": \"Search Products\",\r\n \"searchPlaceholder\": \"Search for products...\",\r\n \"searchButton\": \"Search\",\r\n \"result\": \"result\",\r\n \"results\": \"results\",\r\n \"noResults\": \"No products found\",\r\n \"tryDifferent\": \"Try different keywords\",\r\n \"viewAllResults\": \"View all results\"\r\n}\r\n"
29
+ "content": "{\n \"menu\": \"Menu\",\n \"home\": \"Home\",\n \"products\": \"Products\",\n \"about\": \"About\",\n \"contact\": \"Contact\",\n \"cart\": \"Cart\",\n \"favorites\": \"Favorites\",\n \"searchProducts\": \"Search Products\",\n \"searchPlaceholder\": \"Search for products...\",\n \"searchButton\": \"Search\",\n \"result\": \"result\",\n \"results\": \"results\",\n \"noResults\": \"No products found\",\n \"tryDifferent\": \"Try different keywords\",\n \"viewAllResults\": \"View all results\"\n}\n"
30
30
  },
31
31
  {
32
32
  "path": "header-ecommerce/lang/tr.json",
33
33
  "type": "registry:lang",
34
34
  "target": "$modules$/header-ecommerce/lang/tr.json",
35
- "content": "{\r\n \"menu\": \"Menü\",\r\n \"home\": \"Ana Sayfa\",\r\n \"products\": \"Ürünler\",\r\n \"about\": \"Hakkımızda\",\r\n \"contact\": \"İletişim\",\r\n \"cart\": \"Sepet\",\r\n \"favorites\": \"Favoriler\",\r\n \"searchProducts\": \"Ürün Ara\",\r\n \"searchPlaceholder\": \"Ürün ara...\",\r\n \"searchButton\": \"Ara\",\r\n \"result\": \"sonuç\",\r\n \"results\": \"sonuç\",\r\n \"noResults\": \"Ürün bulunamadı\",\r\n \"tryDifferent\": \"Farklı anahtar kelimeler deneyin\",\r\n \"viewAllResults\": \"Tüm sonuçları gör\"\r\n}\r\n"
35
+ "content": "{\n \"menu\": \"Menü\",\n \"home\": \"Ana Sayfa\",\n \"products\": \"Ürünler\",\n \"about\": \"Hakkımızda\",\n \"contact\": \"İletişim\",\n \"cart\": \"Sepet\",\n \"favorites\": \"Favoriler\",\n \"searchProducts\": \"Ürün Ara\",\n \"searchPlaceholder\": \"Ürün ara...\",\n \"searchButton\": \"Ara\",\n \"result\": \"sonuç\",\n \"results\": \"sonuç\",\n \"noResults\": \"Ürün bulunamadı\",\n \"tryDifferent\": \"Farklı anahtar kelimeler deneyin\",\n \"viewAllResults\": \"Tüm sonuçları gör\"\n}\n"
36
36
  }
37
37
  ],
38
38
  "exports": {
@@ -17,25 +17,25 @@
17
17
  "path": "header-mega/index.ts",
18
18
  "type": "registry:index",
19
19
  "target": "$modules$/header-mega/index.ts",
20
- "content": "export * from './header-mega';\r\n"
20
+ "content": "export * from './header-mega';\n"
21
21
  },
22
22
  {
23
23
  "path": "header-mega/header-mega.tsx",
24
24
  "type": "registry:component",
25
25
  "target": "$modules$/header-mega/header-mega.tsx",
26
- "content": "import { Link } from \"react-router\";\r\nimport { Book, Menu, Sunset, Trees, Zap } from \"lucide-react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport {\r\n Accordion,\r\n AccordionContent,\r\n AccordionItem,\r\n AccordionTrigger,\r\n} from \"@/components/ui/accordion\";\r\nimport { Button } from \"@/components/ui/button\";\r\nimport {\r\n NavigationMenu,\r\n NavigationMenuContent,\r\n NavigationMenuItem,\r\n NavigationMenuLink,\r\n NavigationMenuList,\r\n NavigationMenuTrigger,\r\n} from \"@/components/ui/navigation-menu\";\r\nimport {\r\n Sheet,\r\n SheetContent,\r\n SheetHeader,\r\n SheetTitle,\r\n SheetTrigger,\r\n} from \"@/components/ui/sheet\";\r\nimport constants from \"@/constants/constants.json\";\r\n\r\ninterface MenuItem {\r\n title: string;\r\n url: string;\r\n description?: string;\r\n icon?: React.ReactNode;\r\n items?: MenuItem[];\r\n}\r\n\r\ninterface HeaderMegaProps {\r\n className?: string;\r\n}\r\n\r\nexport function HeaderMega({ className }: HeaderMegaProps) {\r\n const { t } = useTranslation(\"header-mega\");\r\n\r\n const menu: MenuItem[] = [\r\n { title: t(\"home\", \"Home\"), url: \"/\" },\r\n {\r\n title: t(\"products\", \"Products\"),\r\n url: \"/products\",\r\n items: [\r\n {\r\n title: t(\"allProducts\", \"All Products\"),\r\n description: t(\r\n \"allProductsDesc\",\r\n \"Browse our complete product catalog\"\r\n ),\r\n icon: <Book className=\"h-5 w-5 shrink-0\" />,\r\n url: \"/products\",\r\n },\r\n {\r\n title: t(\"featured\", \"Featured\"),\r\n description: t(\r\n \"featuredDesc\",\r\n \"Our handpicked selection of top products\"\r\n ),\r\n icon: <Trees className=\"h-5 w-5 shrink-0\" />,\r\n url: \"/products?featured=true\",\r\n },\r\n {\r\n title: t(\"newArrivals\", \"New Arrivals\"),\r\n description: t(\"newArrivalsDesc\", \"Check out the latest additions\"),\r\n icon: <Sunset className=\"h-5 w-5 shrink-0\" />,\r\n url: \"/products?is_new=true\",\r\n },\r\n {\r\n title: t(\"onSale\", \"On Sale\"),\r\n description: t(\"onSaleDesc\", \"Great deals and special offers\"),\r\n icon: <Zap className=\"h-5 w-5 shrink-0\" />,\r\n url: \"/products?on_sale=true\",\r\n },\r\n ],\r\n },\r\n {\r\n title: t(\"company\", \"Company\"),\r\n url: \"#\",\r\n items: [\r\n {\r\n title: t(\"aboutUs\", \"About Us\"),\r\n description: t(\r\n \"aboutUsDesc\",\r\n \"Learn more about our story and mission\"\r\n ),\r\n icon: <Trees className=\"h-5 w-5 shrink-0\" />,\r\n url: \"/about\",\r\n },\r\n {\r\n title: t(\"contact\", \"Contact\"),\r\n description: t(\"contactDesc\", \"Get in touch with our team\"),\r\n icon: <Sunset className=\"h-5 w-5 shrink-0\" />,\r\n url: \"/contact\",\r\n },\r\n {\r\n title: t(\"blog\", \"Blog\"),\r\n description: t(\"blogDesc\", \"Read our latest articles and updates\"),\r\n icon: <Book className=\"h-5 w-5 shrink-0\" />,\r\n url: \"/blog\",\r\n },\r\n ],\r\n },\r\n ];\r\n\r\n const renderMenuItem = (item: MenuItem) => {\r\n if (item.items) {\r\n return (\r\n <NavigationMenuItem key={item.title}>\r\n <NavigationMenuTrigger>{item.title}</NavigationMenuTrigger>\r\n <NavigationMenuContent className=\"z-50 bg-popover text-popover-foreground\">\r\n {item.items.map((subItem) => (\r\n <NavigationMenuLink asChild key={subItem.title} className=\"w-80\">\r\n <SubMenuLink item={subItem} />\r\n </NavigationMenuLink>\r\n ))}\r\n </NavigationMenuContent>\r\n </NavigationMenuItem>\r\n );\r\n }\r\n\r\n return (\r\n <NavigationMenuItem key={item.title}>\r\n <NavigationMenuLink asChild>\r\n <Link\r\n to={item.url}\r\n className=\"group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-muted hover:text-accent-foreground\"\r\n >\r\n {item.title}\r\n </Link>\r\n </NavigationMenuLink>\r\n </NavigationMenuItem>\r\n );\r\n };\r\n\r\n const renderMobileMenuItem = (item: MenuItem) => {\r\n if (item.items) {\r\n return (\r\n <AccordionItem\r\n key={item.title}\r\n value={item.title}\r\n className=\"border-b-0\"\r\n >\r\n <AccordionTrigger className=\"text-md py-0 font-semibold hover:no-underline\">\r\n {item.title}\r\n </AccordionTrigger>\r\n <AccordionContent className=\"mt-2\">\r\n {item.items.map((subItem) => (\r\n <SubMenuLink key={subItem.title} item={subItem} />\r\n ))}\r\n </AccordionContent>\r\n </AccordionItem>\r\n );\r\n }\r\n\r\n return (\r\n <Link key={item.title} to={item.url} className=\"text-md font-semibold\">\r\n {item.title}\r\n </Link>\r\n );\r\n };\r\n\r\n return (\r\n <header\r\n className={cn(\r\n \"relative z-50 py-4 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 overflow-visible\",\r\n className\r\n )}\r\n >\r\n <div className=\"container max-w-7xl mx-auto px-4\">\r\n {/* Desktop Menu */}\r\n <nav className=\"hidden items-center justify-between lg:flex overflow-visible\">\r\n <div className=\"flex items-center gap-6\">\r\n {/* Logo */}\r\n <Link to=\"/\" className=\"flex items-center gap-2\">\r\n <img\r\n src=\"/images/logo.png\"\r\n className=\"h-8 w-auto\"\r\n alt={constants.site.name}\r\n onError={(e) => {\r\n e.currentTarget.style.display = \"none\";\r\n }}\r\n />\r\n <span className=\"text-lg font-semibold tracking-tight\">\r\n {constants.site.name}\r\n </span>\r\n </Link>\r\n <div className=\"flex items-center\">\r\n <NavigationMenu>\r\n <NavigationMenuList>\r\n {menu.map((item) => renderMenuItem(item))}\r\n </NavigationMenuList>\r\n </NavigationMenu>\r\n </div>\r\n </div>\r\n <div className=\"flex gap-2\">\r\n <Button asChild variant=\"outline\" size=\"sm\">\r\n <Link to=\"/login\">{t(\"login\", \"Login\")}</Link>\r\n </Button>\r\n <Button asChild size=\"sm\">\r\n <Link to=\"/register\">{t(\"signup\", \"Sign up\")}</Link>\r\n </Button>\r\n </div>\r\n </nav>\r\n\r\n {/* Mobile Menu */}\r\n <div className=\"block lg:hidden\">\r\n <div className=\"flex items-center justify-between\">\r\n {/* Logo */}\r\n <Link to=\"/\" className=\"flex items-center gap-2\">\r\n <img\r\n src=\"/images/logo.png\"\r\n className=\"h-8 w-auto\"\r\n alt={constants.site.name}\r\n onError={(e) => {\r\n e.currentTarget.style.display = \"none\";\r\n }}\r\n />\r\n <span className=\"text-lg font-semibold tracking-tight\">\r\n {constants.site.name}\r\n </span>\r\n </Link>\r\n <Sheet>\r\n <SheetTrigger asChild>\r\n <Button variant=\"outline\" size=\"icon\">\r\n <Menu className=\"h-4 w-4\" />\r\n </Button>\r\n </SheetTrigger>\r\n <SheetContent className=\"z-50 overflow-y-auto px-6\">\r\n <SheetHeader>\r\n <SheetTitle>\r\n <Link to=\"/\" className=\"flex items-center gap-2\">\r\n <img\r\n src=\"/images/logo.png\"\r\n className=\"h-8 w-auto\"\r\n alt={constants.site.name}\r\n onError={(e) => {\r\n e.currentTarget.style.display = \"none\";\r\n }}\r\n />\r\n </Link>\r\n </SheetTitle>\r\n </SheetHeader>\r\n <div className=\"flex flex-col gap-6 p-4\">\r\n <Accordion\r\n type=\"single\"\r\n collapsible\r\n className=\"flex w-full flex-col gap-4\"\r\n >\r\n {menu.map((item) => renderMobileMenuItem(item))}\r\n </Accordion>\r\n\r\n <div className=\"flex flex-col gap-3\">\r\n <Button asChild variant=\"outline\">\r\n <Link to=\"/login\">{t(\"login\", \"Login\")}</Link>\r\n </Button>\r\n <Button asChild>\r\n <Link to=\"/register\">{t(\"signup\", \"Sign up\")}</Link>\r\n </Button>\r\n </div>\r\n </div>\r\n </SheetContent>\r\n </Sheet>\r\n </div>\r\n </div>\r\n </div>\r\n </header>\r\n );\r\n}\r\n\r\nfunction SubMenuLink({ item }: { item: MenuItem }) {\r\n return (\r\n <Link\r\n to={item.url}\r\n className=\"flex min-w-80 flex-row gap-4 rounded-md p-3 leading-none no-underline transition-colors outline-none select-none hover:bg-muted hover:text-accent-foreground\"\r\n >\r\n <div className=\"text-foreground\">{item.icon}</div>\r\n <div>\r\n <div className=\"text-sm font-semibold\">{item.title}</div>\r\n {item.description && (\r\n <p className=\"text-sm leading-snug text-muted-foreground\">\r\n {item.description}\r\n </p>\r\n )}\r\n </div>\r\n </Link>\r\n );\r\n}\r\n"
26
+ "content": "import { Link } from \"react-router\";\nimport { Book, Menu, Sunset, Trees, Zap } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { cn } from \"@/lib/utils\";\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/components/ui/accordion\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n NavigationMenu,\n NavigationMenuContent,\n NavigationMenuItem,\n NavigationMenuLink,\n NavigationMenuList,\n NavigationMenuTrigger,\n} from \"@/components/ui/navigation-menu\";\nimport {\n Sheet,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\";\nimport constants from \"@/constants/constants.json\";\n\ninterface MenuItem {\n title: string;\n url: string;\n description?: string;\n icon?: React.ReactNode;\n items?: MenuItem[];\n}\n\ninterface HeaderMegaProps {\n className?: string;\n}\n\nexport function HeaderMega({ className }: HeaderMegaProps) {\n const { t } = useTranslation(\"header-mega\");\n\n const menu: MenuItem[] = [\n { title: t(\"home\", \"Home\"), url: \"/\" },\n {\n title: t(\"products\", \"Products\"),\n url: \"/products\",\n items: [\n {\n title: t(\"allProducts\", \"All Products\"),\n description: t(\n \"allProductsDesc\",\n \"Browse our complete product catalog\"\n ),\n icon: <Book className=\"h-5 w-5 shrink-0\" />,\n url: \"/products\",\n },\n {\n title: t(\"featured\", \"Featured\"),\n description: t(\n \"featuredDesc\",\n \"Our handpicked selection of top products\"\n ),\n icon: <Trees className=\"h-5 w-5 shrink-0\" />,\n url: \"/products?featured=true\",\n },\n {\n title: t(\"newArrivals\", \"New Arrivals\"),\n description: t(\"newArrivalsDesc\", \"Check out the latest additions\"),\n icon: <Sunset className=\"h-5 w-5 shrink-0\" />,\n url: \"/products?is_new=true\",\n },\n {\n title: t(\"onSale\", \"On Sale\"),\n description: t(\"onSaleDesc\", \"Great deals and special offers\"),\n icon: <Zap className=\"h-5 w-5 shrink-0\" />,\n url: \"/products?on_sale=true\",\n },\n ],\n },\n {\n title: t(\"company\", \"Company\"),\n url: \"#\",\n items: [\n {\n title: t(\"aboutUs\", \"About Us\"),\n description: t(\n \"aboutUsDesc\",\n \"Learn more about our story and mission\"\n ),\n icon: <Trees className=\"h-5 w-5 shrink-0\" />,\n url: \"/about\",\n },\n {\n title: t(\"contact\", \"Contact\"),\n description: t(\"contactDesc\", \"Get in touch with our team\"),\n icon: <Sunset className=\"h-5 w-5 shrink-0\" />,\n url: \"/contact\",\n },\n {\n title: t(\"blog\", \"Blog\"),\n description: t(\"blogDesc\", \"Read our latest articles and updates\"),\n icon: <Book className=\"h-5 w-5 shrink-0\" />,\n url: \"/blog\",\n },\n ],\n },\n ];\n\n const renderMenuItem = (item: MenuItem) => {\n if (item.items) {\n return (\n <NavigationMenuItem key={item.title}>\n <NavigationMenuTrigger>{item.title}</NavigationMenuTrigger>\n <NavigationMenuContent className=\"z-50 bg-popover text-popover-foreground\">\n {item.items.map((subItem) => (\n <NavigationMenuLink asChild key={subItem.title} className=\"w-80\">\n <SubMenuLink item={subItem} />\n </NavigationMenuLink>\n ))}\n </NavigationMenuContent>\n </NavigationMenuItem>\n );\n }\n\n return (\n <NavigationMenuItem key={item.title}>\n <NavigationMenuLink asChild>\n <Link\n to={item.url}\n className=\"group inline-flex h-10 w-max items-center justify-center rounded-md bg-background px-4 py-2 text-sm font-medium transition-colors hover:bg-muted hover:text-accent-foreground\"\n >\n {item.title}\n </Link>\n </NavigationMenuLink>\n </NavigationMenuItem>\n );\n };\n\n const renderMobileMenuItem = (item: MenuItem) => {\n if (item.items) {\n return (\n <AccordionItem\n key={item.title}\n value={item.title}\n className=\"border-b-0\"\n >\n <AccordionTrigger className=\"text-md py-0 font-semibold hover:no-underline\">\n {item.title}\n </AccordionTrigger>\n <AccordionContent className=\"mt-2\">\n {item.items.map((subItem) => (\n <SubMenuLink key={subItem.title} item={subItem} />\n ))}\n </AccordionContent>\n </AccordionItem>\n );\n }\n\n return (\n <Link key={item.title} to={item.url} className=\"text-md font-semibold\">\n {item.title}\n </Link>\n );\n };\n\n return (\n <header\n className={cn(\n \"relative z-50 py-4 border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60 overflow-visible\",\n className\n )}\n >\n <div className=\"container max-w-7xl mx-auto px-4\">\n {/* Desktop Menu */}\n <nav className=\"hidden items-center justify-between lg:flex overflow-visible\">\n <div className=\"flex items-center gap-6\">\n {/* Logo */}\n <Link to=\"/\" className=\"flex items-center gap-2\">\n <img\n src=\"/images/logo.png\"\n className=\"h-8 w-auto\"\n alt={constants.site.name}\n onError={(e) => {\n e.currentTarget.style.display = \"none\";\n }}\n />\n <span className=\"text-lg font-semibold tracking-tight\">\n {constants.site.name}\n </span>\n </Link>\n <div className=\"flex items-center\">\n <NavigationMenu>\n <NavigationMenuList>\n {menu.map((item) => renderMenuItem(item))}\n </NavigationMenuList>\n </NavigationMenu>\n </div>\n </div>\n <div className=\"flex gap-2\">\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link to=\"/login\">{t(\"login\", \"Login\")}</Link>\n </Button>\n <Button asChild size=\"sm\">\n <Link to=\"/register\">{t(\"signup\", \"Sign up\")}</Link>\n </Button>\n </div>\n </nav>\n\n {/* Mobile Menu */}\n <div className=\"block lg:hidden\">\n <div className=\"flex items-center justify-between\">\n {/* Logo */}\n <Link to=\"/\" className=\"flex items-center gap-2\">\n <img\n src=\"/images/logo.png\"\n className=\"h-8 w-auto\"\n alt={constants.site.name}\n onError={(e) => {\n e.currentTarget.style.display = \"none\";\n }}\n />\n <span className=\"text-lg font-semibold tracking-tight\">\n {constants.site.name}\n </span>\n </Link>\n <Sheet>\n <SheetTrigger asChild>\n <Button variant=\"outline\" size=\"icon\">\n <Menu className=\"h-4 w-4\" />\n </Button>\n </SheetTrigger>\n <SheetContent className=\"z-50 overflow-y-auto px-6\">\n <SheetHeader>\n <SheetTitle>\n <Link to=\"/\" className=\"flex items-center gap-2\">\n <img\n src=\"/images/logo.png\"\n className=\"h-8 w-auto\"\n alt={constants.site.name}\n onError={(e) => {\n e.currentTarget.style.display = \"none\";\n }}\n />\n </Link>\n </SheetTitle>\n </SheetHeader>\n <div className=\"flex flex-col gap-6 p-4\">\n <Accordion\n type=\"single\"\n collapsible\n className=\"flex w-full flex-col gap-4\"\n >\n {menu.map((item) => renderMobileMenuItem(item))}\n </Accordion>\n\n <div className=\"flex flex-col gap-3\">\n <Button asChild variant=\"outline\">\n <Link to=\"/login\">{t(\"login\", \"Login\")}</Link>\n </Button>\n <Button asChild>\n <Link to=\"/register\">{t(\"signup\", \"Sign up\")}</Link>\n </Button>\n </div>\n </div>\n </SheetContent>\n </Sheet>\n </div>\n </div>\n </div>\n </header>\n );\n}\n\nfunction SubMenuLink({ item }: { item: MenuItem }) {\n return (\n <Link\n to={item.url}\n className=\"flex min-w-80 flex-row gap-4 rounded-md p-3 leading-none no-underline transition-colors outline-none select-none hover:bg-muted hover:text-accent-foreground\"\n >\n <div className=\"text-foreground\">{item.icon}</div>\n <div>\n <div className=\"text-sm font-semibold\">{item.title}</div>\n {item.description && (\n <p className=\"text-sm leading-snug text-muted-foreground\">\n {item.description}\n </p>\n )}\n </div>\n </Link>\n );\n}\n"
27
27
  },
28
28
  {
29
29
  "path": "header-mega/lang/en.json",
30
30
  "type": "registry:lang",
31
31
  "target": "$modules$/header-mega/lang/en.json",
32
- "content": "{\r\n \"home\": \"Home\",\r\n \"products\": \"Products\",\r\n \"allProducts\": \"All Products\",\r\n \"allProductsDesc\": \"Brief description that appears in the mega menu. Explain what visitors will find in your full product catalog. Use Promake to customize this menu text to guide navigation.\",\r\n \"featured\": \"Featured\",\r\n \"featuredDesc\": \"Menu description for your featured or highlighted products. Explain what makes these items special or recommended. Customize with Promake.\",\r\n \"newArrivals\": \"New Arrivals\",\r\n \"newArrivalsDesc\": \"Menu text describing your latest products. Create interest in what's new. Use Promake to customize this navigation description.\",\r\n \"onSale\": \"On Sale\",\r\n \"onSaleDesc\": \"Menu description for sale or discounted items. Highlight current promotions or deals. Customize with Promake to drive interest.\",\r\n \"company\": \"About\",\r\n \"aboutUs\": \"About Us\",\r\n \"aboutUsDesc\": \"Brief menu description of your about page. Tease what visitors will learn about your company, mission, or story. Customize with Promake.\",\r\n \"contact\": \"Contact\",\r\n \"contactDesc\": \"Menu text that encourages visitors to get in touch. Mention how you can help or your availability. Use Promake to create inviting contact text.\",\r\n \"blog\": \"Blog\",\r\n \"blogDesc\": \"Menu description for your blog section. Explain what type of content you publish or topics you cover. Customize with Promake.\",\r\n \"login\": \"Login\",\r\n \"signup\": \"Sign up\"\r\n}\r\n"
32
+ "content": "{\n \"home\": \"Home\",\n \"products\": \"Products\",\n \"allProducts\": \"All Products\",\n \"allProductsDesc\": \"Brief description that appears in the mega menu. Explain what visitors will find in your full product catalog. Use Promake to customize this menu text to guide navigation.\",\n \"featured\": \"Featured\",\n \"featuredDesc\": \"Menu description for your featured or highlighted products. Explain what makes these items special or recommended. Customize with Promake.\",\n \"newArrivals\": \"New Arrivals\",\n \"newArrivalsDesc\": \"Menu text describing your latest products. Create interest in what's new. Use Promake to customize this navigation description.\",\n \"onSale\": \"On Sale\",\n \"onSaleDesc\": \"Menu description for sale or discounted items. Highlight current promotions or deals. Customize with Promake to drive interest.\",\n \"company\": \"About\",\n \"aboutUs\": \"About Us\",\n \"aboutUsDesc\": \"Brief menu description of your about page. Tease what visitors will learn about your company, mission, or story. Customize with Promake.\",\n \"contact\": \"Contact\",\n \"contactDesc\": \"Menu text that encourages visitors to get in touch. Mention how you can help or your availability. Use Promake to create inviting contact text.\",\n \"blog\": \"Blog\",\n \"blogDesc\": \"Menu description for your blog section. Explain what type of content you publish or topics you cover. Customize with Promake.\",\n \"login\": \"Login\",\n \"signup\": \"Sign up\"\n}\n"
33
33
  },
34
34
  {
35
35
  "path": "header-mega/lang/tr.json",
36
36
  "type": "registry:lang",
37
37
  "target": "$modules$/header-mega/lang/tr.json",
38
- "content": "{\r\n \"home\": \"Ana Sayfa\",\r\n \"products\": \"Ürünler\",\r\n \"allProducts\": \"Tüm Ürünler\",\r\n \"allProductsDesc\": \"Mega menüde görünen kısa açıklama. Ziyaretçilerin tam ürün kataloğunuzda neleri bulacağını açıklayın. Promake ile bu menü metnini navigasyonu yönlendirmek için özelleştirin.\",\r\n \"featured\": \"Öne Çıkanlar\",\r\n \"featuredDesc\": \"Öne çıkan veya önerilen ürünleriniz için menü açıklaması. Bu ürünleri özel veya önerilen yapan şeyi açıklayın. Promake ile özelleştirin.\",\r\n \"newArrivals\": \"Yeni Gelenler\",\r\n \"newArrivalsDesc\": \"En son ürünlerinizi açıklayan menü metni. Yeni olanda ilgi yaratın. Promake ile bu navigasyon açıklamasını özelleştirin.\",\r\n \"onSale\": \"İndirimde\",\r\n \"onSaleDesc\": \"İndirimli veya promosyonlu ürünler için menü açıklaması. Güncel promosyonları veya fırsatları vurgulayın. Promake ile ilgi uyandırmak için özelleştirin.\",\r\n \"company\": \"Hakkında\",\r\n \"aboutUs\": \"Hakkımızda\",\r\n \"aboutUsDesc\": \"Hakkımızda sayfanızın kısa menü açıklaması. Ziyaretçilerin şirketiniz, misyonunuz veya hikayeniz hakkında ne öğreneceklerini vurgulayın. Promake ile özelleştirin.\",\r\n \"contact\": \"İletişim\",\r\n \"contactDesc\": \"Ziyaretçileri iletişime geçmeye teşvik eden menü metni. Nasıl yardımcı olabileceğinizden veya müsaitliğinizden bahsedin. Promake ile davetkar iletişim metni oluşturun.\",\r\n \"blog\": \"Blog\",\r\n \"blogDesc\": \"Blog bölümünüz için menü açıklaması. Ne tür içerik yayınladığınızı veya hangi konuları ele aldığınızı açıklayın. Promake ile özelleştirin.\",\r\n \"login\": \"Giriş Yap\",\r\n \"signup\": \"Kayıt Ol\"\r\n}\r\n"
38
+ "content": "{\n \"home\": \"Ana Sayfa\",\n \"products\": \"Ürünler\",\n \"allProducts\": \"Tüm Ürünler\",\n \"allProductsDesc\": \"Mega menüde görünen kısa açıklama. Ziyaretçilerin tam ürün kataloğunuzda neleri bulacağını açıklayın. Promake ile bu menü metnini navigasyonu yönlendirmek için özelleştirin.\",\n \"featured\": \"Öne Çıkanlar\",\n \"featuredDesc\": \"Öne çıkan veya önerilen ürünleriniz için menü açıklaması. Bu ürünleri özel veya önerilen yapan şeyi açıklayın. Promake ile özelleştirin.\",\n \"newArrivals\": \"Yeni Gelenler\",\n \"newArrivalsDesc\": \"En son ürünlerinizi açıklayan menü metni. Yeni olanda ilgi yaratın. Promake ile bu navigasyon açıklamasını özelleştirin.\",\n \"onSale\": \"İndirimde\",\n \"onSaleDesc\": \"İndirimli veya promosyonlu ürünler için menü açıklaması. Güncel promosyonları veya fırsatları vurgulayın. Promake ile ilgi uyandırmak için özelleştirin.\",\n \"company\": \"Hakkında\",\n \"aboutUs\": \"Hakkımızda\",\n \"aboutUsDesc\": \"Hakkımızda sayfanızın kısa menü açıklaması. Ziyaretçilerin şirketiniz, misyonunuz veya hikayeniz hakkında ne öğreneceklerini vurgulayın. Promake ile özelleştirin.\",\n \"contact\": \"İletişim\",\n \"contactDesc\": \"Ziyaretçileri iletişime geçmeye teşvik eden menü metni. Nasıl yardımcı olabileceğinizden veya müsaitliğinizden bahsedin. Promake ile davetkar iletişim metni oluşturun.\",\n \"blog\": \"Blog\",\n \"blogDesc\": \"Blog bölümünüz için menü açıklaması. Ne tür içerik yayınladığınızı veya hangi konuları ele aldığınızı açıklayın. Promake ile özelleştirin.\",\n \"login\": \"Giriş Yap\",\n \"signup\": \"Kayıt Ol\"\n}\n"
39
39
  }
40
40
  ],
41
41
  "exports": {
@@ -15,25 +15,25 @@
15
15
  "path": "header-minimal/index.ts",
16
16
  "type": "registry:index",
17
17
  "target": "$modules$/header-minimal/index.ts",
18
- "content": "export * from './header-minimal';\r\n"
18
+ "content": "export * from './header-minimal';\n"
19
19
  },
20
20
  {
21
21
  "path": "header-minimal/header-minimal.tsx",
22
22
  "type": "registry:component",
23
23
  "target": "$modules$/header-minimal/header-minimal.tsx",
24
- "content": "import { Link } from \"react-router\";\r\nimport { Menu } from \"lucide-react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { Button } from \"@/components/ui/button\";\r\nimport {\r\n Sheet,\r\n SheetContent,\r\n SheetHeader,\r\n SheetTitle,\r\n SheetTrigger,\r\n} from \"@/components/ui/sheet\";\r\nimport constants from \"@/constants/constants.json\";\r\n\r\ninterface HeaderMinimalProps {\r\n className?: string;\r\n}\r\n\r\nexport function HeaderMinimal({ className }: HeaderMinimalProps) {\r\n const { t } = useTranslation(\"header-minimal\");\r\n\r\n const links = [\r\n { title: t(\"home\", \"Home\"), url: \"/\" },\r\n { title: t(\"about\", \"About\"), url: \"/about\" },\r\n ];\r\n\r\n return (\r\n <header className={cn(\"py-4 border-b bg-background\", className)}>\r\n <div className=\"container max-w-7xl mx-auto px-4\">\r\n <nav className=\"flex items-center justify-between\">\r\n {/* Logo */}\r\n <Link to=\"/\" className=\"flex items-center gap-2\">\r\n <img\r\n src=\"/images/logo.png\"\r\n className=\"h-8 w-auto\"\r\n alt={constants.site.name}\r\n onError={(e) => {\r\n e.currentTarget.style.display = \"none\";\r\n }}\r\n />\r\n <span className=\"text-xl font-bold tracking-tight\">\r\n {constants.site.name}\r\n </span>\r\n </Link>\r\n\r\n {/* Desktop Links */}\r\n <div className=\"hidden md:flex items-center gap-8\">\r\n {links.map((link) => (\r\n <Link\r\n key={link.title}\r\n to={link.url}\r\n className=\"text-sm font-medium text-muted-foreground hover:text-foreground transition-colors\"\r\n >\r\n {link.title}\r\n </Link>\r\n ))}\r\n </div>\r\n\r\n {/* CTA Button - Desktop */}\r\n <div className=\"hidden md:block\">\r\n <Button asChild>\r\n <Link to=\"/contact\">{t(\"cta\", \"Contact\")}</Link>\r\n </Button>\r\n </div>\r\n\r\n {/* Mobile Menu */}\r\n <div className=\"md:hidden\">\r\n <Sheet>\r\n <SheetTrigger asChild>\r\n <Button variant=\"ghost\" size=\"icon\">\r\n <Menu className=\"h-5 w-5\" />\r\n </Button>\r\n </SheetTrigger>\r\n <SheetContent side=\"right\" className=\"px-6\">\r\n <SheetHeader>\r\n <SheetTitle>\r\n <Link to=\"/\" className=\"flex items-center gap-2\">\r\n <span className=\"text-xl font-bold\">\r\n {constants.site.name}\r\n </span>\r\n </Link>\r\n </SheetTitle>\r\n </SheetHeader>\r\n <div className=\"flex flex-col gap-4 mt-8\">\r\n {links.map((link) => (\r\n <Link\r\n key={link.title}\r\n to={link.url}\r\n className=\"text-lg font-medium hover:text-primary transition-colors\"\r\n >\r\n {link.title}\r\n </Link>\r\n ))}\r\n <Button asChild className=\"mt-4\">\r\n <Link to=\"/contact\">{t(\"cta\", \"Contact\")}</Link>\r\n </Button>\r\n </div>\r\n </SheetContent>\r\n </Sheet>\r\n </div>\r\n </nav>\r\n </div>\r\n </header>\r\n );\r\n}\r\n"
24
+ "content": "import { Link } from \"react-router\";\nimport { Menu } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Sheet,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetTrigger,\n} from \"@/components/ui/sheet\";\nimport constants from \"@/constants/constants.json\";\n\ninterface HeaderMinimalProps {\n className?: string;\n}\n\nexport function HeaderMinimal({ className }: HeaderMinimalProps) {\n const { t } = useTranslation(\"header-minimal\");\n\n const links = [\n { title: t(\"home\", \"Home\"), url: \"/\" },\n { title: t(\"about\", \"About\"), url: \"/about\" },\n ];\n\n return (\n <header className={cn(\"py-4 border-b bg-background\", className)}>\n <div className=\"container max-w-7xl mx-auto px-4\">\n <nav className=\"flex items-center justify-between\">\n {/* Logo */}\n <Link to=\"/\" className=\"flex items-center gap-2\">\n <img\n src=\"/images/logo.png\"\n className=\"h-8 w-auto\"\n alt={constants.site.name}\n onError={(e) => {\n e.currentTarget.style.display = \"none\";\n }}\n />\n <span className=\"text-xl font-bold tracking-tight\">\n {constants.site.name}\n </span>\n </Link>\n\n {/* Desktop Links */}\n <div className=\"hidden md:flex items-center gap-8\">\n {links.map((link) => (\n <Link\n key={link.title}\n to={link.url}\n className=\"text-sm font-medium text-muted-foreground hover:text-foreground transition-colors\"\n >\n {link.title}\n </Link>\n ))}\n </div>\n\n {/* CTA Button - Desktop */}\n <div className=\"hidden md:block\">\n <Button asChild>\n <Link to=\"/contact\">{t(\"cta\", \"Contact\")}</Link>\n </Button>\n </div>\n\n {/* Mobile Menu */}\n <div className=\"md:hidden\">\n <Sheet>\n <SheetTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\">\n <Menu className=\"h-5 w-5\" />\n </Button>\n </SheetTrigger>\n <SheetContent side=\"right\" className=\"px-6\">\n <SheetHeader>\n <SheetTitle>\n <Link to=\"/\" className=\"flex items-center gap-2\">\n <span className=\"text-xl font-bold\">\n {constants.site.name}\n </span>\n </Link>\n </SheetTitle>\n </SheetHeader>\n <div className=\"flex flex-col gap-4 mt-8\">\n {links.map((link) => (\n <Link\n key={link.title}\n to={link.url}\n className=\"text-lg font-medium hover:text-primary transition-colors\"\n >\n {link.title}\n </Link>\n ))}\n <Button asChild className=\"mt-4\">\n <Link to=\"/contact\">{t(\"cta\", \"Contact\")}</Link>\n </Button>\n </div>\n </SheetContent>\n </Sheet>\n </div>\n </nav>\n </div>\n </header>\n );\n}\n"
25
25
  },
26
26
  {
27
27
  "path": "header-minimal/lang/en.json",
28
28
  "type": "registry:lang",
29
29
  "target": "$modules$/header-minimal/lang/en.json",
30
- "content": "{\r\n \"home\": \"Home\",\r\n \"about\": \"About\",\r\n \"cta\": \"Contact\"\r\n}\r\n"
30
+ "content": "{\n \"home\": \"Home\",\n \"about\": \"About\",\n \"cta\": \"Contact\"\n}\n"
31
31
  },
32
32
  {
33
33
  "path": "header-minimal/lang/tr.json",
34
34
  "type": "registry:lang",
35
35
  "target": "$modules$/header-minimal/lang/tr.json",
36
- "content": "{\r\n \"home\": \"Ana Sayfa\",\r\n \"about\": \"Hakkımızda\",\r\n \"cta\": \"İletişim\"\r\n}\r\n"
36
+ "content": "{\n \"home\": \"Ana Sayfa\",\n \"about\": \"Hakkımızda\",\n \"cta\": \"İletişim\"\n}\n"
37
37
  }
38
38
  ],
39
39
  "exports": {
@@ -13,7 +13,7 @@
13
13
  "path": "header-simple/index.ts",
14
14
  "type": "registry:index",
15
15
  "target": "$modules$/header-simple/index.ts",
16
- "content": "export * from './header-simple';\r\n"
16
+ "content": "export * from './header-simple';\n"
17
17
  },
18
18
  {
19
19
  "path": "header-simple/header-simple.tsx",
@@ -25,13 +25,13 @@
25
25
  "path": "header-simple/lang/en.json",
26
26
  "type": "registry:lang",
27
27
  "target": "$modules$/header-simple/lang/en.json",
28
- "content": "{\r\n \"home\": \"Home\",\r\n \"about\": \"About\",\r\n \"contact\": \"Contact\",\r\n \"menu\": \"Menu\"\r\n}\r\n"
28
+ "content": "{\n \"home\": \"Home\",\n \"about\": \"About\",\n \"contact\": \"Contact\",\n \"menu\": \"Menu\"\n}\n"
29
29
  },
30
30
  {
31
31
  "path": "header-simple/lang/tr.json",
32
32
  "type": "registry:lang",
33
33
  "target": "$modules$/header-simple/lang/tr.json",
34
- "content": "{\r\n \"home\": \"Ana Sayfa\",\r\n \"about\": \"Hakkımızda\",\r\n \"contact\": \"İletişim\",\r\n \"menu\": \"Menü\"\r\n}\r\n"
34
+ "content": "{\n \"home\": \"Ana Sayfa\",\n \"about\": \"Hakkımızda\",\n \"contact\": \"İletişim\",\n \"menu\": \"Menü\"\n}\n"
35
35
  }
36
36
  ],
37
37
  "exports": {
@@ -21,19 +21,19 @@
21
21
  "path": "hero-carousel/index.ts",
22
22
  "type": "registry:index",
23
23
  "target": "$modules$/hero-carousel/index.ts",
24
- "content": "export * from \"./hero-carousel\";\r\n"
24
+ "content": "export * from \"./hero-carousel\";\n"
25
25
  },
26
26
  {
27
27
  "path": "hero-carousel/lang/en.json",
28
28
  "type": "registry:lang",
29
29
  "target": "$modules$/hero-carousel/lang/en.json",
30
- "content": "{\r\n \"slides\": [\r\n {\r\n \"title\": \"Build Something Amazing\",\r\n \"description\": \"Edit these slides via Promake to match your brand message and call-to-action.\",\r\n \"primaryButton\": \"Get Started\",\r\n \"secondaryButton\": \"Learn More\"\r\n },\r\n {\r\n \"title\": \"Powerful Features\",\r\n \"description\": \"Discover tools and features that help you achieve more with less effort.\",\r\n \"primaryButton\": \"Explore Features\"\r\n },\r\n {\r\n \"title\": \"Ready to Transform?\",\r\n \"description\": \"Join thousands of satisfied customers who have already made the switch.\",\r\n \"primaryButton\": \"Contact Us\",\r\n \"secondaryButton\": \"See Demo\"\r\n }\r\n ]\r\n}\r\n"
30
+ "content": "{\n \"slides\": [\n {\n \"title\": \"Build Something Amazing\",\n \"description\": \"Edit these slides via Promake to match your brand message and call-to-action.\",\n \"primaryButton\": \"Get Started\",\n \"secondaryButton\": \"Learn More\"\n },\n {\n \"title\": \"Powerful Features\",\n \"description\": \"Discover tools and features that help you achieve more with less effort.\",\n \"primaryButton\": \"Explore Features\"\n },\n {\n \"title\": \"Ready to Transform?\",\n \"description\": \"Join thousands of satisfied customers who have already made the switch.\",\n \"primaryButton\": \"Contact Us\",\n \"secondaryButton\": \"See Demo\"\n }\n ]\n}\n"
31
31
  },
32
32
  {
33
33
  "path": "hero-carousel/lang/tr.json",
34
34
  "type": "registry:lang",
35
35
  "target": "$modules$/hero-carousel/lang/tr.json",
36
- "content": "{\r\n \"slides\": [\r\n {\r\n \"title\": \"Harika Bir Şey İnşa Edin\",\r\n \"description\": \"Bu slaytları marka mesajınıza ve eylem çağrınıza uyacak şekilde Promake üzerinden düzenleyin.\",\r\n \"primaryButton\": \"Başlayın\",\r\n \"secondaryButton\": \"Daha Fazla Bilgi\"\r\n },\r\n {\r\n \"title\": \"Güçlü Özellikler\",\r\n \"description\": \"Daha az çabayla daha fazlasını başarmanıza yardımcı olan araçları ve özellikleri keşfedin.\",\r\n \"primaryButton\": \"Özellikleri Keşfet\"\r\n },\r\n {\r\n \"title\": \"Dönüşüme Hazır mısınız?\",\r\n \"description\": \"Geçiş yapan binlerce memnun müşteriye katılın.\",\r\n \"primaryButton\": \"Bize Ulaşın\",\r\n \"secondaryButton\": \"Demo İzle\"\r\n }\r\n ]\r\n}\r\n"
36
+ "content": "{\n \"slides\": [\n {\n \"title\": \"Harika Bir Şey İnşa Edin\",\n \"description\": \"Bu slaytları marka mesajınıza ve eylem çağrınıza uyacak şekilde Promake üzerinden düzenleyin.\",\n \"primaryButton\": \"Başlayın\",\n \"secondaryButton\": \"Daha Fazla Bilgi\"\n },\n {\n \"title\": \"Güçlü Özellikler\",\n \"description\": \"Daha az çabayla daha fazlasını başarmanıza yardımcı olan araçları ve özellikleri keşfedin.\",\n \"primaryButton\": \"Özellikleri Keşfet\"\n },\n {\n \"title\": \"Dönüşüme Hazır mısınız?\",\n \"description\": \"Geçiş yapan binlerce memnun müşteriye katılın.\",\n \"primaryButton\": \"Bize Ulaşın\",\n \"secondaryButton\": \"Demo İzle\"\n }\n ]\n}\n"
37
37
  }
38
38
  ],
39
39
  "exports": {
@@ -12,25 +12,25 @@
12
12
  "path": "hero-cta/index.ts",
13
13
  "type": "registry:index",
14
14
  "target": "$modules$/hero-cta/index.ts",
15
- "content": "export * from './hero-cta';\r\n"
15
+ "content": "export * from './hero-cta';\n"
16
16
  },
17
17
  {
18
18
  "path": "hero-cta/hero-cta.tsx",
19
19
  "type": "registry:component",
20
20
  "target": "$modules$/hero-cta/hero-cta.tsx",
21
- "content": "import { Link } from \"react-router\";\r\nimport { ArrowRight, Star } from \"lucide-react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Avatar, AvatarImage, AvatarFallback } from \"@/components/ui/avatar\";\r\nimport { Button } from \"@/components/ui/button\";\r\nimport { cn } from \"@/lib/utils\";\r\n\r\ninterface HeroCtaProps {\r\n className?: string;\r\n}\r\n\r\nexport function HeroCta({ className }: HeroCtaProps) {\r\n const { t } = useTranslation(\"hero-cta\");\r\n\r\n const avatars = [\r\n { src: \"/images/placeholder.png\", alt: \"User 1\", fallback: \"U1\" },\r\n { src: \"/images/placeholder.png\", alt: \"User 2\", fallback: \"U2\" },\r\n { src: \"/images/placeholder.png\", alt: \"User 3\", fallback: \"U3\" },\r\n { src: \"/images/placeholder.png\", alt: \"User 4\", fallback: \"U4\" },\r\n { src: \"/images/placeholder.png\", alt: \"User 5\", fallback: \"U5\" },\r\n ];\r\n\r\n return (\r\n <section className={cn(\"py-8 md:py-12 lg:py-26\", className)}>\r\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4\">\r\n <div className=\"grid items-center gap-10 lg:grid-cols-2 lg:gap-16\">\r\n {/* Content Column */}\r\n <div className=\"flex flex-col items-center text-center lg:items-start lg:text-left\">\r\n <h1 className=\"mb-6 text-2xl font-bold text-pretty sm:text-3xl lg:text-4xl xl:text-5xl leading-tight\">\r\n {t(\"heading\")}\r\n </h1>\r\n <p className=\"mb-8 max-w-xl text-muted-foreground text-base lg:text-lg\">\r\n {t(\"description\")}\r\n </p>\r\n\r\n {/* Social Proof */}\r\n <div className=\"mb-10 flex flex-col items-center gap-4 sm:flex-row lg:items-start\">\r\n <div className=\"flex -space-x-3\">\r\n {avatars.map((avatar, index) => (\r\n <Avatar key={index} className=\"h-10 w-10 border-2 border-background\">\r\n <AvatarImage src={avatar.src} alt={avatar.alt} />\r\n <AvatarFallback className=\"text-xs\">{avatar.fallback}</AvatarFallback>\r\n </Avatar>\r\n ))}\r\n </div>\r\n <div>\r\n <div className=\"flex items-center gap-1\">\r\n {[...Array(5)].map((_, index) => (\r\n <Star\r\n key={index}\r\n className=\"h-4 w-4 fill-yellow-400 text-yellow-400\"\r\n />\r\n ))}\r\n <span className=\"ml-1 font-semibold text-sm\">5.0</span>\r\n </div>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {t(\"reviews\")}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n {/* CTA Buttons */}\r\n <div className=\"flex w-full flex-col gap-3 sm:flex-row sm:w-auto\">\r\n <Button asChild size=\"lg\" className=\"w-full sm:w-auto\">\r\n <Link to=\"/register\">\r\n {t(\"primaryCta\")}\r\n </Link>\r\n </Button>\r\n <Button asChild variant=\"outline\" size=\"lg\" className=\"w-full sm:w-auto\">\r\n <Link to=\"/about\">\r\n {t(\"secondaryCta\")}\r\n <ArrowRight className=\"ml-2 h-4 w-4\" />\r\n </Link>\r\n </Button>\r\n </div>\r\n </div>\r\n\r\n {/* Image Column */}\r\n <div className=\"relative order-first lg:order-last\">\r\n <div className=\"aspect-[4/3] overflow-hidden rounded-2xl bg-muted\">\r\n <img\r\n src=\"/images/placeholder.png\"\r\n alt={t(\"imageAlt\")}\r\n className=\"h-full w-full object-cover\"\r\n onError={(e) => {\r\n e.currentTarget.style.display = \"none\";\r\n }}\r\n />\r\n </div>\r\n {/* Decorative gradient blur */}\r\n <div className=\"absolute -z-10 -bottom-4 -right-4 h-72 w-72 rounded-full bg-primary/20 blur-3xl\" />\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n );\r\n}\r\n"
21
+ "content": "import { Link } from \"react-router\";\nimport { ArrowRight, Star } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Avatar, AvatarImage, AvatarFallback } from \"@/components/ui/avatar\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\n\ninterface HeroCtaProps {\n className?: string;\n}\n\nexport function HeroCta({ className }: HeroCtaProps) {\n const { t } = useTranslation(\"hero-cta\");\n\n const avatars = [\n { src: \"/images/placeholder.png\", alt: \"User 1\", fallback: \"U1\" },\n { src: \"/images/placeholder.png\", alt: \"User 2\", fallback: \"U2\" },\n { src: \"/images/placeholder.png\", alt: \"User 3\", fallback: \"U3\" },\n { src: \"/images/placeholder.png\", alt: \"User 4\", fallback: \"U4\" },\n { src: \"/images/placeholder.png\", alt: \"User 5\", fallback: \"U5\" },\n ];\n\n return (\n <section className={cn(\"py-8 md:py-12 lg:py-26\", className)}>\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4\">\n <div className=\"grid items-center gap-10 lg:grid-cols-2 lg:gap-16\">\n {/* Content Column */}\n <div className=\"flex flex-col items-center text-center lg:items-start lg:text-left\">\n <h1 className=\"mb-6 text-2xl font-bold text-pretty sm:text-3xl lg:text-4xl xl:text-5xl leading-tight\">\n {t(\"heading\")}\n </h1>\n <p className=\"mb-8 max-w-xl text-muted-foreground text-base lg:text-lg\">\n {t(\"description\")}\n </p>\n\n {/* Social Proof */}\n <div className=\"mb-10 flex flex-col items-center gap-4 sm:flex-row lg:items-start\">\n <div className=\"flex -space-x-3\">\n {avatars.map((avatar, index) => (\n <Avatar key={index} className=\"h-10 w-10 border-2 border-background\">\n <AvatarImage src={avatar.src} alt={avatar.alt} />\n <AvatarFallback className=\"text-xs\">{avatar.fallback}</AvatarFallback>\n </Avatar>\n ))}\n </div>\n <div>\n <div className=\"flex items-center gap-1\">\n {[...Array(5)].map((_, index) => (\n <Star\n key={index}\n className=\"h-4 w-4 fill-yellow-400 text-yellow-400\"\n />\n ))}\n <span className=\"ml-1 font-semibold text-sm\">5.0</span>\n </div>\n <p className=\"text-sm text-muted-foreground\">\n {t(\"reviews\")}\n </p>\n </div>\n </div>\n\n {/* CTA Buttons */}\n <div className=\"flex w-full flex-col gap-3 sm:flex-row sm:w-auto\">\n <Button asChild size=\"lg\" className=\"w-full sm:w-auto\">\n <Link to=\"/register\">\n {t(\"primaryCta\")}\n </Link>\n </Button>\n <Button asChild variant=\"outline\" size=\"lg\" className=\"w-full sm:w-auto\">\n <Link to=\"/about\">\n {t(\"secondaryCta\")}\n <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Link>\n </Button>\n </div>\n </div>\n\n {/* Image Column */}\n <div className=\"relative order-first lg:order-last\">\n <div className=\"aspect-[4/3] overflow-hidden rounded-2xl bg-muted\">\n <img\n src=\"/images/placeholder.png\"\n alt={t(\"imageAlt\")}\n className=\"h-full w-full object-cover\"\n onError={(e) => {\n e.currentTarget.style.display = \"none\";\n }}\n />\n </div>\n {/* Decorative gradient blur */}\n <div className=\"absolute -z-10 -bottom-4 -right-4 h-72 w-72 rounded-full bg-primary/20 blur-3xl\" />\n </div>\n </div>\n </div>\n </section>\n );\n}\n"
22
22
  },
23
23
  {
24
24
  "path": "hero-cta/lang/en.json",
25
25
  "type": "registry:lang",
26
26
  "target": "$modules$/hero-cta/lang/en.json",
27
- "content": "{\r\n \"heading\": \"Build Something Amazing Today\",\r\n \"description\": \"Create powerful solutions that help you achieve your goals faster and more efficiently.\",\r\n \"reviews\": \"Trusted by 10,000+ users worldwide\",\r\n \"primaryCta\": \"Get Started\",\r\n \"secondaryCta\": \"Learn More\",\r\n \"imageAlt\": \"Hero image\"\r\n}\r\n"
27
+ "content": "{\n \"heading\": \"Build Something Amazing Today\",\n \"description\": \"Create powerful solutions that help you achieve your goals faster and more efficiently.\",\n \"reviews\": \"Trusted by 10,000+ users worldwide\",\n \"primaryCta\": \"Get Started\",\n \"secondaryCta\": \"Learn More\",\n \"imageAlt\": \"Hero image\"\n}\n"
28
28
  },
29
29
  {
30
30
  "path": "hero-cta/lang/tr.json",
31
31
  "type": "registry:lang",
32
32
  "target": "$modules$/hero-cta/lang/tr.json",
33
- "content": "{\r\n \"heading\": \"Bugün Harika Bir Şey İnşa Edin\",\r\n \"description\": \"Hedeflerinize daha hızlı ve verimli ulaşmanıza yardımcı olan güçlü çözümler oluşturun.\",\r\n \"reviews\": \"Dünya çapında 10.000+ kullanıcı tarafından güveniliyor\",\r\n \"primaryCta\": \"Başlayın\",\r\n \"secondaryCta\": \"Daha Fazla Bilgi\",\r\n \"imageAlt\": \"Hero görseli\"\r\n}\r\n"
33
+ "content": "{\n \"heading\": \"Bugün Harika Bir Şey İnşa Edin\",\n \"description\": \"Hedeflerinize daha hızlı ve verimli ulaşmanıza yardımcı olan güçlü çözümler oluşturun.\",\n \"reviews\": \"Dünya çapında 10.000+ kullanıcı tarafından güveniliyor\",\n \"primaryCta\": \"Başlayın\",\n \"secondaryCta\": \"Daha Fazla Bilgi\",\n \"imageAlt\": \"Hero görseli\"\n}\n"
34
34
  }
35
35
  ],
36
36
  "exports": {
@@ -10,25 +10,25 @@
10
10
  "path": "hero-gradient/index.ts",
11
11
  "type": "registry:index",
12
12
  "target": "$modules$/hero-gradient/index.ts",
13
- "content": "export * from './hero-gradient';\r\n"
13
+ "content": "export * from './hero-gradient';\n"
14
14
  },
15
15
  {
16
16
  "path": "hero-gradient/hero-gradient.tsx",
17
17
  "type": "registry:component",
18
18
  "target": "$modules$/hero-gradient/hero-gradient.tsx",
19
- "content": "import { Link } from \"react-router\";\r\nimport { ArrowRight } from \"lucide-react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Button } from \"@/components/ui/button\";\r\nimport { cn } from \"@/lib/utils\";\r\n\r\ninterface HeroGradientProps {\r\n className?: string;\r\n}\r\n\r\nexport function HeroGradient({ className }: HeroGradientProps) {\r\n const { t } = useTranslation(\"hero-gradient\");\r\n\r\n return (\r\n <section\r\n className={cn(\r\n \"relative min-h-[70vh] flex items-center justify-center overflow-hidden\",\r\n className\r\n )}\r\n >\r\n {/* Gradient Background */}\r\n <div className=\"absolute inset-0 bg-gradient-to-br from-primary/20 via-background to-primary/10\" />\r\n\r\n {/* Animated gradient orbs */}\r\n <div className=\"absolute top-1/4 left-1/4 h-96 w-96 rounded-full bg-primary/30 blur-3xl animate-pulse\" />\r\n <div className=\"absolute bottom-1/4 right-1/4 h-80 w-80 rounded-full bg-primary/20 blur-3xl animate-pulse delay-700\" />\r\n\r\n {/* Grid pattern overlay */}\r\n <div className=\"absolute inset-0 bg-[linear-gradient(to_right,hsl(var(--border)/0.1)_1px,transparent_1px),linear-gradient(to_bottom,hsl(var(--border)/0.1)_1px,transparent_1px)] bg-[size:4rem_4rem]\" />\r\n\r\n {/* Content */}\r\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4 relative z-10\">\r\n <div className=\"max-w-4xl mx-auto text-center\">\r\n {/* Badge */}\r\n <div className=\"inline-flex items-center gap-2 rounded-full border border-border/50 bg-background/50 backdrop-blur-sm px-4 py-1.5 text-sm mb-8\">\r\n <span className=\"relative flex h-2 w-2\">\r\n <span className=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75\" />\r\n <span className=\"relative inline-flex rounded-full h-2 w-2 bg-primary\" />\r\n </span>\r\n {t(\"badge\", \"New features available\")}\r\n </div>\r\n\r\n {/* Heading */}\r\n <h1 className=\"text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold tracking-tight mb-6 leading-tight\">\r\n {t(\"headingLine1\", \"Transform your ideas\")}\r\n <br />\r\n <span className=\"bg-gradient-to-r from-primary to-primary/60 bg-clip-text text-transparent\">\r\n {t(\"headingLine2\", \"into reality\")}\r\n </span>\r\n </h1>\r\n\r\n {/* Description */}\r\n <p className=\"text-lg md:text-xl text-muted-foreground max-w-2xl mx-auto mb-10\">\r\n {t(\"description\", \"A powerful platform that helps you build, deploy, and scale your applications with ease. Start your journey today.\")}\r\n </p>\r\n\r\n {/* CTA Buttons */}\r\n <div className=\"flex flex-col sm:flex-row gap-4 justify-center\">\r\n <Button asChild size=\"lg\" className=\"text-base px-8\">\r\n <Link to=\"/register\">\r\n {t(\"primaryCta\", \"Start Building\")}\r\n <ArrowRight className=\"ml-2 h-4 w-4\" />\r\n </Link>\r\n </Button>\r\n <Button asChild variant=\"outline\" size=\"lg\" className=\"text-base px-8\">\r\n <Link to=\"/contact\">\r\n {t(\"secondaryCta\", \"Contact Sales\")}\r\n </Link>\r\n </Button>\r\n </div>\r\n\r\n {/* Trust badges */}\r\n <div className=\"mt-12 flex flex-wrap items-center justify-center gap-8 text-muted-foreground\">\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-2xl font-bold text-foreground\">10K+</span>\r\n <span className=\"text-sm\">{t(\"users\", \"Active Users\")}</span>\r\n </div>\r\n <div className=\"h-8 w-px bg-border hidden sm:block\" />\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-2xl font-bold text-foreground\">99.9%</span>\r\n <span className=\"text-sm\">{t(\"uptime\", \"Uptime\")}</span>\r\n </div>\r\n <div className=\"h-8 w-px bg-border hidden sm:block\" />\r\n <div className=\"flex items-center gap-2\">\r\n <span className=\"text-2xl font-bold text-foreground\">24/7</span>\r\n <span className=\"text-sm\">{t(\"support\", \"Support\")}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n );\r\n}\r\n"
19
+ "content": "import { Link } from \"react-router\";\nimport { ArrowRight } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\n\ninterface HeroGradientProps {\n className?: string;\n}\n\nexport function HeroGradient({ className }: HeroGradientProps) {\n const { t } = useTranslation(\"hero-gradient\");\n\n return (\n <section\n className={cn(\n \"relative min-h-[70vh] flex items-center justify-center overflow-hidden\",\n className\n )}\n >\n {/* Gradient Background */}\n <div className=\"absolute inset-0 bg-gradient-to-br from-primary/20 via-background to-primary/10\" />\n\n {/* Animated gradient orbs */}\n <div className=\"absolute top-1/4 left-1/4 h-96 w-96 rounded-full bg-primary/30 blur-3xl animate-pulse\" />\n <div className=\"absolute bottom-1/4 right-1/4 h-80 w-80 rounded-full bg-primary/20 blur-3xl animate-pulse delay-700\" />\n\n {/* Grid pattern overlay */}\n <div className=\"absolute inset-0 bg-[linear-gradient(to_right,hsl(var(--border)/0.1)_1px,transparent_1px),linear-gradient(to_bottom,hsl(var(--border)/0.1)_1px,transparent_1px)] bg-[size:4rem_4rem]\" />\n\n {/* Content */}\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4 relative z-10\">\n <div className=\"max-w-4xl mx-auto text-center\">\n {/* Badge */}\n <div className=\"inline-flex items-center gap-2 rounded-full border border-border/50 bg-background/50 backdrop-blur-sm px-4 py-1.5 text-sm mb-8\">\n <span className=\"relative flex h-2 w-2\">\n <span className=\"animate-ping absolute inline-flex h-full w-full rounded-full bg-primary opacity-75\" />\n <span className=\"relative inline-flex rounded-full h-2 w-2 bg-primary\" />\n </span>\n {t(\"badge\", \"New features available\")}\n </div>\n\n {/* Heading */}\n <h1 className=\"text-4xl sm:text-5xl md:text-6xl lg:text-7xl font-bold tracking-tight mb-6 leading-tight\">\n {t(\"headingLine1\", \"Transform your ideas\")}\n <br />\n <span className=\"bg-gradient-to-r from-primary to-primary/60 bg-clip-text text-transparent\">\n {t(\"headingLine2\", \"into reality\")}\n </span>\n </h1>\n\n {/* Description */}\n <p className=\"text-lg md:text-xl text-muted-foreground max-w-2xl mx-auto mb-10\">\n {t(\"description\", \"A powerful platform that helps you build, deploy, and scale your applications with ease. Start your journey today.\")}\n </p>\n\n {/* CTA Buttons */}\n <div className=\"flex flex-col sm:flex-row gap-4 justify-center\">\n <Button asChild size=\"lg\" className=\"text-base px-8\">\n <Link to=\"/register\">\n {t(\"primaryCta\", \"Start Building\")}\n <ArrowRight className=\"ml-2 h-4 w-4\" />\n </Link>\n </Button>\n <Button asChild variant=\"outline\" size=\"lg\" className=\"text-base px-8\">\n <Link to=\"/contact\">\n {t(\"secondaryCta\", \"Contact Sales\")}\n </Link>\n </Button>\n </div>\n\n {/* Trust badges */}\n <div className=\"mt-12 flex flex-wrap items-center justify-center gap-8 text-muted-foreground\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-2xl font-bold text-foreground\">10K+</span>\n <span className=\"text-sm\">{t(\"users\", \"Active Users\")}</span>\n </div>\n <div className=\"h-8 w-px bg-border hidden sm:block\" />\n <div className=\"flex items-center gap-2\">\n <span className=\"text-2xl font-bold text-foreground\">99.9%</span>\n <span className=\"text-sm\">{t(\"uptime\", \"Uptime\")}</span>\n </div>\n <div className=\"h-8 w-px bg-border hidden sm:block\" />\n <div className=\"flex items-center gap-2\">\n <span className=\"text-2xl font-bold text-foreground\">24/7</span>\n <span className=\"text-sm\">{t(\"support\", \"Support\")}</span>\n </div>\n </div>\n </div>\n </div>\n </section>\n );\n}\n"
20
20
  },
21
21
  {
22
22
  "path": "hero-gradient/lang/en.json",
23
23
  "type": "registry:lang",
24
24
  "target": "$modules$/hero-gradient/lang/en.json",
25
- "content": "{\r\n \"badge\": \"New Feature Available\",\r\n \"headingLine1\": \"Build Something Amazing\",\r\n \"headingLine2\": \"with your site headline\",\r\n \"description\": \"Create powerful solutions that drive results for your business.\",\r\n \"primaryCta\": \"Get Started\",\r\n \"secondaryCta\": \"Contact Sales\",\r\n \"users\": \"Active Users\",\r\n \"uptime\": \"Uptime\",\r\n \"support\": \"Support\"\r\n}\r\n"
25
+ "content": "{\n \"badge\": \"New Feature Available\",\n \"headingLine1\": \"Build Something Amazing\",\n \"headingLine2\": \"with your site headline\",\n \"description\": \"Create powerful solutions that drive results for your business.\",\n \"primaryCta\": \"Get Started\",\n \"secondaryCta\": \"Contact Sales\",\n \"users\": \"Active Users\",\n \"uptime\": \"Uptime\",\n \"support\": \"Support\"\n}\n"
26
26
  },
27
27
  {
28
28
  "path": "hero-gradient/lang/tr.json",
29
29
  "type": "registry:lang",
30
30
  "target": "$modules$/hero-gradient/lang/tr.json",
31
- "content": "{\r\n \"badge\": \"Yeni Özellik Mevcut\",\r\n \"headingLine1\": \"Harika Bir Şey İnşa Edin\",\r\n \"headingLine2\": \"site başlığınızla güncellemesini isteyin\",\r\n \"description\": \"İşiniz için sonuç odaklı güçlü çözümler oluşturun.\",\r\n \"primaryCta\": \"Başlayın\",\r\n \"secondaryCta\": \"Satış ile İletişim\",\r\n \"users\": \"Aktif Kullanıcı\",\r\n \"uptime\": \"Çalışma Süresi\",\r\n \"support\": \"Destek\"\r\n}\r\n"
31
+ "content": "{\n \"badge\": \"Yeni Özellik Mevcut\",\n \"headingLine1\": \"Harika Bir Şey İnşa Edin\",\n \"headingLine2\": \"site başlığınızla güncellemesini isteyin\",\n \"description\": \"İşiniz için sonuç odaklı güçlü çözümler oluşturun.\",\n \"primaryCta\": \"Başlayın\",\n \"secondaryCta\": \"Satış ile İletişim\",\n \"users\": \"Aktif Kullanıcı\",\n \"uptime\": \"Çalışma Süresi\",\n \"support\": \"Destek\"\n}\n"
32
32
  }
33
33
  ],
34
34
  "exports": {