@promakeai/cli 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +212 -0
- package/dist/registry/about-page.json +45 -0
- package/dist/registry/about-section.json +40 -0
- package/dist/registry/animations.json +69 -0
- package/dist/registry/bento-grid-section.json +42 -0
- package/dist/registry/blog-core.json +74 -0
- package/dist/registry/blog-list-page.json +48 -0
- package/dist/registry/blog-section.json +43 -0
- package/dist/registry/cards-carousel-section.json +46 -0
- package/dist/registry/cart-drawer.json +43 -0
- package/dist/registry/cart-page.json +47 -0
- package/dist/registry/category-section.json +43 -0
- package/dist/registry/checkout-page.json +47 -0
- package/dist/registry/contact-info-grid.json +40 -0
- package/dist/registry/contact-page-centered.json +50 -0
- package/dist/registry/contact-page-map-overlay.json +54 -0
- package/dist/registry/contact-page-map-split.json +54 -0
- package/dist/registry/contact-page-split.json +49 -0
- package/dist/registry/contact-page.json +45 -0
- package/dist/registry/content-section.json +40 -0
- package/dist/registry/cookies-page.json +45 -0
- package/dist/registry/cta-section.json +40 -0
- package/dist/registry/docs/about-page.md +32 -0
- package/dist/registry/docs/about-section.md +33 -0
- package/dist/registry/docs/animations.md +44 -0
- package/dist/registry/docs/bento-grid-section.md +40 -0
- package/dist/registry/docs/blog-core.md +37 -0
- package/dist/registry/docs/blog-list-page.md +38 -0
- package/dist/registry/docs/blog-section.md +39 -0
- package/dist/registry/docs/cards-carousel-section.md +39 -0
- package/dist/registry/docs/cart-drawer.md +42 -0
- package/dist/registry/docs/cart-page.md +37 -0
- package/dist/registry/docs/category-section.md +34 -0
- package/dist/registry/docs/checkout-page.md +38 -0
- package/dist/registry/docs/contact-info-grid.md +33 -0
- package/dist/registry/docs/contact-page-centered.md +41 -0
- package/dist/registry/docs/contact-page-map-overlay.md +44 -0
- package/dist/registry/docs/contact-page-map-split.md +44 -0
- package/dist/registry/docs/contact-page-split.md +40 -0
- package/dist/registry/docs/contact-page.md +33 -0
- package/dist/registry/docs/content-section.md +35 -0
- package/dist/registry/docs/cookies-page.md +32 -0
- package/dist/registry/docs/cta-section.md +32 -0
- package/dist/registry/docs/ecommerce-core.md +41 -0
- package/dist/registry/docs/empty-page.md +31 -0
- package/dist/registry/docs/faq-categorized.md +38 -0
- package/dist/registry/docs/faq-simple.md +38 -0
- package/dist/registry/docs/favorites-blog-block.md +38 -0
- package/dist/registry/docs/favorites-ecommerce-block.md +38 -0
- package/dist/registry/docs/feature-section.md +33 -0
- package/dist/registry/docs/featured-products.md +38 -0
- package/dist/registry/docs/footer-detailed.md +33 -0
- package/dist/registry/docs/footer-minimal.md +32 -0
- package/dist/registry/docs/footer.md +32 -0
- package/dist/registry/docs/google-map.md +36 -0
- package/dist/registry/docs/header-centered-pill.md +37 -0
- package/dist/registry/docs/header-ecommerce.md +38 -0
- package/dist/registry/docs/header-mega.md +40 -0
- package/dist/registry/docs/header-minimal.md +38 -0
- package/dist/registry/docs/header-simple.md +32 -0
- package/dist/registry/docs/hero-cta.md +38 -0
- package/dist/registry/docs/hero-gradient.md +33 -0
- package/dist/registry/docs/hero-grid.md +40 -0
- package/dist/registry/docs/hero-profile.md +33 -0
- package/dist/registry/docs/hero.md +32 -0
- package/dist/registry/docs/login-page-split.md +40 -0
- package/dist/registry/docs/login-page.md +39 -0
- package/dist/registry/docs/newsletter-section.md +40 -0
- package/dist/registry/docs/order-card-compact.md +37 -0
- package/dist/registry/docs/order-detail-block.md +37 -0
- package/dist/registry/docs/orders-list-block.md +40 -0
- package/dist/registry/docs/payment-success-block.md +32 -0
- package/dist/registry/docs/post-card.md +37 -0
- package/dist/registry/docs/post-detail-block.md +37 -0
- package/dist/registry/docs/pricing-card.md +37 -0
- package/dist/registry/docs/pricing-section.md +39 -0
- package/dist/registry/docs/privacy-page.md +32 -0
- package/dist/registry/docs/product-card-detailed.md +42 -0
- package/dist/registry/docs/product-card-hover.md +35 -0
- package/dist/registry/docs/product-card.md +37 -0
- package/dist/registry/docs/product-detail-block.md +37 -0
- package/dist/registry/docs/product-detail-section.md +45 -0
- package/dist/registry/docs/products-page.md +39 -0
- package/dist/registry/docs/related-posts-block.md +38 -0
- package/dist/registry/docs/related-products-block.md +38 -0
- package/dist/registry/docs/service-card.md +34 -0
- package/dist/registry/docs/skill-card.md +33 -0
- package/dist/registry/docs/terms-page.md +32 -0
- package/dist/registry/docs/testimonials-carousel.md +40 -0
- package/dist/registry/docs/testimonials-grid.md +39 -0
- package/dist/registry/ecommerce-core.json +95 -0
- package/dist/registry/empty-page.json +45 -0
- package/dist/registry/faq-categorized.json +42 -0
- package/dist/registry/faq-simple.json +42 -0
- package/dist/registry/favorites-blog-block.json +43 -0
- package/dist/registry/favorites-ecommerce-block.json +43 -0
- package/dist/registry/feature-section.json +40 -0
- package/dist/registry/featured-products.json +43 -0
- package/dist/registry/footer-detailed.json +43 -0
- package/dist/registry/footer-minimal.json +40 -0
- package/dist/registry/footer.json +40 -0
- package/dist/registry/google-map.json +31 -0
- package/dist/registry/header-centered-pill.json +45 -0
- package/dist/registry/header-ecommerce.json +42 -0
- package/dist/registry/header-mega.json +47 -0
- package/dist/registry/header-minimal.json +45 -0
- package/dist/registry/header-simple.json +43 -0
- package/dist/registry/hero-cta.json +42 -0
- package/dist/registry/hero-gradient.json +40 -0
- package/dist/registry/hero-grid.json +42 -0
- package/dist/registry/hero-profile.json +62 -0
- package/dist/registry/hero.json +40 -0
- package/dist/registry/index.json +70 -0
- package/dist/registry/login-page-split.json +47 -0
- package/dist/registry/login-page.json +49 -0
- package/dist/registry/newsletter-section.json +44 -0
- package/dist/registry/order-card-compact.json +42 -0
- package/dist/registry/order-detail-block.json +42 -0
- package/dist/registry/orders-list-block.json +45 -0
- package/dist/registry/payment-success-block.json +40 -0
- package/dist/registry/post-card.json +42 -0
- package/dist/registry/post-detail-block.json +42 -0
- package/dist/registry/pricing-card.json +40 -0
- package/dist/registry/pricing-section.json +43 -0
- package/dist/registry/privacy-page.json +45 -0
- package/dist/registry/product-card-detailed.json +45 -0
- package/dist/registry/product-card-hover.json +40 -0
- package/dist/registry/product-card.json +42 -0
- package/dist/registry/product-detail-block.json +42 -0
- package/dist/registry/product-detail-section.json +46 -0
- package/dist/registry/products-page.json +48 -0
- package/dist/registry/related-posts-block.json +43 -0
- package/dist/registry/related-products-block.json +43 -0
- package/dist/registry/service-card.json +28 -0
- package/dist/registry/skill-card.json +28 -0
- package/dist/registry/terms-page.json +45 -0
- package/dist/registry/testimonials-carousel.json +44 -0
- package/dist/registry/testimonials-grid.json +43 -0
- package/package.json +52 -0
- package/template/.env +6 -0
- package/template/.prettierignore +3 -0
- package/template/.prettierrc +1 -0
- package/template/README.md +73 -0
- package/template/bun.lock +1007 -0
- package/template/components.json +22 -0
- package/template/eslint.config.js +32 -0
- package/template/index.html +285 -0
- package/template/package.json +92 -0
- package/template/promake.json +6 -0
- package/template/public/_redirects +1 -0
- package/template/public/data/database.db +0 -0
- package/template/public/favicon.svg +1 -0
- package/template/public/images/placeholder.png +0 -0
- package/template/public/robots.txt +14 -0
- package/template/scripts/init-db.ts +131 -0
- package/template/src/App.tsx +33 -0
- package/template/src/components/Footer.tsx +100 -0
- package/template/src/components/Header.tsx +79 -0
- package/template/src/components/Hero.tsx +69 -0
- package/template/src/components/LanguageSwitcher.tsx +47 -0
- package/template/src/components/Layout.tsx +25 -0
- package/template/src/components/Logo.tsx +64 -0
- package/template/src/components/ThemeSwitcher.tsx +58 -0
- package/template/src/components/ui/accordion.tsx +64 -0
- package/template/src/components/ui/alert-dialog.tsx +155 -0
- package/template/src/components/ui/alert.tsx +66 -0
- package/template/src/components/ui/aspect-ratio.tsx +11 -0
- package/template/src/components/ui/avatar.tsx +51 -0
- package/template/src/components/ui/badge.tsx +46 -0
- package/template/src/components/ui/breadcrumb.tsx +109 -0
- package/template/src/components/ui/button-group.tsx +83 -0
- package/template/src/components/ui/button.tsx +62 -0
- package/template/src/components/ui/calendar.tsx +220 -0
- package/template/src/components/ui/card.tsx +92 -0
- package/template/src/components/ui/carousel.tsx +239 -0
- package/template/src/components/ui/chart.tsx +357 -0
- package/template/src/components/ui/checkbox.tsx +32 -0
- package/template/src/components/ui/collapsible.tsx +31 -0
- package/template/src/components/ui/command.tsx +182 -0
- package/template/src/components/ui/context-menu.tsx +252 -0
- package/template/src/components/ui/dialog.tsx +141 -0
- package/template/src/components/ui/drawer.tsx +135 -0
- package/template/src/components/ui/dropdown-menu.tsx +255 -0
- package/template/src/components/ui/empty.tsx +104 -0
- package/template/src/components/ui/field.tsx +246 -0
- package/template/src/components/ui/form.tsx +168 -0
- package/template/src/components/ui/hover-card.tsx +44 -0
- package/template/src/components/ui/input-group.tsx +170 -0
- package/template/src/components/ui/input-otp.tsx +75 -0
- package/template/src/components/ui/input.tsx +21 -0
- package/template/src/components/ui/item.tsx +193 -0
- package/template/src/components/ui/kbd.tsx +28 -0
- package/template/src/components/ui/label.tsx +24 -0
- package/template/src/components/ui/menubar.tsx +274 -0
- package/template/src/components/ui/navigation-menu.tsx +168 -0
- package/template/src/components/ui/pagination.tsx +127 -0
- package/template/src/components/ui/popover.tsx +48 -0
- package/template/src/components/ui/progress.tsx +29 -0
- package/template/src/components/ui/radio-group.tsx +45 -0
- package/template/src/components/ui/resizable.tsx +54 -0
- package/template/src/components/ui/scroll-area.tsx +58 -0
- package/template/src/components/ui/select.tsx +188 -0
- package/template/src/components/ui/separator.tsx +28 -0
- package/template/src/components/ui/sheet.tsx +137 -0
- package/template/src/components/ui/sidebar.tsx +726 -0
- package/template/src/components/ui/skeleton.tsx +13 -0
- package/template/src/components/ui/slider.tsx +63 -0
- package/template/src/components/ui/sonner.tsx +38 -0
- package/template/src/components/ui/spinner.tsx +16 -0
- package/template/src/components/ui/switch.tsx +31 -0
- package/template/src/components/ui/table.tsx +114 -0
- package/template/src/components/ui/tabs.tsx +66 -0
- package/template/src/components/ui/textarea.tsx +18 -0
- package/template/src/components/ui/toggle-group.tsx +81 -0
- package/template/src/components/ui/toggle.tsx +45 -0
- package/template/src/components/ui/tooltip.tsx +61 -0
- package/template/src/constants/constants.json +58 -0
- package/template/src/hooks/use-is-mobile.ts +21 -0
- package/template/src/hooks/use-page-title.ts +49 -0
- package/template/src/hooks/use-theme.ts +57 -0
- package/template/src/index.css +128 -0
- package/template/src/lang/en/about.json +4 -0
- package/template/src/lang/en/contact.json +39 -0
- package/template/src/lang/en/cookies.json +4 -0
- package/template/src/lang/en/footer.json +12 -0
- package/template/src/lang/en/forgotPassword.json +37 -0
- package/template/src/lang/en/header.json +10 -0
- package/template/src/lang/en/hero.json +8 -0
- package/template/src/lang/en/index.json +30 -0
- package/template/src/lang/en/login.json +18 -0
- package/template/src/lang/en/notfound.json +7 -0
- package/template/src/lang/en/privacy.json +4 -0
- package/template/src/lang/en/register.json +25 -0
- package/template/src/lang/en/terms.json +4 -0
- package/template/src/lang/index.ts +86 -0
- package/template/src/lang/tr/about.json +4 -0
- package/template/src/lang/tr/contact.json +39 -0
- package/template/src/lang/tr/cookies.json +4 -0
- package/template/src/lang/tr/footer.json +12 -0
- package/template/src/lang/tr/forgotPassword.json +37 -0
- package/template/src/lang/tr/header.json +10 -0
- package/template/src/lang/tr/hero.json +8 -0
- package/template/src/lang/tr/index.json +30 -0
- package/template/src/lang/tr/login.json +18 -0
- package/template/src/lang/tr/notfound.json +7 -0
- package/template/src/lang/tr/privacy.json +4 -0
- package/template/src/lang/tr/register.json +25 -0
- package/template/src/lang/tr/terms.json +4 -0
- package/template/src/lib/api.ts +237 -0
- package/template/src/lib/storage.ts +109 -0
- package/template/src/lib/utils.ts +15 -0
- package/template/src/main.tsx +13 -0
- package/template/src/modules/api/USAGE.md +515 -0
- package/template/src/modules/api/customer-client.ts +20 -0
- package/template/src/modules/api/get-error-message.ts +18 -0
- package/template/src/modules/api/validation/en.json +29 -0
- package/template/src/modules/api/validation/tr.json +29 -0
- package/template/src/modules/auth/USAGE.md +248 -0
- package/template/src/modules/auth/auth-header-menu.tsx +123 -0
- package/template/src/modules/auth/auth-store.ts +57 -0
- package/template/src/modules/auth/forgot-password-page.tsx +371 -0
- package/template/src/modules/auth/login-page.tsx +183 -0
- package/template/src/modules/auth/register-page.tsx +252 -0
- package/template/src/modules/auth/use-auth.ts +273 -0
- package/template/src/modules/db/adapters/IDataAdapter.ts +26 -0
- package/template/src/modules/db/adapters/SqliteAdapter.ts +364 -0
- package/template/src/modules/db/adapters/index.ts +2 -0
- package/template/src/modules/db/config.ts +59 -0
- package/template/src/modules/db/core/DataManager.ts +125 -0
- package/template/src/modules/db/core/types.ts +101 -0
- package/template/src/modules/db/index.ts +42 -0
- package/template/src/modules/db/react/QueryProvider.tsx +16 -0
- package/template/src/modules/db/react/index.ts +23 -0
- package/template/src/modules/db/react/queryClient.ts +64 -0
- package/template/src/modules/db/react/useRepository.ts +400 -0
- package/template/src/modules/db/utils/parsers.ts +96 -0
- package/template/src/pages/Index.tsx +108 -0
- package/template/src/pages/NotFound.tsx +35 -0
- package/template/src/router.tsx +14 -0
- package/template/src/types/index.ts +0 -0
- package/template/src/vite-env.d.ts +1 -0
- package/template/tsconfig.app.json +32 -0
- package/template/tsconfig.json +17 -0
- package/template/tsconfig.node.json +26 -0
- package/template/vite.config.ts +74 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "contact-page-split",
|
|
3
|
+
"type": "registry:page",
|
|
4
|
+
"title": "Contact Page Split",
|
|
5
|
+
"description": "50/50 split layout contact page with colored info panel on left and form on right. Left side features primary color background with contact details (email, phone, address, hours). Right side has clean form with name, email, phone, and message fields.",
|
|
6
|
+
"registryDependencies": [
|
|
7
|
+
"input",
|
|
8
|
+
"textarea",
|
|
9
|
+
"label"
|
|
10
|
+
],
|
|
11
|
+
"usage": "import { ContactPageSplit } from '@/modules/contact-page-split';\n\n<ContactPageSplit />\n\n- 50/50 split layout\n- Primary color info panel\n- Contact details with icons\n- Clean form on white background",
|
|
12
|
+
"route": {
|
|
13
|
+
"path": "/contact",
|
|
14
|
+
"componentName": "ContactPageSplit"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
{
|
|
18
|
+
"path": "contact-page-split/index.ts",
|
|
19
|
+
"type": "registry:index",
|
|
20
|
+
"target": "$modules$/contact-page-split/index.ts",
|
|
21
|
+
"content": "export * from './contact-page-split';\r\nexport { ContactPageSplit as default } from './contact-page-split';\r\n"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "contact-page-split/contact-page-split.tsx",
|
|
25
|
+
"type": "registry:component",
|
|
26
|
+
"target": "$modules$/contact-page-split/contact-page-split.tsx",
|
|
27
|
+
"content": "import React, { useState } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { Mail, Phone, MapPin, Clock } from \"lucide-react\";\r\nimport { Layout } from \"@/components/Layout\";\r\nimport { useApiService } from \"@/lib/api\";\r\nimport { Button } from \"@/components/ui/button\";\r\nimport { Input } from \"@/components/ui/input\";\r\nimport { Textarea } from \"@/components/ui/textarea\";\r\nimport { Label } from \"@/components/ui/label\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport constants from \"@/constants/constants.json\";\r\n\r\ninterface ContactPageSplitProps {\r\n className?: string;\r\n}\r\n\r\nexport function ContactPageSplit({ className }: ContactPageSplitProps) {\r\n const { t } = useTranslation(\"contact-page-split\");\r\n const apiService = useApiService();\r\n\r\n const [formData, setFormData] = useState({\r\n name: \"\",\r\n email: \"\",\r\n phone: \"\",\r\n message: \"\",\r\n });\r\n const [isSubmitting, setIsSubmitting] = useState(false);\r\n const [submitStatus, setSubmitStatus] = useState<\"idle\" | \"success\" | \"error\">(\"idle\");\r\n\r\n const handleSubmit = async (e: React.FormEvent) => {\r\n e.preventDefault();\r\n setIsSubmitting(true);\r\n setSubmitStatus(\"idle\");\r\n\r\n try {\r\n await apiService.submitForm(\r\n formData,\r\n {\r\n email_subject1: \"Thank you for contacting us\",\r\n email_subject2: \"New Contact Form Submission\",\r\n fields: [\r\n { name: \"name\", required: true },\r\n { name: \"email\", required: true },\r\n { name: \"phone\", required: false },\r\n { name: \"message\", required: true },\r\n ],\r\n },\r\n constants.site.defaultLanguage\r\n );\r\n\r\n setSubmitStatus(\"success\");\r\n setFormData({ name: \"\", email: \"\", phone: \"\", message: \"\" });\r\n setTimeout(() => setSubmitStatus(\"idle\"), 5000);\r\n } catch {\r\n setSubmitStatus(\"error\");\r\n setTimeout(() => setSubmitStatus(\"idle\"), 5000);\r\n } finally {\r\n setIsSubmitting(false);\r\n }\r\n };\r\n\r\n const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\r\n setFormData((prev) => ({ ...prev, [e.target.name]: e.target.value }));\r\n };\r\n\r\n return (\r\n <Layout>\r\n <div className={cn(\"min-h-screen\", className)}>\r\n <div className=\"grid lg:grid-cols-2 min-h-screen\">\r\n {/* Left Side - Info & Image */}\r\n <div className=\"relative bg-primary text-primary-foreground p-8 lg:p-12 flex flex-col justify-center\">\r\n {/* Background Pattern */}\r\n <div className=\"absolute inset-0 bg-[linear-gradient(to_right,rgba(255,255,255,0.1)_1px,transparent_1px),linear-gradient(to_bottom,rgba(255,255,255,0.1)_1px,transparent_1px)] bg-[size:4rem_4rem]\" />\r\n\r\n <div className=\"relative z-10 max-w-lg\">\r\n <h1 className=\"text-3xl lg:text-4xl font-bold mb-4\">\r\n {t(\"title\", \"Let's Start a Conversation\")}\r\n </h1>\r\n <p className=\"text-primary-foreground/80 mb-8\">\r\n {t(\"subtitle\", \"Have a project in mind? We'd love to hear about it. Get in touch and let's create something amazing together.\")}\r\n </p>\r\n\r\n <div className=\"space-y-6\">\r\n <div className=\"flex items-start gap-4\">\r\n <div className=\"w-10 h-10 rounded-full bg-primary-foreground/10 flex items-center justify-center flex-shrink-0\">\r\n <Mail className=\"h-5 w-5\" />\r\n </div>\r\n <div>\r\n <p className=\"font-semibold\">{t(\"emailLabel\", \"Email\")}</p>\r\n <p className=\"text-primary-foreground/70\">{constants.email || \"hello@example.com\"}</p>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex items-start gap-4\">\r\n <div className=\"w-10 h-10 rounded-full bg-primary-foreground/10 flex items-center justify-center flex-shrink-0\">\r\n <Phone className=\"h-5 w-5\" />\r\n </div>\r\n <div>\r\n <p className=\"font-semibold\">{t(\"phoneLabel\", \"Phone\")}</p>\r\n <p className=\"text-primary-foreground/70\">{constants.phone || \"+1 234 567 890\"}</p>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex items-start gap-4\">\r\n <div className=\"w-10 h-10 rounded-full bg-primary-foreground/10 flex items-center justify-center flex-shrink-0\">\r\n <MapPin className=\"h-5 w-5\" />\r\n </div>\r\n <div>\r\n <p className=\"font-semibold\">{t(\"addressLabel\", \"Address\")}</p>\r\n <p className=\"text-primary-foreground/70\">\r\n {constants.address?.line1 || \"123 Main Street\"}<br />\r\n {constants.address?.city || \"New York\"}, {constants.address?.country || \"USA\"}\r\n </p>\r\n </div>\r\n </div>\r\n\r\n <div className=\"flex items-start gap-4\">\r\n <div className=\"w-10 h-10 rounded-full bg-primary-foreground/10 flex items-center justify-center flex-shrink-0\">\r\n <Clock className=\"h-5 w-5\" />\r\n </div>\r\n <div>\r\n <p className=\"font-semibold\">{t(\"hoursLabel\", \"Business Hours\")}</p>\r\n <p className=\"text-primary-foreground/70\">{t(\"hours\", \"Mon - Fri: 9:00 AM - 6:00 PM\")}</p>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n {/* Right Side - Form */}\r\n <div className=\"p-8 lg:p-12 flex items-center justify-center bg-background\">\r\n <div className=\"w-full max-w-md\">\r\n <h2 className=\"text-2xl font-bold mb-2\">{t(\"formTitle\", \"Send us a message\")}</h2>\r\n <p className=\"text-muted-foreground mb-8\">\r\n {t(\"formSubtitle\", \"Fill out the form below and we'll get back to you as soon as possible.\")}\r\n </p>\r\n\r\n <form onSubmit={handleSubmit} className=\"space-y-5\">\r\n <div>\r\n <Label htmlFor=\"name\">{t(\"nameLabel\", \"Full Name\")} *</Label>\r\n <Input\r\n id=\"name\"\r\n name=\"name\"\r\n value={formData.name}\r\n onChange={handleChange}\r\n placeholder={t(\"namePlaceholder\", \"John Doe\")}\r\n required\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <Label htmlFor=\"email\">{t(\"emailInputLabel\", \"Email\")} *</Label>\r\n <Input\r\n id=\"email\"\r\n name=\"email\"\r\n type=\"email\"\r\n value={formData.email}\r\n onChange={handleChange}\r\n placeholder={t(\"emailPlaceholder\", \"john@example.com\")}\r\n required\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <Label htmlFor=\"phone\">{t(\"phoneInputLabel\", \"Phone\")}</Label>\r\n <Input\r\n id=\"phone\"\r\n name=\"phone\"\r\n type=\"tel\"\r\n value={formData.phone}\r\n onChange={handleChange}\r\n placeholder={t(\"phonePlaceholder\", \"+1 234 567 890\")}\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n\r\n <div>\r\n <Label htmlFor=\"message\">{t(\"messageLabel\", \"Message\")} *</Label>\r\n <Textarea\r\n id=\"message\"\r\n name=\"message\"\r\n value={formData.message}\r\n onChange={handleChange}\r\n placeholder={t(\"messagePlaceholder\", \"Tell us about your project...\")}\r\n required\r\n rows={5}\r\n className=\"mt-1 resize-none\"\r\n />\r\n </div>\r\n\r\n {submitStatus === \"success\" && (\r\n <div className=\"p-4 bg-green-500/10 border border-green-500/30 rounded-lg\">\r\n <p className=\"text-green-600 dark:text-green-400 text-sm font-medium\">\r\n {t(\"success\", \"Message sent! We'll be in touch soon.\")}\r\n </p>\r\n </div>\r\n )}\r\n\r\n {submitStatus === \"error\" && (\r\n <div className=\"p-4 bg-destructive/10 border border-destructive/30 rounded-lg\">\r\n <p className=\"text-destructive text-sm font-medium\">\r\n {t(\"error\", \"Something went wrong. Please try again.\")}\r\n </p>\r\n </div>\r\n )}\r\n\r\n <Button type=\"submit\" size=\"lg\" className=\"w-full\" disabled={isSubmitting}>\r\n {isSubmitting ? t(\"sending\", \"Sending...\") : t(\"submit\", \"Send Message\")}\r\n </Button>\r\n </form>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </Layout>\r\n );\r\n}\r\n"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"path": "contact-page-split/lang/en.json",
|
|
31
|
+
"type": "registry:lang",
|
|
32
|
+
"target": "$modules$/contact-page-split/lang/en.json",
|
|
33
|
+
"content": "{\r\n \"title\": \"Let's Start a Conversation\",\r\n \"subtitle\": \"AI will customize this subtitle based on your contact page purpose. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\",\r\n \"emailLabel\": \"Email\",\r\n \"phoneLabel\": \"Phone\",\r\n \"addressLabel\": \"Address\",\r\n \"hoursLabel\": \"Hours\",\r\n \"hours\": \"Mon - Fri: 9:00 AM - 6:00 PM\",\r\n \"formTitle\": \"Send us a message\",\r\n \"formSubtitle\": \"Fill out the form below and we'll get back to you as soon as possible.\",\r\n \"nameLabel\": \"Full Name\",\r\n \"namePlaceholder\": \"John Doe\",\r\n \"emailInputLabel\": \"Email\",\r\n \"emailPlaceholder\": \"john@example.com\",\r\n \"phoneInputLabel\": \"Phone\",\r\n \"phonePlaceholder\": \"+1 234 567 890\",\r\n \"messageLabel\": \"Message\",\r\n \"messagePlaceholder\": \"Tell us about your project...\",\r\n \"submit\": \"Send Message\",\r\n \"sending\": \"Sending...\",\r\n \"success\": \"Message sent! We'll be in touch soon.\",\r\n \"error\": \"Something went wrong. Please try again.\"\r\n}\r\n"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"path": "contact-page-split/lang/tr.json",
|
|
37
|
+
"type": "registry:lang",
|
|
38
|
+
"target": "$modules$/contact-page-split/lang/tr.json",
|
|
39
|
+
"content": "{\r\n \"title\": \"Bir Sohbet Başlatalım\",\r\n \"subtitle\": \"AI bu alt başlığı iletişim sayfası amacınıza göre özelleştirecektir. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\",\r\n \"emailLabel\": \"E-posta\",\r\n \"phoneLabel\": \"Telefon\",\r\n \"addressLabel\": \"Adres\",\r\n \"hoursLabel\": \"Çalışma Saatleri\",\r\n \"hours\": \"Pazartesi - Cuma: 09:00 - 18:00\",\r\n \"formTitle\": \"Bize mesaj gönderin\",\r\n \"formSubtitle\": \"Aşağıdaki formu doldurun, en kısa sürede size döneceğiz.\",\r\n \"nameLabel\": \"Ad Soyad\",\r\n \"namePlaceholder\": \"Ahmet Yılmaz\",\r\n \"emailInputLabel\": \"E-posta\",\r\n \"emailPlaceholder\": \"ahmet@ornek.com\",\r\n \"phoneInputLabel\": \"Telefon\",\r\n \"phonePlaceholder\": \"+90 532 123 4567\",\r\n \"messageLabel\": \"Mesaj\",\r\n \"messagePlaceholder\": \"Projeniz hakkında bize bilgi verin...\",\r\n \"submit\": \"Mesaj Gönder\",\r\n \"sending\": \"Gönderiliyor...\",\r\n \"success\": \"Mesaj gönderildi! En kısa sürede iletişime geçeceğiz.\",\r\n \"error\": \"Bir şeyler yanlış gitti. Lütfen tekrar deneyin.\"\r\n}\r\n"
|
|
40
|
+
}
|
|
41
|
+
],
|
|
42
|
+
"exports": {
|
|
43
|
+
"types": [],
|
|
44
|
+
"variables": [
|
|
45
|
+
"ContactPageSplit",
|
|
46
|
+
"default"
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "contact-page",
|
|
3
|
+
"type": "registry:page",
|
|
4
|
+
"title": "Contact Page",
|
|
5
|
+
"description": "Contact page with two-column layout: contact form (name, email, subject, message) on left, and contact information (address, phone, email, business hours, social links) on right. Includes embedded Google Map, form validation, and success/error toast notifications. Mobile-responsive with stacked layout.",
|
|
6
|
+
"registryDependencies": [],
|
|
7
|
+
"usage": "import { ContactPage } from '@/modules/contact-page';\n\n<Route path=\"/contact\" element={<ContactPage />} />\n\n• Two-column: form left, info right\n• Form: name, email, subject, message\n• Info: address, phone, email, hours, map\n• Toast notifications on submit",
|
|
8
|
+
"route": {
|
|
9
|
+
"path": "/contact",
|
|
10
|
+
"componentName": "ContactPage"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
{
|
|
14
|
+
"path": "contact-page/index.ts",
|
|
15
|
+
"type": "registry:index",
|
|
16
|
+
"target": "$modules$/contact-page/index.ts",
|
|
17
|
+
"content": "export * from './contact-page';\r\nexport { ContactPage as default } from './contact-page';\r\n"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"path": "contact-page/contact-page.tsx",
|
|
21
|
+
"type": "registry:page",
|
|
22
|
+
"target": "$modules$/contact-page/contact-page.tsx",
|
|
23
|
+
"content": "import React, { useState, useMemo } from \"react\";\nimport { usePageTitle } from \"@/hooks/use-page-title\";\nimport { useTranslation } from \"react-i18next\";\nimport { Layout } from \"@/components/Layout\";\nimport { useApiService } from \"@/lib/api\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { Textarea } from \"@/components/ui/textarea\";\nimport { Label } from \"@/components/ui/label\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"@/components/ui/card\";\nimport {\n Mail,\n Phone,\n MapPin,\n MessageSquare,\n Facebook,\n Twitter,\n Instagram,\n Linkedin,\n} from \"lucide-react\";\nimport constants from \"@/constants/constants.json\";\nimport { FadeIn, SlideInLeft, SlideInRight } from \"@/modules/animations\";\n\nconst socialIcons: Record<string, React.ElementType> = {\n facebook: Facebook,\n twitter: Twitter,\n instagram: Instagram,\n linkedin: Linkedin,\n};\n\nexport function ContactPage() {\n const { t } = useTranslation(\"contact-page\");\n usePageTitle({ title: t(\"title\") });\n\n const apiService = useApiService();\n\n const socialLinks = useMemo(() => {\n const socialMedia = constants.socialMedia as\n | Record<string, string>\n | undefined;\n if (!socialMedia) return [];\n return Object.entries(socialMedia)\n .filter(([platform, url]) => url && socialIcons[platform])\n .map(([platform, url]) => ({\n platform,\n url,\n Icon: socialIcons[platform],\n }));\n }, []);\n\n const [formData, setFormData] = useState({\n name: \"\",\n email: \"\",\n phone: \"\",\n subject: \"\",\n message: \"\",\n });\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitStatus, setSubmitStatus] = useState<\n \"idle\" | \"success\" | \"error\"\n >(\"idle\");\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setIsSubmitting(true);\n setSubmitStatus(\"idle\");\n\n try {\n const currentLanguage = constants.site.defaultLanguage;\n\n await apiService.submitForm(\n formData,\n {\n email_subject1: \"Thank you for contacting us\",\n email_subject2: \"New Contact Form Submission\",\n fields: [\n { name: \"name\", required: true },\n { name: \"email\", required: true },\n { name: \"phone\", required: false },\n { name: \"subject\", required: false },\n { name: \"message\", required: true },\n ],\n },\n currentLanguage\n );\n\n setSubmitStatus(\"success\");\n setFormData({\n name: \"\",\n email: \"\",\n phone: \"\",\n subject: \"\",\n message: \"\",\n });\n\n setTimeout(() => {\n setSubmitStatus(\"idle\");\n }, 5000);\n } catch (error: unknown) {\n console.error(\"Form submission failed:\", error);\n setSubmitStatus(\"error\");\n\n setTimeout(() => {\n setSubmitStatus(\"idle\");\n }, 5000);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const handleChange = (\n e: React.ChangeEvent<\n HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement\n >\n ) => {\n setFormData((prev) => ({\n ...prev,\n [e.target.name]: e.target.value,\n }));\n };\n\n return (\n <Layout>\n <div className=\"min-h-screen bg-muted/30 py-12\">\n <div className=\"container mx-auto px-4 max-w-6xl\">\n {/* Hero Section */}\n <FadeIn className=\"text-center mb-12\">\n <h1 className=\"text-4xl font-bold text-foreground mb-4\">\n {t(\"title\")}\n </h1>\n <div className=\"w-16 h-1 bg-primary mx-auto mb-6\"></div>\n <p className=\"text-lg text-muted-foreground max-w-3xl mx-auto\">\n {t(\"description\")}\n </p>\n </FadeIn>\n\n <div className=\"grid lg:grid-cols-3 gap-8\">\n {/* Contact Information */}\n <SlideInLeft className=\"lg:col-span-1 space-y-6\">\n {/* Company Info */}\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <MessageSquare className=\"w-5 h-5 text-primary\" />\n {t(\"getInTouch\")}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div className=\"flex items-start gap-3\">\n <Mail className=\"w-5 h-5 text-primary mt-1\" />\n <div>\n <p className=\"font-medium text-foreground\">\n {t(\"email\")}\n </p>\n <p className=\"text-muted-foreground\">{constants.email}</p>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {t(\"emailResponse\")}\n </p>\n </div>\n </div>\n\n <div className=\"flex items-start gap-3\">\n <Phone className=\"w-5 h-5 text-primary mt-1\" />\n <div>\n <p className=\"font-medium text-foreground\">\n {t(\"phone\")}\n </p>\n <p className=\"text-muted-foreground\">{constants.phone}</p>\n </div>\n </div>\n\n <div className=\"flex items-start gap-3\">\n <MapPin className=\"w-5 h-5 text-primary mt-1\" />\n <div>\n <p className=\"font-medium text-foreground\">\n {t(\"address\")}\n </p>\n <div className=\"text-muted-foreground\">\n <p>{constants.address.line1}</p>\n {constants.address.line2 && (\n <p>{constants.address.line2}</p>\n )}\n <p>\n {constants.address.city}, {constants.address.state}{\" \"}\n {constants.address.postalCode}\n </p>\n {constants.address.country && (\n <p>{constants.address.country}</p>\n )}\n </div>\n </div>\n </div>\n\n {/* Social Media Links */}\n {socialLinks.length > 0 && (\n <div className=\"pt-4 border-t\">\n <p className=\"font-medium text-foreground mb-3\">\n {t(\"followUs\")}\n </p>\n <div className=\"flex gap-2\">\n {socialLinks.map(({ platform, url, Icon }) => (\n <a\n key={platform}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"h-10 w-10 flex items-center justify-center rounded-md border text-muted-foreground hover:text-primary hover:border-primary transition-colors\"\n >\n <Icon className=\"h-5 w-5\" />\n </a>\n ))}\n </div>\n </div>\n )}\n </CardContent>\n </Card>\n\n {/* Support Info */}\n <Card>\n <CardHeader>\n <CardTitle>{t(\"needSupport\")}</CardTitle>\n </CardHeader>\n <CardContent>\n <p className=\"text-muted-foreground mb-4\">\n {t(\"supportDescription\")}\n </p>\n <div className=\"space-y-2\">\n <p className=\"font-medium text-foreground\">\n {t(\"supportEmail\")}\n </p>\n <p className=\"text-muted-foreground\">{constants.email}</p>\n </div>\n </CardContent>\n </Card>\n </SlideInLeft>\n\n {/* Contact Form */}\n <SlideInRight className=\"lg:col-span-2\">\n <Card>\n <CardHeader>\n <CardTitle>{t(\"sendMessage\")}</CardTitle>\n </CardHeader>\n <CardContent>\n <form onSubmit={handleSubmit} className=\"space-y-6\">\n {/* Full Name */}\n <div>\n <Label htmlFor=\"name\">{t(\"fullName\")} *</Label>\n <Input\n id=\"name\"\n name=\"name\"\n type=\"text\"\n value={formData.name}\n onChange={handleChange}\n placeholder={t(\"fullNamePlaceholder\")}\n required\n className=\"mt-1\"\n />\n </div>\n\n {/* Email */}\n <div>\n <Label htmlFor=\"email\">{t(\"emailAddress\")} *</Label>\n <Input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n value={formData.email}\n onChange={handleChange}\n placeholder={t(\"emailPlaceholder\")}\n required\n className=\"mt-1\"\n />\n </div>\n\n {/* Phone */}\n <div>\n <Label htmlFor=\"phone\">{t(\"phoneNumber\")}</Label>\n <Input\n id=\"phone\"\n name=\"phone\"\n type=\"tel\"\n value={formData.phone}\n onChange={handleChange}\n placeholder={t(\"phonePlaceholder\")}\n className=\"mt-1\"\n />\n </div>\n\n {/* Subject */}\n <div>\n <Label htmlFor=\"subject\">{t(\"subject\")}</Label>\n <Input\n id=\"subject\"\n name=\"subject\"\n type=\"text\"\n value={formData.subject}\n onChange={handleChange}\n placeholder={t(\"subjectPlaceholder\")}\n className=\"mt-1\"\n />\n </div>\n\n {/* Message */}\n <div>\n <Label htmlFor=\"message\">{t(\"message\")} *</Label>\n <Textarea\n id=\"message\"\n name=\"message\"\n value={formData.message}\n onChange={handleChange}\n placeholder={t(\"messagePlaceholder\")}\n required\n rows={6}\n className=\"mt-1 resize-none\"\n />\n </div>\n\n {submitStatus === \"success\" && (\n <div className=\"p-4 bg-green-500/10 dark:bg-green-500/20 border border-green-500/30 rounded-lg\">\n <p className=\"text-green-600 dark:text-green-400 text-sm font-medium\">\n {t(\"success\")}\n </p>\n </div>\n )}\n\n {submitStatus === \"error\" && (\n <div className=\"p-4 bg-destructive/10 border border-destructive/30 rounded-lg\">\n <p className=\"text-destructive text-sm font-medium\">\n {t(\"error\")}\n </p>\n </div>\n )}\n\n <Button\n type=\"submit\"\n size=\"lg\"\n className=\"w-full\"\n disabled={isSubmitting}\n >\n {isSubmitting ? (\n <>\n <div className=\"w-4 h-4 border-2 border-primary-foreground border-t-transparent rounded-full animate-spin mr-2\" />\n {t(\"sending\")}\n </>\n ) : (\n t(\"submit\")\n )}\n </Button>\n </form>\n </CardContent>\n </Card>\n </SlideInRight>\n </div>\n </div>\n </div>\n </Layout>\n );\n}\n"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"path": "contact-page/lang/en.json",
|
|
27
|
+
"type": "registry:lang",
|
|
28
|
+
"target": "$modules$/contact-page/lang/en.json",
|
|
29
|
+
"content": "{\r\n \"title\": \"Contact Us\",\r\n \"getInTouch\": \"Get in Touch\",\r\n \"emailUs\": \"Email Us\",\r\n \"callUs\": \"Call Us\",\r\n \"visitUs\": \"Visit Us\",\r\n \"businessHours\": \"Hours\",\r\n \"sendMessage\": \"Send us a Message\",\r\n \"formNotAvailable\": \"Form is not available at the moment.\",\r\n \"fullName\": \"Full Name\",\r\n \"emailAddress\": \"Email Address\",\r\n \"phoneNumber\": \"Phone Number\",\r\n \"subject\": \"Subject\",\r\n \"message\": \"Message\",\r\n \"submit\": \"Send Message\",\r\n \"sending\": \"Sending...\",\r\n \"success\": \"Thank you for your message! We will get back to you soon.\",\r\n \"error\": \"Failed to send message. Please try again later.\",\r\n \"description\": \"AI will customize this contact page description based on your site and support options. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\",\r\n \"email\": \"Email\",\r\n \"phone\": \"Phone\",\r\n \"address\": \"Address\",\r\n \"fullNamePlaceholder\": \"Your full name\",\r\n \"emailPlaceholder\": \"your@email.com\",\r\n \"phonePlaceholder\": \"+1 (555) 123-4567\",\r\n \"subjectPlaceholder\": \"What is this regarding?\",\r\n \"messagePlaceholder\": \"Tell us how we can help you...\",\r\n \"loading\": \"Loading contact information...\",\r\n \"emailResponse\": \"We typically respond within 24 hours\",\r\n \"needSupport\": \"Need Support?\",\r\n \"supportDescription\": \"For technical support or general inquiries, contact our dedicated support team:\",\r\n \"supportEmail\": \"Support Email\",\r\n \"monday_friday\": \"Monday - Friday\",\r\n \"saturday\": \"Saturday\",\r\n \"sunday\": \"Sunday\",\r\n \"closed\": \"Closed\",\r\n \"am\": \"AM\",\r\n \"pm\": \"PM\"\r\n}\r\n"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"path": "contact-page/lang/tr.json",
|
|
33
|
+
"type": "registry:lang",
|
|
34
|
+
"target": "$modules$/contact-page/lang/tr.json",
|
|
35
|
+
"content": "{\r\n \"title\": \"İletişim\",\r\n \"getInTouch\": \"Bize Ulaşın\",\r\n \"emailUs\": \"E-posta Gönderin\",\r\n \"callUs\": \"Bizi Arayın\",\r\n \"visitUs\": \"Bizi Ziyaret Edin\",\r\n \"businessHours\": \"Çalışma Saatleri\",\r\n \"sendMessage\": \"Bize Mesaj Gönderin\",\r\n \"formNotAvailable\": \"Form şu anda kullanılamıyor.\",\r\n \"fullName\": \"Ad Soyad\",\r\n \"emailAddress\": \"E-posta Adresi\",\r\n \"phoneNumber\": \"Telefon Numarası\",\r\n \"subject\": \"Konu\",\r\n \"message\": \"Mesaj\",\r\n \"submit\": \"Mesaj Gönder\",\r\n \"sending\": \"Gönderiliyor...\",\r\n \"success\": \"Mesajınız için teşekkürler! En kısa sürede size dönüş yapacağız.\",\r\n \"error\": \"Mesaj gönderilemedi. Lütfen tekrar deneyin.\",\r\n \"description\": \"AI bu iletişim sayfası açıklamasını sitenize ve destek seçeneklerinize göre özelleştirecektir. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\",\r\n \"email\": \"E-posta\",\r\n \"phone\": \"Telefon\",\r\n \"address\": \"Adres\",\r\n \"fullNamePlaceholder\": \"Adınız ve soyadınız\",\r\n \"emailPlaceholder\": \"eposta@adresiniz.com\",\r\n \"phonePlaceholder\": \"+90 5XX XXX XX XX\",\r\n \"subjectPlaceholder\": \"Konu nedir?\",\r\n \"messagePlaceholder\": \"Size nasıl yardımcı olabiliriz...\",\r\n \"loading\": \"İletişim bilgileri yükleniyor...\",\r\n \"emailResponse\": \"Genellikle 24 saat içinde yanıt veririz\",\r\n \"needSupport\": \"Desteğe İhtiyacınız mı Var?\",\r\n \"supportDescription\": \"Teknik destek veya sipariş sorularınız için özel destek ekibimizle iletişime geçin:\",\r\n \"supportEmail\": \"Destek E-postası\",\r\n \"monday_friday\": \"Pazartesi - Cuma\",\r\n \"saturday\": \"Cumartesi\",\r\n \"sunday\": \"Pazar\",\r\n \"closed\": \"Kapalı\",\r\n \"am\": \"\",\r\n \"pm\": \"\"\r\n}\r\n"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"exports": {
|
|
39
|
+
"types": [],
|
|
40
|
+
"variables": [
|
|
41
|
+
"ContactPage",
|
|
42
|
+
"default"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "content-section",
|
|
3
|
+
"type": "registry:component",
|
|
4
|
+
"title": "Content Section",
|
|
5
|
+
"description": "Two-column content section with large image and title/description grid. Features optional grayscale effect on image, CTA button, and responsive layout. Perfect for about pages and feature showcases.",
|
|
6
|
+
"registryDependencies": [],
|
|
7
|
+
"usage": "import { ContentSection } from '@/modules/content-section';\n\n<ContentSection\n image=\"/images/team.jpg\"\n title=\"Our Mission\"\n description=\"We are building the future...\"\n ctaText=\"Learn More\"\n ctaLink=\"/about\"\n grayscale\n/>",
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "content-section/index.ts",
|
|
11
|
+
"type": "registry:index",
|
|
12
|
+
"target": "$modules$/content-section/index.ts",
|
|
13
|
+
"content": "export * from './content-section';\r\n"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"path": "content-section/content-section.tsx",
|
|
17
|
+
"type": "registry:component",
|
|
18
|
+
"target": "$modules$/content-section/content-section.tsx",
|
|
19
|
+
"content": "import { Link } from \"react-router\";\r\nimport { ChevronRight } from \"lucide-react\";\r\nimport { Button } from \"@/components/ui/button\";\r\nimport { cn } from \"@/lib/utils\";\r\n\r\ninterface ContentSectionProps {\r\n image: string;\r\n imageAlt?: string;\r\n title: string;\r\n description: string;\r\n ctaText?: string;\r\n ctaLink?: string;\r\n grayscale?: boolean;\r\n className?: string;\r\n}\r\n\r\nexport function ContentSection({\r\n image,\r\n imageAlt,\r\n title,\r\n description,\r\n ctaText,\r\n ctaLink = \"#\",\r\n grayscale = false,\r\n className,\r\n}: ContentSectionProps) {\r\n\r\n return (\r\n <section className={cn(\"py-16 md:py-32\", className)}>\r\n <div className=\"mx-auto max-w-5xl space-y-8 px-6 md:space-y-12\">\r\n <img\r\n className={cn(\"rounded-lg w-full\", grayscale && \"grayscale\")}\r\n src={image}\r\n alt={imageAlt || title}\r\n loading=\"lazy\"\r\n />\r\n\r\n <div className=\"grid gap-6 md:grid-cols-2 md:gap-12\">\r\n <h2 className=\"text-3xl md:text-4xl font-medium leading-tight\">\r\n {title}\r\n </h2>\r\n <div className=\"space-y-6\">\r\n <p className=\"text-muted-foreground leading-relaxed\">\r\n {description}\r\n </p>\r\n\r\n {ctaText && (\r\n <Button asChild variant=\"secondary\" size=\"sm\" className=\"gap-1 pr-1.5\">\r\n <Link to={ctaLink}>\r\n <span>{ctaText}</span>\r\n <ChevronRight className=\"size-4\" />\r\n </Link>\r\n </Button>\r\n )}\r\n </div>\r\n </div>\r\n </div>\r\n </section>\r\n );\r\n}\r\n"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"path": "content-section/lang/en.json",
|
|
23
|
+
"type": "registry:lang",
|
|
24
|
+
"target": "$modules$/content-section/lang/en.json",
|
|
25
|
+
"content": "{\r\n \"learnMore\": \"Learn More\"\r\n}\r\n"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"path": "content-section/lang/tr.json",
|
|
29
|
+
"type": "registry:lang",
|
|
30
|
+
"target": "$modules$/content-section/lang/tr.json",
|
|
31
|
+
"content": "{\r\n \"learnMore\": \"Daha Fazla\"\r\n}\r\n"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"exports": {
|
|
35
|
+
"types": [],
|
|
36
|
+
"variables": [
|
|
37
|
+
"ContentSection"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cookies-page",
|
|
3
|
+
"type": "registry:page",
|
|
4
|
+
"title": "Cookie Policy Page",
|
|
5
|
+
"description": "Cookie policy page explaining cookie types (essential, analytics, marketing), purposes, third-party cookies, and user controls. Includes cookie table with name, purpose, and expiration. GDPR/ePrivacy compliant formatting with clear explanations for non-technical users.",
|
|
6
|
+
"registryDependencies": [],
|
|
7
|
+
"usage": "import { CookiesPage } from '@/modules/cookies-page';\n\n<Route path=\"/cookies\" element={<CookiesPage />} />\n\n• Cookie types: essential, analytics, marketing\n• Cookie table with name, purpose, expiration\n• GDPR/ePrivacy compliant",
|
|
8
|
+
"route": {
|
|
9
|
+
"path": "/cookies",
|
|
10
|
+
"componentName": "CookiesPage"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
{
|
|
14
|
+
"path": "cookies-page/index.ts",
|
|
15
|
+
"type": "registry:index",
|
|
16
|
+
"target": "$modules$/cookies-page/index.ts",
|
|
17
|
+
"content": "export * from './cookies-page';\r\nexport { CookiesPage as default } from './cookies-page';\r\n"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"path": "cookies-page/cookies-page.tsx",
|
|
21
|
+
"type": "registry:page",
|
|
22
|
+
"target": "$modules$/cookies-page/cookies-page.tsx",
|
|
23
|
+
"content": "import { useTranslation } from \"react-i18next\";\nimport { usePageTitle } from \"@/hooks/use-page-title\";\nimport { Layout } from \"@/components/Layout\";\nimport { Card, CardContent } from \"@/components/ui/card\";\nimport { Cookie, Settings, BarChart, Megaphone, Shield, Info } from \"lucide-react\";\nimport { FadeIn, StaggerContainer, StaggerItem } from \"@/modules/animations\";\n\nexport function CookiesPage() {\n const { t } = useTranslation(\"cookies-page\");\n usePageTitle({ title: t(\"title\") });\n\n const cookieTypes = [\n { icon: Shield, titleKey: \"essentialTitle\", descKey: \"essentialDesc\" },\n { icon: BarChart, titleKey: \"analyticsTitle\", descKey: \"analyticsDesc\" },\n { icon: Settings, titleKey: \"functionalTitle\", descKey: \"functionalDesc\" },\n { icon: Megaphone, titleKey: \"marketingTitle\", descKey: \"marketingDesc\" },\n ];\n\n return (\n <Layout>\n <div className=\"min-h-screen bg-muted/30 py-12\">\n <div className=\"container mx-auto px-4\">\n {/* Header */}\n <FadeIn className=\"text-center mb-12\">\n <div className=\"w-16 h-16 bg-primary/10 rounded-full flex items-center justify-center mx-auto mb-4\">\n <Cookie className=\"w-8 h-8 text-primary\" />\n </div>\n <h1 className=\"text-4xl font-bold text-foreground mb-4\">\n {t(\"title\")}\n </h1>\n <p className=\"text-muted-foreground\">\n {t(\"lastUpdated\")}: {t(\"updateDate\")}\n </p>\n </FadeIn>\n\n {/* Introduction */}\n <FadeIn delay={0.1} className=\"max-w-4xl mx-auto mb-12\">\n <Card>\n <CardContent className=\"p-8\">\n <p className=\"text-muted-foreground leading-relaxed\">\n {t(\"introduction\")}\n </p>\n </CardContent>\n </Card>\n </FadeIn>\n\n {/* What Are Cookies */}\n <FadeIn delay={0.2} className=\"max-w-4xl mx-auto mb-8\">\n <Card>\n <CardContent className=\"p-8\">\n <div className=\"flex items-start gap-4\">\n <div className=\"w-10 h-10 bg-primary/10 rounded-lg flex items-center justify-center flex-shrink-0\">\n <Info className=\"w-5 h-5 text-primary\" />\n </div>\n <div className=\"flex-1\">\n <h2 className=\"text-xl font-semibold mb-3\">{t(\"whatTitle\")}</h2>\n <p className=\"text-muted-foreground\">{t(\"whatContent\")}</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </FadeIn>\n\n {/* Cookie Types */}\n <div className=\"max-w-4xl mx-auto mb-8\">\n <FadeIn className=\"text-center mb-6\">\n <h2 className=\"text-2xl font-semibold\">{t(\"typesTitle\")}</h2>\n </FadeIn>\n <StaggerContainer className=\"grid md:grid-cols-2 gap-6\">\n {cookieTypes.map(({ icon: Icon, titleKey, descKey }) => (\n <StaggerItem key={titleKey}>\n <Card className=\"h-full\">\n <CardContent className=\"p-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"w-10 h-10 bg-primary/10 rounded-lg flex items-center justify-center flex-shrink-0\">\n <Icon className=\"w-5 h-5 text-primary\" />\n </div>\n <div className=\"flex-1\">\n <h3 className=\"font-semibold mb-2\">{t(titleKey)}</h3>\n <p className=\"text-sm text-muted-foreground\">{t(descKey)}</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </StaggerItem>\n ))}\n </StaggerContainer>\n </div>\n\n {/* Management */}\n <FadeIn className=\"max-w-4xl mx-auto mb-12\">\n <Card>\n <CardContent className=\"p-8\">\n <div className=\"flex items-start gap-4\">\n <div className=\"w-10 h-10 bg-primary/10 rounded-lg flex items-center justify-center flex-shrink-0\">\n <Settings className=\"w-5 h-5 text-primary\" />\n </div>\n <div className=\"flex-1\">\n <h2 className=\"text-xl font-semibold mb-3\">{t(\"managementTitle\")}</h2>\n <p className=\"text-muted-foreground\">{t(\"managementContent\")}</p>\n </div>\n </div>\n </CardContent>\n </Card>\n </FadeIn>\n\n {/* Footer Note */}\n <FadeIn className=\"max-w-4xl mx-auto text-center\">\n <p className=\"text-sm text-muted-foreground\">{t(\"footerNote\")}</p>\n </FadeIn>\n </div>\n </div>\n </Layout>\n );\n}\n\nexport default CookiesPage;\n"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"path": "cookies-page/lang/en.json",
|
|
27
|
+
"type": "registry:lang",
|
|
28
|
+
"target": "$modules$/cookies-page/lang/en.json",
|
|
29
|
+
"content": "{\r\n \"title\": \"Cookie Policy\",\r\n \"lastUpdated\": \"Last Updated\",\r\n \"updateDate\": \"January 2026\",\r\n \"introduction\": \"This Cookie Policy explains how we use cookies and similar tracking technologies when you visit our website. We use these technologies to enhance your browsing experience, analyze site traffic, and understand where our visitors are coming from.\",\r\n \"whatTitle\": \"What Are Cookies?\",\r\n \"whatContent\": \"Cookies are small text files that are stored on your device when you visit a website. They help the website remember your preferences and understand how you interact with the site. Cookies are widely used to make websites work more efficiently and provide useful information to website owners.\",\r\n \"typesTitle\": \"Types of Cookies We Use\",\r\n \"essentialTitle\": \"Essential Cookies\",\r\n \"essentialDesc\": \"These cookies are necessary for the website to function properly. They enable basic features like page navigation, secure area access, and shopping cart functionality. The website cannot function properly without these cookies.\",\r\n \"analyticsTitle\": \"Analytics Cookies\",\r\n \"analyticsDesc\": \"These cookies help us understand how visitors interact with our website by collecting and reporting information anonymously. This helps us improve our website and provide a better user experience.\",\r\n \"functionalTitle\": \"Functional Cookies\",\r\n \"functionalDesc\": \"These cookies enable enhanced functionality and personalization, such as remembering your preferences, language settings, and login information. They may be set by us or by third-party providers.\",\r\n \"marketingTitle\": \"Marketing Cookies\",\r\n \"marketingDesc\": \"These cookies are used to track visitors across websites to display relevant and personalized advertisements. They help measure the effectiveness of advertising campaigns and limit the number of times you see an ad.\",\r\n \"managementTitle\": \"Managing Your Cookie Preferences\",\r\n \"managementContent\": \"You can manage your cookie preferences through your browser settings. Most browsers allow you to block or delete cookies, set preferences for certain websites, or browse in private mode. Please note that blocking essential cookies may affect the functionality of our website.\",\r\n \"footerNote\": \"This cookie policy may be updated periodically. We encourage you to review this page regularly for any changes. Your continued use of our website constitutes acceptance of our cookie practices.\"\r\n}\r\n"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"path": "cookies-page/lang/tr.json",
|
|
33
|
+
"type": "registry:lang",
|
|
34
|
+
"target": "$modules$/cookies-page/lang/tr.json",
|
|
35
|
+
"content": "{\r\n \"title\": \"Çerez Politikası\",\r\n \"lastUpdated\": \"Son Güncelleme\",\r\n \"updateDate\": \"Ocak 2026\",\r\n \"introduction\": \"Bu Çerez Politikası, web sitemizi ziyaret ettiğinizde çerezleri ve benzer izleme teknolojilerini nasıl kullandığımızı açıklamaktadır. Bu teknolojileri tarama deneyiminizi geliştirmek, site trafiğini analiz etmek ve ziyaretçilerimizin nereden geldiğini anlamak için kullanıyoruz.\",\r\n \"whatTitle\": \"Çerez Nedir?\",\r\n \"whatContent\": \"Çerezler, bir web sitesini ziyaret ettiğinizde cihazınızda saklanan küçük metin dosyalarıdır. Web sitesinin tercihlerinizi hatırlamasına ve siteyle nasıl etkileşim kurduğunuzu anlamasına yardımcı olurlar. Çerezler, web sitelerinin daha verimli çalışmasını sağlamak ve site sahiplerine yararlı bilgiler sunmak için yaygın olarak kullanılır.\",\r\n \"typesTitle\": \"Kullandığımız Çerez Türleri\",\r\n \"essentialTitle\": \"Temel Çerezler\",\r\n \"essentialDesc\": \"Bu çerezler web sitesinin düzgün çalışması için gereklidir. Sayfa gezintisi, güvenli alan erişimi ve alışveriş sepeti işlevselliği gibi temel özellikleri etkinleştirirler. Web sitesi bu çerezler olmadan düzgün çalışamaz.\",\r\n \"analyticsTitle\": \"Analitik Çerezler\",\r\n \"analyticsDesc\": \"Bu çerezler, bilgileri anonim olarak toplayıp raporlayarak ziyaretçilerin web sitemizle nasıl etkileşim kurduğunu anlamamıza yardımcı olur. Bu, web sitemizi iyileştirmemize ve daha iyi bir kullanıcı deneyimi sunmamıza olanak tanır.\",\r\n \"functionalTitle\": \"İşlevsel Çerezler\",\r\n \"functionalDesc\": \"Bu çerezler, tercihlerinizi, dil ayarlarınızı ve oturum açma bilgilerinizi hatırlama gibi gelişmiş işlevsellik ve kişiselleştirme sağlar. Tarafımızdan veya üçüncü taraf sağlayıcılar tarafından ayarlanabilirler.\",\r\n \"marketingTitle\": \"Pazarlama Çerezleri\",\r\n \"marketingDesc\": \"Bu çerezler, ilgili ve kişiselleştirilmiş reklamlar görüntülemek için ziyaretçileri web siteleri arasında izlemek için kullanılır. Reklam kampanyalarının etkinliğini ölçmeye ve bir reklamı görme sayınızı sınırlamaya yardımcı olurlar.\",\r\n \"managementTitle\": \"Çerez Tercihlerinizi Yönetme\",\r\n \"managementContent\": \"Çerez tercihlerinizi tarayıcı ayarlarınız aracılığıyla yönetebilirsiniz. Çoğu tarayıcı, çerezleri engellemenize veya silmenize, belirli web siteleri için tercihler belirlemenize veya gizli modda gezinmenize olanak tanır. Temel çerezleri engellemenin web sitemizin işlevselliğini etkileyebileceğini lütfen unutmayın.\",\r\n \"footerNote\": \"Bu çerez politikası periyodik olarak güncellenebilir. Herhangi bir değişiklik için bu sayfayı düzenli olarak incelemenizi öneririz. Web sitemizi kullanmaya devam etmeniz çerez uygulamalarımızı kabul ettiğiniz anlamına gelir.\"\r\n}\r\n"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"exports": {
|
|
39
|
+
"types": [],
|
|
40
|
+
"variables": [
|
|
41
|
+
"CookiesPage",
|
|
42
|
+
"default"
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cta-section",
|
|
3
|
+
"type": "registry:component",
|
|
4
|
+
"title": "CTA Section",
|
|
5
|
+
"description": "Eye-catching call-to-action section with primary/brand color background. Features large headline, supporting text, and prominent action button. Can include secondary button or email input for newsletter. Designed to drive conversions at the bottom of landing pages.",
|
|
6
|
+
"registryDependencies": [],
|
|
7
|
+
"usage": "import { CtaSection } from '@/modules/cta-section';\n\n<CtaSection />\n\n• Installed at: src/modules/cta-section/\n• Customize content: src/modules/cta-section/lang/*.json\n• Customize background via CSS variables",
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "cta-section/index.ts",
|
|
11
|
+
"type": "registry:index",
|
|
12
|
+
"target": "$modules$/cta-section/index.ts",
|
|
13
|
+
"content": "export * from './cta-section';\r\n"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"path": "cta-section/cta-section.tsx",
|
|
17
|
+
"type": "registry:component",
|
|
18
|
+
"target": "$modules$/cta-section/cta-section.tsx",
|
|
19
|
+
"content": "import { Link } from \"react-router\";\nimport { Button } from \"@/components/ui/button\";\nimport { useTranslation } from \"react-i18next\";\n\nexport function CtaSection() {\n const { t } = useTranslation(\"cta-section\");\n\n return (\n <section className=\"py-20 bg-primary text-primary-foreground\">\n <div className=\"container mx-auto px-4 text-center\">\n <h2 className=\"text-3xl lg:text-4xl font-bold mb-6\">\n {t(\"title\", \"Ready to Start Your Project?\")}\n </h2>\n <p className=\"text-xl opacity-90 max-w-2xl mx-auto mb-8\">\n {t(\n \"description\",\n \"Let's discuss your needs and create a solution that drives results for your business.\"\n )}\n </p>\n <div className=\"flex flex-col sm:flex-row gap-4 justify-center\">\n <Button\n size=\"lg\"\n variant=\"secondary\"\n className=\"px-8 py-3 text-lg\"\n asChild\n >\n <Link to=\"/contact\">{t(\"primaryButton\", \"Get Free Quote\")}</Link>\n </Button>\n <Button\n size=\"lg\"\n variant=\"outline\"\n className=\"px-8 py-3 text-lg border-primary-foreground text-primary-foreground bg-transparent hover:bg-primary-foreground hover:text-primary transition-all duration-300\"\n asChild\n >\n <Link to=\"/about\" className=\"text-primary-foreground hover:text-primary\">\n {t(\"secondaryButton\", \"Learn About Us\")}\n </Link>\n </Button>\n </div>\n </div>\n </section>\n );\n}\n"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"path": "cta-section/lang/en.json",
|
|
23
|
+
"type": "registry:lang",
|
|
24
|
+
"target": "$modules$/cta-section/lang/en.json",
|
|
25
|
+
"content": "{\r\n \"title\": \"Ready to Start Your Project?\",\r\n \"description\": \"AI will customize this CTA description based on your site goals. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\",\r\n \"primaryButton\": \"Get Free Quote\",\r\n \"secondaryButton\": \"Learn About Us\"\r\n}\r\n"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"path": "cta-section/lang/tr.json",
|
|
29
|
+
"type": "registry:lang",
|
|
30
|
+
"target": "$modules$/cta-section/lang/tr.json",
|
|
31
|
+
"content": "{\r\n \"title\": \"Projenizi Başlatmaya Hazır mısınız?\",\r\n \"description\": \"AI bu CTA açıklamasını iş tekliflerinize göre özelleştirecektir. Lorem ipsum dolor sit amet, consectetur adipiscing elit.\",\r\n \"primaryButton\": \"Ücretsiz Teklif Al\",\r\n \"secondaryButton\": \"Hakkımızda\"\r\n}\r\n"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"exports": {
|
|
35
|
+
"types": [],
|
|
36
|
+
"variables": [
|
|
37
|
+
"CtaSection"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# About Page
|
|
2
|
+
|
|
3
|
+
Company/personal about page with hero section, mission statement, team member cards with photos, company timeline/history, values section with icons, and statistics counters. Responsive layout with alternating content sections. Supports both corporate and personal portfolio styles.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| Target | Type |
|
|
8
|
+
|--------|------|
|
|
9
|
+
| `$modules$/about-page/index.ts` | index |
|
|
10
|
+
| `$modules$/about-page/about-page.tsx` | page |
|
|
11
|
+
| `$modules$/about-page/lang/en.json` | lang |
|
|
12
|
+
| `$modules$/about-page/lang/tr.json` | lang |
|
|
13
|
+
|
|
14
|
+
## Exports
|
|
15
|
+
|
|
16
|
+
**Components/Functions:** `AboutPage`, `default`
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { AboutPage, default } from '@/modules/about-page';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
import { AboutPage } from '@/modules/about-page';
|
|
26
|
+
|
|
27
|
+
<Route path="/about" element={<AboutPage />} />
|
|
28
|
+
|
|
29
|
+
• Sections: hero, mission, team, timeline, values, stats
|
|
30
|
+
• Edit content in lang/en.json
|
|
31
|
+
• Wrapped with Layout component
|
|
32
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# About Section
|
|
2
|
+
|
|
3
|
+
Comprehensive about section with image grid, mission card, company logos, and stats grid. Features two-column header, main image with side column (mission card + secondary image), company names ticker, and 4-column achievement stats. Perfect for landing pages and about pages.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| Target | Type |
|
|
8
|
+
|--------|------|
|
|
9
|
+
| `$modules$/about-section/index.ts` | index |
|
|
10
|
+
| `$modules$/about-section/about-section.tsx` | component |
|
|
11
|
+
| `$modules$/about-section/lang/en.json` | lang |
|
|
12
|
+
| `$modules$/about-section/lang/tr.json` | lang |
|
|
13
|
+
|
|
14
|
+
## Exports
|
|
15
|
+
|
|
16
|
+
**Components/Functions:** `AboutSection`
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { AboutSection } from '@/modules/about-section';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
import { AboutSection } from '@/modules/about-section';
|
|
26
|
+
|
|
27
|
+
<AboutSection />
|
|
28
|
+
|
|
29
|
+
- Image grid with mission card
|
|
30
|
+
- Company logos section
|
|
31
|
+
- 4-column stats grid
|
|
32
|
+
- Fully translatable via lang files
|
|
33
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Animations
|
|
2
|
+
|
|
3
|
+
Motion animation utilities and wrapper components including FadeIn, SlideIn, ScaleUp, StaggerContainer. Built with motion/react for smooth, performant animations.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| Target | Type |
|
|
8
|
+
|--------|------|
|
|
9
|
+
| `$modules$/animations/index.ts` | index |
|
|
10
|
+
| `$modules$/animations/animations.ts` | lib |
|
|
11
|
+
| `$modules$/animations/components.tsx` | component |
|
|
12
|
+
|
|
13
|
+
## Exports
|
|
14
|
+
|
|
15
|
+
**Components/Functions:** `Fade`, `FadeIn`, `FadeInDown`, `GridItem`, `ListItem`, `ScaleUp`, `SlideInLeft`, `SlideInRight`, `StaggerContainer`, `StaggerItem`, `buttonPress`, `carouselSlide`, `collapseVariants`, `easeTransition`, `fade`, `fadeInDown`, `fadeInUp`, `gridItem`, `hoverLift`, `hoverScale`, `hoverScaleSubtle`, `iconHoverRotate`, `listItem`, `notificationVariants`, `pageTransition`, `quickTransition`, `scaleUp`, `slideInLeft`, `slideInRight`, `springTransition`, `staggerContainer`, `staggerContainerFast`, `staggerContainerSlow`
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { Fade, FadeIn, FadeInDown, ... } from '@/modules/animations';
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
import { FadeIn, StaggerContainer, StaggerItem, ScaleUp } from '@/modules/animations';
|
|
25
|
+
|
|
26
|
+
// Simple fade in on scroll
|
|
27
|
+
<FadeIn>
|
|
28
|
+
<Card>Content</Card>
|
|
29
|
+
</FadeIn>
|
|
30
|
+
|
|
31
|
+
// Staggered grid animation
|
|
32
|
+
<StaggerContainer className="grid grid-cols-3 gap-4">
|
|
33
|
+
{items.map(item => (
|
|
34
|
+
<StaggerItem key={item.id}>
|
|
35
|
+
<Card>{item.content}</Card>
|
|
36
|
+
</StaggerItem>
|
|
37
|
+
))}
|
|
38
|
+
</StaggerContainer>
|
|
39
|
+
|
|
40
|
+
// With delay
|
|
41
|
+
<FadeIn delay={0.2}>
|
|
42
|
+
<Section>...</Section>
|
|
43
|
+
</FadeIn>
|
|
44
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Bento Grid Section
|
|
2
|
+
|
|
3
|
+
A modern bento-style grid layout for showcasing features or content. Supports custom headers, icons, and descriptions with hover animations. Responsive design with 3-column layout on desktop.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| Target | Type |
|
|
8
|
+
|--------|------|
|
|
9
|
+
| `$modules$/bento-grid-section/index.ts` | index |
|
|
10
|
+
| `$modules$/bento-grid-section/bento-grid-section.tsx` | component |
|
|
11
|
+
| `$modules$/bento-grid-section/lang/en.json` | lang |
|
|
12
|
+
| `$modules$/bento-grid-section/lang/tr.json` | lang |
|
|
13
|
+
|
|
14
|
+
## Exports
|
|
15
|
+
|
|
16
|
+
**Components/Functions:** `BentoGrid`, `BentoGridItem`, `BentoGridSection`
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { BentoGrid, BentoGridItem, BentoGridSection } from '@/modules/bento-grid-section';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
import { BentoGridSection } from '@/modules/bento-grid-section';
|
|
26
|
+
|
|
27
|
+
<BentoGridSection
|
|
28
|
+
title="Features"
|
|
29
|
+
items={[
|
|
30
|
+
{
|
|
31
|
+
title: "Fast Performance",
|
|
32
|
+
description: "Lightning fast load times",
|
|
33
|
+
header: <div className="h-full w-full bg-gradient-to-br from-violet-500 to-purple-500" />,
|
|
34
|
+
icon: <IconBolt className="h-4 w-4" />,
|
|
35
|
+
className: "md:col-span-2"
|
|
36
|
+
},
|
|
37
|
+
// more items...
|
|
38
|
+
]}
|
|
39
|
+
/>
|
|
40
|
+
```
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Blog Core
|
|
2
|
+
|
|
3
|
+
Complete blog state management with Zustand. Includes useBlogStore for saved/favorite posts functionality, usePosts hook for fetching posts with category filtering, search, and pagination. TypeScript types for Post, Category, and Author. No provider wrapping needed.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| Target | Type |
|
|
8
|
+
|--------|------|
|
|
9
|
+
| `$modules$/blog-core/index.ts` | index |
|
|
10
|
+
| `$modules$/blog-core/types.ts` | type |
|
|
11
|
+
| `$modules$/blog-core/stores/blog-store.ts` | store |
|
|
12
|
+
| `$modules$/blog-core/usePosts.ts` | hook |
|
|
13
|
+
| `$modules$/blog-core/lang/en.json` | lang |
|
|
14
|
+
| `$modules$/blog-core/lang/tr.json` | lang |
|
|
15
|
+
|
|
16
|
+
## Exports
|
|
17
|
+
|
|
18
|
+
**Types:** `Author`, `BlogCategory`, `BlogContextType`, `BlogSettings`, `Comment`, `Post`, `PostCategory`
|
|
19
|
+
|
|
20
|
+
**Components/Functions:** `useBlog`, `useBlogCategories`, `useBlogStore`, `useFeaturedPosts`, `usePopularPosts`, `usePostBySlug`, `usePostSearch`, `usePostStats`, `usePosts`, `usePostsByCategory`, `usePostsByTag`, `useRecentPosts`
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { useBlog, useBlogCategories, useBlogStore, ... } from '@/modules/blog-core';
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
import { useBlog, usePosts, usePostBySlug } from '@/modules/blog-core';
|
|
30
|
+
|
|
31
|
+
// No provider needed - just use the hooks:
|
|
32
|
+
const { favorites, addToFavorites, isFavorite } = useBlog();
|
|
33
|
+
const { posts, loading } = usePosts();
|
|
34
|
+
|
|
35
|
+
// Or use store directly with selectors:
|
|
36
|
+
const favorites = useBlogStore((s) => s.favorites);
|
|
37
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Blog List Page
|
|
2
|
+
|
|
3
|
+
Blog listing page with category filter tabs, search functionality, and responsive post grid. Uses PostCard component for display with grid/list view toggle. Features loading states, empty state handling, pagination, and featured post highlight at top. Includes sidebar with popular posts, categories, and newsletter signup.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| Target | Type |
|
|
8
|
+
|--------|------|
|
|
9
|
+
| `$modules$/blog-list-page/index.ts` | index |
|
|
10
|
+
| `$modules$/blog-list-page/blog-list-page.tsx` | page |
|
|
11
|
+
| `$modules$/blog-list-page/lang/en.json` | lang |
|
|
12
|
+
| `$modules$/blog-list-page/lang/tr.json` | lang |
|
|
13
|
+
|
|
14
|
+
## Exports
|
|
15
|
+
|
|
16
|
+
**Components/Functions:** `BlogListPage`, `default`
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { BlogListPage, default } from '@/modules/blog-list-page';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
import { BlogListPage } from '@/modules/blog-list-page';
|
|
26
|
+
|
|
27
|
+
<Route path="/blog" element={<BlogListPage />} />
|
|
28
|
+
|
|
29
|
+
• Uses usePosts() from blog-core (Zustand)
|
|
30
|
+
• Features: category tabs, search, grid/list view
|
|
31
|
+
• Sidebar: popular posts, categories, newsletter
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Dependencies
|
|
35
|
+
|
|
36
|
+
This component requires:
|
|
37
|
+
- `blog-core`
|
|
38
|
+
- `post-card`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Blog Section
|
|
2
|
+
|
|
3
|
+
Blog posts preview section with 3-column card grid. Features tagline badge, heading, subtitle, and 'view all' link. Each card shows image, category badge, date, title, summary, and 'read more' link. Great for homepage blog previews.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| Target | Type |
|
|
8
|
+
|--------|------|
|
|
9
|
+
| `$modules$/blog-section/index.ts` | index |
|
|
10
|
+
| `$modules$/blog-section/blog-section.tsx` | component |
|
|
11
|
+
| `$modules$/blog-section/lang/en.json` | lang |
|
|
12
|
+
| `$modules$/blog-section/lang/tr.json` | lang |
|
|
13
|
+
|
|
14
|
+
## Exports
|
|
15
|
+
|
|
16
|
+
**Components/Functions:** `BlogSection`
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { BlogSection } from '@/modules/blog-section';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
import { BlogSection } from '@/modules/blog-section';
|
|
26
|
+
|
|
27
|
+
<BlogSection />
|
|
28
|
+
|
|
29
|
+
- 3-column post cards
|
|
30
|
+
- Category badges and dates
|
|
31
|
+
- Hover effects on images
|
|
32
|
+
- Customize posts via lang files
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Dependencies
|
|
36
|
+
|
|
37
|
+
This component requires:
|
|
38
|
+
- `card`
|
|
39
|
+
- `badge`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Cards Carousel Section
|
|
2
|
+
|
|
3
|
+
Apple-style expandable cards carousel with smooth animations. Cards expand into full-screen modals on click. Features horizontal scrolling, navigation buttons, and responsive design.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| Target | Type |
|
|
8
|
+
|--------|------|
|
|
9
|
+
| `$modules$/cards-carousel-section/index.ts` | index |
|
|
10
|
+
| `$modules$/cards-carousel-section/cards-carousel-section.tsx` | component |
|
|
11
|
+
| `$modules$/cards-carousel-section/lang/en.json` | lang |
|
|
12
|
+
| `$modules$/cards-carousel-section/lang/tr.json` | lang |
|
|
13
|
+
|
|
14
|
+
## Exports
|
|
15
|
+
|
|
16
|
+
**Components/Functions:** `Card`, `CardsCarouselSection`, `Carousel`
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { Card, CardsCarouselSection, Carousel } from '@/modules/cards-carousel-section';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
import { CardsCarouselSection, Card, Carousel } from '@/modules/cards-carousel-section';
|
|
26
|
+
|
|
27
|
+
<CardsCarouselSection
|
|
28
|
+
title="Explore"
|
|
29
|
+
items={[
|
|
30
|
+
{
|
|
31
|
+
category: "Technology",
|
|
32
|
+
title: "AI Revolution",
|
|
33
|
+
src: "/images/ai.jpg",
|
|
34
|
+
content: <div>Your content here...</div>
|
|
35
|
+
},
|
|
36
|
+
// more items...
|
|
37
|
+
]}
|
|
38
|
+
/>
|
|
39
|
+
```
|