@promakeai/cli 0.3.2 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +415 -209
- package/dist/registry/about-page.json +3 -3
- package/dist/registry/about-section.json +4 -4
- package/dist/registry/animations.json +2 -2
- package/dist/registry/announcement-bar.json +4 -4
- package/dist/registry/api.json +1 -1
- package/dist/registry/auth-core.json +3 -3
- package/dist/registry/auth.json +70 -0
- package/dist/registry/bento-grid-section.json +4 -4
- package/dist/registry/blog-core.json +5 -5
- package/dist/registry/blog-list-page.json +3 -3
- package/dist/registry/blog-section.json +4 -4
- package/dist/registry/cards-carousel-section.json +4 -4
- package/dist/registry/cart-drawer.json +3 -3
- package/dist/registry/cart-page.json +3 -3
- package/dist/registry/case-study-page.json +3 -3
- package/dist/registry/category-section.json +3 -3
- package/dist/registry/checkout-page.json +3 -3
- package/dist/registry/coming-soon-page-minimal.json +4 -4
- package/dist/registry/coming-soon-page.json +4 -4
- package/dist/registry/contact-info-grid.json +4 -4
- package/dist/registry/contact-page-centered.json +4 -4
- package/dist/registry/contact-page-split.json +4 -4
- package/dist/registry/contact-page.json +3 -3
- package/dist/registry/content-section.json +4 -4
- package/dist/registry/cookie-consent.json +4 -4
- package/dist/registry/cookies-page.json +3 -3
- package/dist/registry/cta-section.json +3 -3
- package/dist/registry/docs/reset-password-page.md +36 -0
- package/dist/registry/ecommerce-core.json +10 -10
- package/dist/registry/empty-page.json +3 -3
- package/dist/registry/faq-categorized.json +4 -4
- package/dist/registry/faq-simple.json +4 -4
- package/dist/registry/favorites-blog-block.json +1 -1
- package/dist/registry/favorites-blog-page.json +4 -4
- package/dist/registry/favorites-ecommerce-block.json +1 -1
- package/dist/registry/favorites-ecommerce-page.json +4 -4
- package/dist/registry/feature-section.json +3 -3
- package/dist/registry/featured-products.json +3 -3
- package/dist/registry/footer-detailed.json +4 -4
- package/dist/registry/footer-minimal.json +3 -3
- package/dist/registry/footer.json +3 -3
- package/dist/registry/forgot-password-page-split.json +4 -4
- package/dist/registry/forgot-password-page.json +4 -4
- package/dist/registry/google-adsense.json +4 -4
- package/dist/registry/google-map.json +2 -2
- package/dist/registry/header-centered-pill.json +4 -4
- package/dist/registry/header-ecommerce.json +3 -3
- package/dist/registry/header-mega.json +4 -4
- package/dist/registry/header-minimal.json +4 -4
- package/dist/registry/header-simple.json +3 -3
- package/dist/registry/hero-carousel.json +3 -3
- package/dist/registry/hero-cta.json +4 -4
- package/dist/registry/hero-gradient.json +4 -4
- package/dist/registry/hero-grid.json +4 -4
- package/dist/registry/hero-profile.json +3 -3
- package/dist/registry/hero.json +3 -3
- package/dist/registry/landing-page-app.json +3 -3
- package/dist/registry/landing-page-saas.json +3 -3
- package/dist/registry/login-page-split.json +4 -4
- package/dist/registry/login-page.json +4 -4
- package/dist/registry/logo-cloud.json +4 -4
- package/dist/registry/masonry-grid.json +3 -3
- package/dist/registry/my-orders-page.json +4 -4
- package/dist/registry/newsletter-section.json +4 -4
- package/dist/registry/order-card-compact.json +1 -1
- package/dist/registry/order-confirmation-page.json +4 -4
- package/dist/registry/order-detail-block.json +1 -1
- package/dist/registry/orders-list-block.json +1 -1
- package/dist/registry/payment-success-block.json +1 -1
- package/dist/registry/portfolio-page.json +4 -4
- package/dist/registry/post-card.json +3 -3
- package/dist/registry/post-detail-block.json +1 -1
- package/dist/registry/post-detail-page.json +4 -4
- package/dist/registry/pricing-card.json +3 -3
- package/dist/registry/pricing-page.json +4 -4
- package/dist/registry/pricing-section.json +4 -4
- package/dist/registry/privacy-page.json +3 -3
- package/dist/registry/product-card-detailed.json +4 -4
- package/dist/registry/product-card-hover.json +4 -4
- package/dist/registry/product-card.json +3 -3
- package/dist/registry/product-detail-block.json +1 -1
- package/dist/registry/product-detail-page.json +4 -4
- package/dist/registry/product-detail-section.json +4 -4
- package/dist/registry/product-quick-view.json +4 -4
- package/dist/registry/products-page.json +3 -3
- package/dist/registry/reading-progress.json +4 -4
- package/dist/registry/register-page-split.json +4 -4
- package/dist/registry/register-page.json +4 -4
- package/dist/registry/related-posts-block.json +1 -1
- package/dist/registry/related-products-block.json +1 -1
- package/dist/registry/reset-password-page-split.json +4 -4
- package/dist/registry/reset-password-page.json +39 -0
- package/dist/registry/service-card.json +1 -1
- package/dist/registry/share-buttons.json +4 -4
- package/dist/registry/skill-card.json +1 -1
- package/dist/registry/team-page.json +4 -4
- package/dist/registry/terms-page.json +3 -3
- package/dist/registry/testimonials-carousel.json +4 -4
- package/dist/registry/testimonials-grid.json +4 -4
- package/dist/registry/timeline-section.json +4 -4
- package/dist/registry/video-hero.json +4 -4
- package/dist/registry/youtube-embed.json +4 -4
- package/package.json +2 -2
- package/template/.env +6 -6
- package/template/public/_redirects +1 -1
- package/template/public/robots.txt +14 -14
- package/template/src/components/GoogleAnalytics.tsx +34 -34
- package/template/src/components/LanguageSwitcher.tsx +53 -53
- package/template/src/components/ScriptInjector.tsx +62 -62
- package/template/src/lib/env.ts +19 -19
- package/template/src/router.tsx +14 -14
- package/template/src/vite-env.d.ts +1 -1
|
@@ -10,25 +10,25 @@
|
|
|
10
10
|
"path": "contact-info-grid/index.ts",
|
|
11
11
|
"type": "registry:index",
|
|
12
12
|
"target": "$modules$/contact-info-grid/index.ts",
|
|
13
|
-
"content": "export * from './contact-info-grid';\n"
|
|
13
|
+
"content": "export * from './contact-info-grid';\r\n"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"path": "contact-info-grid/contact-info-grid.tsx",
|
|
17
17
|
"type": "registry:component",
|
|
18
18
|
"target": "$modules$/contact-info-grid/contact-info-grid.tsx",
|
|
19
|
-
"content": "import { Mail, MapPin, MessageCircle, Phone } from \"lucide-react\";\nimport { useTranslation } from \"react-i18next\";\nimport { cn } from \"@/lib/utils\";\nimport constants from \"@/constants/constants.json\";\n\ninterface ContactInfoGridProps {\n className?: string;\n}\n\nexport function ContactInfoGrid({ className }: ContactInfoGridProps) {\n const { t } = useTranslation(\"contact-info-grid\");\n\n const contactItems = [\n {\n icon: Mail,\n label: t(\"emailLabel\", \"Email\"),\n description: t(\"emailDesc\", \"We respond to all emails within 24 hours.\"),\n value: constants.email || \"hello@example.com\",\n href: `mailto:${constants.email || \"hello@example.com\"}`,\n },\n {\n icon: MapPin,\n label: t(\"officeLabel\", \"Office\"),\n description: t(\"officeDesc\", \"Drop by our office for a chat.\"),\n value: `${constants.address?.line1 || \"\"}, ${constants.address?.city || \"\"}`,\n href: \"#\",\n },\n {\n icon: Phone,\n label: t(\"phoneLabel\", \"Phone\"),\n description: t(\"phoneDesc\", \"We're available Mon-Fri, 9am-5pm.\"),\n value: constants.phone || \"+1 234 567 890\",\n href: `tel:${constants.phone || \"+1234567890\"}`,\n },\n {\n icon: MessageCircle,\n label: t(\"chatLabel\", \"Live Chat\"),\n description: t(\"chatDesc\", \"Get instant help from our support team.\"),\n value: t(\"startChat\", \"Start Chat\"),\n href: \"#\",\n },\n ];\n\n return (\n <section className={cn(\"py-16 md:py-24\", className)}>\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4\">\n <div className=\"mb-12\">\n <h2 className=\"text-3xl font-bold md:text-4xl mb-4\">\n {t(\"title\", \"Get in Touch\")}\n </h2>\n <p className=\"text-lg text-muted-foreground max-w-xl\">\n {t(\"subtitle\", \"Have questions? We'd love to hear from you. Choose your preferred way to reach us.\")}\n </p>\n </div>\n\n <div className=\"grid sm:grid-cols-2 lg:grid-cols-4 gap-6\">\n {contactItems.map((item, index) => (\n <div\n key={index}\n className=\"rounded-xl bg-muted/50 p-6 hover:bg-muted transition-colors\"\n >\n <span className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-primary/10\">\n <item.icon className=\"h-6 w-6 text-primary\" />\n </span>\n <h3 className=\"mb-2 text-lg font-semibold\">{item.label}</h3>\n <p className=\"mb-3 text-sm text-muted-foreground\">\n {item.description}\n </p>\n <a\n href={item.href}\n className=\"text-sm font-semibold text-primary hover:underline\"\n >\n {item.value}\n </a>\n </div>\n ))}\n </div>\n </div>\n </section>\n );\n}\n"
|
|
19
|
+
"content": "import { Mail, MapPin, MessageCircle, Phone } from \"lucide-react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport constants from \"@/constants/constants.json\";\r\n\r\ninterface ContactInfoGridProps {\r\n className?: string;\r\n}\r\n\r\nexport function ContactInfoGrid({ className }: ContactInfoGridProps) {\r\n const { t } = useTranslation(\"contact-info-grid\");\r\n\r\n const contactItems = [\r\n {\r\n icon: Mail,\r\n label: t(\"emailLabel\", \"Email\"),\r\n description: t(\"emailDesc\", \"We respond to all emails within 24 hours.\"),\r\n value: constants.email || \"hello@example.com\",\r\n href: `mailto:${constants.email || \"hello@example.com\"}`,\r\n },\r\n {\r\n icon: MapPin,\r\n label: t(\"officeLabel\", \"Office\"),\r\n description: t(\"officeDesc\", \"Drop by our office for a chat.\"),\r\n value: `${constants.address?.line1 || \"\"}, ${constants.address?.city || \"\"}`,\r\n href: \"#\",\r\n },\r\n {\r\n icon: Phone,\r\n label: t(\"phoneLabel\", \"Phone\"),\r\n description: t(\"phoneDesc\", \"We're available Mon-Fri, 9am-5pm.\"),\r\n value: constants.phone || \"+1 234 567 890\",\r\n href: `tel:${constants.phone || \"+1234567890\"}`,\r\n },\r\n {\r\n icon: MessageCircle,\r\n label: t(\"chatLabel\", \"Live Chat\"),\r\n description: t(\"chatDesc\", \"Get instant help from our support team.\"),\r\n value: t(\"startChat\", \"Start Chat\"),\r\n href: \"#\",\r\n },\r\n ];\r\n\r\n return (\r\n <section className={cn(\"py-16 md:py-24\", className)}>\r\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4\">\r\n <div className=\"mb-12\">\r\n <h2 className=\"text-3xl font-bold md:text-4xl mb-4\">\r\n {t(\"title\", \"Get in Touch\")}\r\n </h2>\r\n <p className=\"text-lg text-muted-foreground max-w-xl\">\r\n {t(\"subtitle\", \"Have questions? We'd love to hear from you. Choose your preferred way to reach us.\")}\r\n </p>\r\n </div>\r\n\r\n <div className=\"grid sm:grid-cols-2 lg:grid-cols-4 gap-6\">\r\n {contactItems.map((item, index) => (\r\n <div\r\n key={index}\r\n className=\"rounded-xl bg-muted/50 p-6 hover:bg-muted transition-colors\"\r\n >\r\n <span className=\"mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-primary/10\">\r\n <item.icon className=\"h-6 w-6 text-primary\" />\r\n </span>\r\n <h3 className=\"mb-2 text-lg font-semibold\">{item.label}</h3>\r\n <p className=\"mb-3 text-sm text-muted-foreground\">\r\n {item.description}\r\n </p>\r\n <a\r\n href={item.href}\r\n className=\"text-sm font-semibold text-primary hover:underline\"\r\n >\r\n {item.value}\r\n </a>\r\n </div>\r\n ))}\r\n </div>\r\n </div>\r\n </section>\r\n );\r\n}\r\n"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
"path": "contact-info-grid/lang/en.json",
|
|
23
23
|
"type": "registry:lang",
|
|
24
24
|
"target": "$modules$/contact-info-grid/lang/en.json",
|
|
25
|
-
"content": "{\n \"title\": \"Get in Touch\",\n \"subtitle\": \"This text introduces your contact information grid. Explain the different ways visitors can reach you and any important details about your contact preferences or availability. Use Promake to provide clear, helpful guidance for getting in touch.\",\n \"emailLabel\": \"Email\",\n \"emailDesc\": \"We respond to all emails within 24 hours.\",\n \"officeLabel\": \"Office\",\n \"officeDesc\": \"Drop by our office for a chat.\",\n \"phoneLabel\": \"Phone\",\n \"phoneDesc\": \"We're available Mon-Fri, 9am-5pm.\",\n \"chatLabel\": \"Live Chat\",\n \"chatDesc\": \"Get instant help from our support team.\",\n \"startChat\": \"Start Chat\"\n}\n"
|
|
25
|
+
"content": "{\r\n \"title\": \"Get in Touch\",\r\n \"subtitle\": \"This text introduces your contact information grid. Explain the different ways visitors can reach you and any important details about your contact preferences or availability. Use Promake to provide clear, helpful guidance for getting in touch.\",\r\n \"emailLabel\": \"Email\",\r\n \"emailDesc\": \"We respond to all emails within 24 hours.\",\r\n \"officeLabel\": \"Office\",\r\n \"officeDesc\": \"Drop by our office for a chat.\",\r\n \"phoneLabel\": \"Phone\",\r\n \"phoneDesc\": \"We're available Mon-Fri, 9am-5pm.\",\r\n \"chatLabel\": \"Live Chat\",\r\n \"chatDesc\": \"Get instant help from our support team.\",\r\n \"startChat\": \"Start Chat\"\r\n}\r\n"
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"path": "contact-info-grid/lang/tr.json",
|
|
29
29
|
"type": "registry:lang",
|
|
30
30
|
"target": "$modules$/contact-info-grid/lang/tr.json",
|
|
31
|
-
"content": "{\n \"title\": \"İletişime Geçin\",\n \"subtitle\": \"Bu metin iletişim bilgileri tablosunu tanıtır. Ziyaretçilerin size ulaşabilecekleri farklı yolları ve iletişim tercihleriniz veya müsaitliğinizle ilgili önemli detayları açıklayın. Promake ile iletişime geçmek için açık ve faydalı rehberlik sağlayın.\",\n \"emailLabel\": \"E-posta\",\n \"emailDesc\": \"Tüm e-postalara 24 saat içinde yanıt veriyoruz.\",\n \"officeLabel\": \"Ofis\",\n \"officeDesc\": \"Sohbet etmek için ofisimize uğrayın.\",\n \"phoneLabel\": \"Telefon\",\n \"phoneDesc\": \"Pazartesi-Cuma, 9:00-17:00 arası müsaitiz.\",\n \"chatLabel\": \"Canlı Sohbet\",\n \"chatDesc\": \"Destek ekibimizden anında yardım alın.\",\n \"startChat\": \"Sohbet Başlat\"\n}\n"
|
|
31
|
+
"content": "{\r\n \"title\": \"İletişime Geçin\",\r\n \"subtitle\": \"Bu metin iletişim bilgileri tablosunu tanıtır. Ziyaretçilerin size ulaşabilecekleri farklı yolları ve iletişim tercihleriniz veya müsaitliğinizle ilgili önemli detayları açıklayın. Promake ile iletişime geçmek için açık ve faydalı rehberlik sağlayın.\",\r\n \"emailLabel\": \"E-posta\",\r\n \"emailDesc\": \"Tüm e-postalara 24 saat içinde yanıt veriyoruz.\",\r\n \"officeLabel\": \"Ofis\",\r\n \"officeDesc\": \"Sohbet etmek için ofisimize uğrayın.\",\r\n \"phoneLabel\": \"Telefon\",\r\n \"phoneDesc\": \"Pazartesi-Cuma, 9:00-17:00 arası müsaitiz.\",\r\n \"chatLabel\": \"Canlı Sohbet\",\r\n \"chatDesc\": \"Destek ekibimizden anında yardım alın.\",\r\n \"startChat\": \"Sohbet Başlat\"\r\n}\r\n"
|
|
32
32
|
}
|
|
33
33
|
],
|
|
34
34
|
"exports": {
|
|
@@ -19,25 +19,25 @@
|
|
|
19
19
|
"path": "contact-page-centered/index.ts",
|
|
20
20
|
"type": "registry:index",
|
|
21
21
|
"target": "$modules$/contact-page-centered/index.ts",
|
|
22
|
-
"content": "export * from './contact-page-centered';\nexport { ContactPageCentered as default } from './contact-page-centered';\n"
|
|
22
|
+
"content": "export * from './contact-page-centered';\r\nexport { ContactPageCentered as default } from './contact-page-centered';\r\n"
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
"path": "contact-page-centered/contact-page-centered.tsx",
|
|
26
26
|
"type": "registry:component",
|
|
27
27
|
"target": "$modules$/contact-page-centered/contact-page-centered.tsx",
|
|
28
|
-
"content": "import React, { useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { usePageTitle } from \"@/hooks/use-page-title\";\nimport { Mail, Phone, MapPin } from \"lucide-react\";\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 } from \"@/components/ui/card\";\nimport { cn } from \"@/lib/utils\";\nimport constants from \"@/constants/constants.json\";\n\ninterface ContactPageCenteredProps {\n className?: string;\n}\n\nexport function ContactPageCentered({ className }: ContactPageCenteredProps) {\n const { t } = useTranslation(\"contact-page-centered\");\n usePageTitle({ title: t(\"title\", \"Contact Us\") });\n const apiService = useApiService();\n\n const [formData, setFormData] = useState({\n name: \"\",\n email: \"\",\n message: \"\",\n });\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitStatus, setSubmitStatus] = useState<\"idle\" | \"success\" | \"error\">(\"idle\");\n\n const contactCards = [\n {\n icon: Mail,\n title: t(\"emailTitle\", \"Email\"),\n value: constants.email || \"hello@example.com\",\n href: `mailto:${constants.email || \"hello@example.com\"}`,\n },\n {\n icon: Phone,\n title: t(\"phoneTitle\", \"Phone\"),\n value: constants.phone || \"+1 234 567 890\",\n href: `tel:${constants.phone || \"+1234567890\"}`,\n },\n {\n icon: MapPin,\n title: t(\"addressTitle\", \"Address\"),\n value: constants.address?.city || \"New York, USA\",\n href: \"#\",\n },\n ];\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setIsSubmitting(true);\n setSubmitStatus(\"idle\");\n\n try {\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: \"message\", required: true },\n ],\n },\n constants.site.defaultLanguage\n );\n\n setSubmitStatus(\"success\");\n setFormData({ name: \"\", email: \"\", message: \"\" });\n setTimeout(() => setSubmitStatus(\"idle\"), 5000);\n } catch {\n setSubmitStatus(\"error\");\n setTimeout(() => setSubmitStatus(\"idle\"), 5000);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n setFormData((prev) => ({ ...prev, [e.target.name]: e.target.value }));\n };\n\n return (\n <Layout>\n <div className={cn(\"min-h-screen bg-muted/30 py-16 md:py-24\", className)}>\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4 max-w-4xl\">\n {/* Header */}\n <div className=\"text-center mb-12\">\n <h1 className=\"text-4xl font-bold mb-4\">{t(\"title\", \"Contact Us\")}</h1>\n <p className=\"text-lg text-muted-foreground max-w-2xl mx-auto\">\n {t(\"subtitle\", \"We'd love to hear from you. Send us a message and we'll respond as soon as possible.\")}\n </p>\n </div>\n\n {/* Contact Cards */}\n <div className=\"grid sm:grid-cols-3 gap-4 mb-12\">\n {contactCards.map((card, index) => (\n <Card key={index} className=\"text-center\">\n <CardContent className=\"pt-6\">\n <div className=\"mx-auto w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center mb-4\">\n <card.icon className=\"h-6 w-6 text-primary\" />\n </div>\n <h3 className=\"font-semibold mb-1\">{card.title}</h3>\n <a\n href={card.href}\n className=\"text-sm text-muted-foreground hover:text-primary transition-colors\"\n >\n {card.value}\n </a>\n </CardContent>\n </Card>\n ))}\n </div>\n\n {/* Form */}\n <Card>\n <CardContent className=\"pt-6\">\n <form onSubmit={handleSubmit} className=\"space-y-6\">\n <div className=\"grid sm:grid-cols-2 gap-4\">\n <div>\n <Label htmlFor=\"name\">{t(\"nameLabel\", \"Name\")} *</Label>\n <Input\n id=\"name\"\n name=\"name\"\n value={formData.name}\n onChange={handleChange}\n placeholder={t(\"namePlaceholder\", \"Your name\")}\n required\n className=\"mt-1\"\n />\n </div>\n <div>\n <Label htmlFor=\"email\">{t(\"emailLabel\", \"Email\")} *</Label>\n <Input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n value={formData.email}\n onChange={handleChange}\n placeholder={t(\"emailPlaceholder\", \"your@email.com\")}\n required\n className=\"mt-1\"\n />\n </div>\n </div>\n\n <div>\n <Label htmlFor=\"message\">{t(\"messageLabel\", \"Message\")} *</Label>\n <Textarea\n id=\"message\"\n name=\"message\"\n value={formData.message}\n onChange={handleChange}\n placeholder={t(\"messagePlaceholder\", \"How can we help you?\")}\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 border border-green-500/30 rounded-lg\">\n <p className=\"text-green-600 dark:text-green-400 text-sm font-medium\">\n {t(\"success\", \"Message sent successfully! We'll get back to you soon.\")}\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\", \"Something went wrong. Please try again.\")}\n </p>\n </div>\n )}\n\n <Button type=\"submit\" size=\"lg\" className=\"w-full\" disabled={isSubmitting}>\n {isSubmitting ? t(\"sending\", \"Sending...\") : t(\"submit\", \"Send Message\")}\n </Button>\n </form>\n </CardContent>\n </Card>\n </div>\n </div>\n </Layout>\n );\n}\n\nexport default ContactPageCentered;\n"
|
|
28
|
+
"content": "import React, { useState } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { usePageTitle } from \"@/hooks/use-page-title\";\r\nimport { Mail, Phone, MapPin } 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 { Card, CardContent } from \"@/components/ui/card\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport constants from \"@/constants/constants.json\";\r\n\r\ninterface ContactPageCenteredProps {\r\n className?: string;\r\n}\r\n\r\nexport function ContactPageCentered({ className }: ContactPageCenteredProps) {\r\n const { t } = useTranslation(\"contact-page-centered\");\r\n usePageTitle({ title: t(\"title\", \"Contact Us\") });\r\n const apiService = useApiService();\r\n\r\n const [formData, setFormData] = useState({\r\n name: \"\",\r\n email: \"\",\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 contactCards = [\r\n {\r\n icon: Mail,\r\n title: t(\"emailTitle\", \"Email\"),\r\n value: constants.email || \"hello@example.com\",\r\n href: `mailto:${constants.email || \"hello@example.com\"}`,\r\n },\r\n {\r\n icon: Phone,\r\n title: t(\"phoneTitle\", \"Phone\"),\r\n value: constants.phone || \"+1 234 567 890\",\r\n href: `tel:${constants.phone || \"+1234567890\"}`,\r\n },\r\n {\r\n icon: MapPin,\r\n title: t(\"addressTitle\", \"Address\"),\r\n value: constants.address?.city || \"New York, USA\",\r\n href: \"#\",\r\n },\r\n ];\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: \"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: \"\", 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 bg-muted/30 py-16 md:py-24\", className)}>\r\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4 max-w-4xl\">\r\n {/* Header */}\r\n <div className=\"text-center mb-12\">\r\n <h1 className=\"text-4xl font-bold mb-4\">{t(\"title\", \"Contact Us\")}</h1>\r\n <p className=\"text-lg text-muted-foreground max-w-2xl mx-auto\">\r\n {t(\"subtitle\", \"We'd love to hear from you. Send us a message and we'll respond as soon as possible.\")}\r\n </p>\r\n </div>\r\n\r\n {/* Contact Cards */}\r\n <div className=\"grid sm:grid-cols-3 gap-4 mb-12\">\r\n {contactCards.map((card, index) => (\r\n <Card key={index} className=\"text-center\">\r\n <CardContent className=\"pt-6\">\r\n <div className=\"mx-auto w-12 h-12 rounded-full bg-primary/10 flex items-center justify-center mb-4\">\r\n <card.icon className=\"h-6 w-6 text-primary\" />\r\n </div>\r\n <h3 className=\"font-semibold mb-1\">{card.title}</h3>\r\n <a\r\n href={card.href}\r\n className=\"text-sm text-muted-foreground hover:text-primary transition-colors\"\r\n >\r\n {card.value}\r\n </a>\r\n </CardContent>\r\n </Card>\r\n ))}\r\n </div>\r\n\r\n {/* Form */}\r\n <Card>\r\n <CardContent className=\"pt-6\">\r\n <form onSubmit={handleSubmit} className=\"space-y-6\">\r\n <div className=\"grid sm:grid-cols-2 gap-4\">\r\n <div>\r\n <Label htmlFor=\"name\">{t(\"nameLabel\", \"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\", \"Your name\")}\r\n required\r\n className=\"mt-1\"\r\n />\r\n </div>\r\n <div>\r\n <Label htmlFor=\"email\">{t(\"emailLabel\", \"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\", \"your@email.com\")}\r\n required\r\n className=\"mt-1\"\r\n />\r\n </div>\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\", \"How can we help you?\")}\r\n required\r\n rows={6}\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 successfully! We'll get back to you 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 </CardContent>\r\n </Card>\r\n </div>\r\n </div>\r\n </Layout>\r\n );\r\n}\r\n\r\nexport default ContactPageCentered;\r\n"
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"path": "contact-page-centered/lang/en.json",
|
|
32
32
|
"type": "registry:lang",
|
|
33
33
|
"target": "$modules$/contact-page-centered/lang/en.json",
|
|
34
|
-
"content": "{\n \"title\": \"Contact Us\",\n \"subtitle\": \"This subtitle appears below your contact page heading. Use it to encourage visitors to reach out, explain your availability, or highlight your commitment to customer service. Customize with Promake to reflect your brand's communication style.\",\n \"emailTitle\": \"Email\",\n \"phoneTitle\": \"Phone\",\n \"addressTitle\": \"Address\",\n \"nameLabel\": \"Name\",\n \"namePlaceholder\": \"Your name\",\n \"emailLabel\": \"Email\",\n \"emailPlaceholder\": \"your@email.com\",\n \"messageLabel\": \"Message\",\n \"messagePlaceholder\": \"How can we help you?\",\n \"submit\": \"Send Message\",\n \"sending\": \"Sending...\",\n \"success\": \"Message sent successfully! We'll get back to you soon.\",\n \"error\": \"Something went wrong. Please try again.\"\n}\n"
|
|
34
|
+
"content": "{\r\n \"title\": \"Contact Us\",\r\n \"subtitle\": \"This subtitle appears below your contact page heading. Use it to encourage visitors to reach out, explain your availability, or highlight your commitment to customer service. Customize with Promake to reflect your brand's communication style.\",\r\n \"emailTitle\": \"Email\",\r\n \"phoneTitle\": \"Phone\",\r\n \"addressTitle\": \"Address\",\r\n \"nameLabel\": \"Name\",\r\n \"namePlaceholder\": \"Your name\",\r\n \"emailLabel\": \"Email\",\r\n \"emailPlaceholder\": \"your@email.com\",\r\n \"messageLabel\": \"Message\",\r\n \"messagePlaceholder\": \"How can we help you?\",\r\n \"submit\": \"Send Message\",\r\n \"sending\": \"Sending...\",\r\n \"success\": \"Message sent successfully! We'll get back to you soon.\",\r\n \"error\": \"Something went wrong. Please try again.\"\r\n}\r\n"
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
37
|
"path": "contact-page-centered/lang/tr.json",
|
|
38
38
|
"type": "registry:lang",
|
|
39
39
|
"target": "$modules$/contact-page-centered/lang/tr.json",
|
|
40
|
-
"content": "{\n \"title\": \"İletişim\",\n \"subtitle\": \"Bu alt başlık iletişim sayfası başlığınızın altında görünür. Ziyaretçileri iletişime geçmeye teşvik etmek, müsaitliğinizi açıklamak veya müşteri hizmetlerine olan bağlılığınızı vurgulamak için kullanın. Promake ile markanızın iletişim tarzını yansıtacak şekilde özelleştirin.\",\n \"emailTitle\": \"E-posta\",\n \"phoneTitle\": \"Telefon\",\n \"addressTitle\": \"Adres\",\n \"nameLabel\": \"İsim\",\n \"namePlaceholder\": \"Adınız\",\n \"emailLabel\": \"E-posta\",\n \"emailPlaceholder\": \"email@adresiniz.com\",\n \"messageLabel\": \"Mesaj\",\n \"messagePlaceholder\": \"Size nasıl yardımcı olabiliriz?\",\n \"submit\": \"Mesaj Gönder\",\n \"sending\": \"Gönderiliyor...\",\n \"success\": \"Mesajınız başarıyla gönderildi! En kısa sürede size döneceğiz.\",\n \"error\": \"Bir şeyler yanlış gitti. Lütfen tekrar deneyin.\"\n}\n"
|
|
40
|
+
"content": "{\r\n \"title\": \"İletişim\",\r\n \"subtitle\": \"Bu alt başlık iletişim sayfası başlığınızın altında görünür. Ziyaretçileri iletişime geçmeye teşvik etmek, müsaitliğinizi açıklamak veya müşteri hizmetlerine olan bağlılığınızı vurgulamak için kullanın. Promake ile markanızın iletişim tarzını yansıtacak şekilde özelleştirin.\",\r\n \"emailTitle\": \"E-posta\",\r\n \"phoneTitle\": \"Telefon\",\r\n \"addressTitle\": \"Adres\",\r\n \"nameLabel\": \"İsim\",\r\n \"namePlaceholder\": \"Adınız\",\r\n \"emailLabel\": \"E-posta\",\r\n \"emailPlaceholder\": \"email@adresiniz.com\",\r\n \"messageLabel\": \"Mesaj\",\r\n \"messagePlaceholder\": \"Size nasıl yardımcı olabiliriz?\",\r\n \"submit\": \"Mesaj Gönder\",\r\n \"sending\": \"Gönderiliyor...\",\r\n \"success\": \"Mesajınız başarıyla gönderildi! En kısa sürede size döneceğiz.\",\r\n \"error\": \"Bir şeyler yanlış gitti. Lütfen tekrar deneyin.\"\r\n}\r\n"
|
|
41
41
|
}
|
|
42
42
|
],
|
|
43
43
|
"exports": {
|
|
@@ -18,25 +18,25 @@
|
|
|
18
18
|
"path": "contact-page-split/index.ts",
|
|
19
19
|
"type": "registry:index",
|
|
20
20
|
"target": "$modules$/contact-page-split/index.ts",
|
|
21
|
-
"content": "export * from './contact-page-split';\nexport { ContactPageSplit as default } from './contact-page-split';\n"
|
|
21
|
+
"content": "export * from './contact-page-split';\r\nexport { ContactPageSplit as default } from './contact-page-split';\r\n"
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
"path": "contact-page-split/contact-page-split.tsx",
|
|
25
25
|
"type": "registry:component",
|
|
26
26
|
"target": "$modules$/contact-page-split/contact-page-split.tsx",
|
|
27
|
-
"content": "import React, { useState } from \"react\";\nimport { useTranslation } from \"react-i18next\";\nimport { usePageTitle } from \"@/hooks/use-page-title\";\nimport { Mail, Phone, MapPin, Clock } from \"lucide-react\";\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 { cn } from \"@/lib/utils\";\nimport constants from \"@/constants/constants.json\";\n\ninterface ContactPageSplitProps {\n className?: string;\n}\n\nexport function ContactPageSplit({ className }: ContactPageSplitProps) {\n const { t } = useTranslation(\"contact-page-split\");\n usePageTitle({ title: t(\"pageTitle\", \"Contact Us\") });\n const apiService = useApiService();\n\n const [formData, setFormData] = useState({\n name: \"\",\n email: \"\",\n phone: \"\",\n message: \"\",\n });\n const [isSubmitting, setIsSubmitting] = useState(false);\n const [submitStatus, setSubmitStatus] = useState<\"idle\" | \"success\" | \"error\">(\"idle\");\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setIsSubmitting(true);\n setSubmitStatus(\"idle\");\n\n try {\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: \"message\", required: true },\n ],\n },\n constants.site.defaultLanguage\n );\n\n setSubmitStatus(\"success\");\n setFormData({ name: \"\", email: \"\", phone: \"\", message: \"\" });\n setTimeout(() => setSubmitStatus(\"idle\"), 5000);\n } catch {\n setSubmitStatus(\"error\");\n setTimeout(() => setSubmitStatus(\"idle\"), 5000);\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n setFormData((prev) => ({ ...prev, [e.target.name]: e.target.value }));\n };\n\n return (\n <Layout>\n <div className={cn(\"min-h-[calc(100vh-200px)] py-8 md:py-12\", className)}>\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4\">\n <div className=\"grid lg:grid-cols-2 h-full rounded-xl overflow-hidden shadow-lg\">\n {/* Left Side - Info & Image */}\n <div className=\"relative bg-primary text-primary-foreground p-8 lg:p-12 flex flex-col justify-center\">\n {/* Background Pattern */}\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]\" />\n\n <div className=\"relative z-10 max-w-lg\">\n <h1 className=\"text-3xl lg:text-4xl font-bold mb-4\">\n {t(\"title\", \"Let's Start a Conversation\")}\n </h1>\n <p className=\"text-primary-foreground/80 mb-8\">\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.\")}\n </p>\n\n <div className=\"space-y-6\">\n <div className=\"flex items-start gap-4\">\n <div className=\"w-10 h-10 rounded-full bg-primary-foreground/10 flex items-center justify-center flex-shrink-0\">\n <Mail className=\"h-5 w-5\" />\n </div>\n <div>\n <p className=\"font-semibold\">{t(\"emailLabel\", \"Email\")}</p>\n <p className=\"text-primary-foreground/70\">{constants.email || \"hello@example.com\"}</p>\n </div>\n </div>\n\n <div className=\"flex items-start gap-4\">\n <div className=\"w-10 h-10 rounded-full bg-primary-foreground/10 flex items-center justify-center flex-shrink-0\">\n <Phone className=\"h-5 w-5\" />\n </div>\n <div>\n <p className=\"font-semibold\">{t(\"phoneLabel\", \"Phone\")}</p>\n <p className=\"text-primary-foreground/70\">{constants.phone || \"+1 234 567 890\"}</p>\n </div>\n </div>\n\n <div className=\"flex items-start gap-4\">\n <div className=\"w-10 h-10 rounded-full bg-primary-foreground/10 flex items-center justify-center flex-shrink-0\">\n <MapPin className=\"h-5 w-5\" />\n </div>\n <div>\n <p className=\"font-semibold\">{t(\"addressLabel\", \"Address\")}</p>\n <p className=\"text-primary-foreground/70\">\n {constants.address?.line1 || \"123 Main Street\"}<br />\n {constants.address?.city || \"New York\"}, {constants.address?.country || \"USA\"}\n </p>\n </div>\n </div>\n\n <div className=\"flex items-start gap-4\">\n <div className=\"w-10 h-10 rounded-full bg-primary-foreground/10 flex items-center justify-center flex-shrink-0\">\n <Clock className=\"h-5 w-5\" />\n </div>\n <div>\n <p className=\"font-semibold\">{t(\"hoursLabel\", \"Business Hours\")}</p>\n <p className=\"text-primary-foreground/70\">{t(\"hours\", \"Mon - Fri: 9:00 AM - 6:00 PM\")}</p>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n {/* Right Side - Form */}\n <div className=\"p-8 lg:p-12 flex items-center justify-center bg-background\">\n <div className=\"w-full max-w-md\">\n <h2 className=\"text-2xl font-bold mb-2\">{t(\"formTitle\", \"Send us a message\")}</h2>\n <p className=\"text-muted-foreground mb-8\">\n {t(\"formSubtitle\", \"Fill out the form below and we'll get back to you as soon as possible.\")}\n </p>\n\n <form onSubmit={handleSubmit} className=\"space-y-5\">\n <div>\n <Label htmlFor=\"name\">{t(\"nameLabel\", \"Full Name\")} *</Label>\n <Input\n id=\"name\"\n name=\"name\"\n value={formData.name}\n onChange={handleChange}\n placeholder={t(\"namePlaceholder\", \"John Doe\")}\n required\n className=\"mt-1\"\n />\n </div>\n\n <div>\n <Label htmlFor=\"email\">{t(\"emailInputLabel\", \"Email\")} *</Label>\n <Input\n id=\"email\"\n name=\"email\"\n type=\"email\"\n value={formData.email}\n onChange={handleChange}\n placeholder={t(\"emailPlaceholder\", \"john@example.com\")}\n required\n className=\"mt-1\"\n />\n </div>\n\n <div>\n <Label htmlFor=\"phone\">{t(\"phoneInputLabel\", \"Phone\")}</Label>\n <Input\n id=\"phone\"\n name=\"phone\"\n type=\"tel\"\n value={formData.phone}\n onChange={handleChange}\n placeholder={t(\"phonePlaceholder\", \"+1 234 567 890\")}\n className=\"mt-1\"\n />\n </div>\n\n <div>\n <Label htmlFor=\"message\">{t(\"messageLabel\", \"Message\")} *</Label>\n <Textarea\n id=\"message\"\n name=\"message\"\n value={formData.message}\n onChange={handleChange}\n placeholder={t(\"messagePlaceholder\", \"Tell us about your project...\")}\n required\n rows={5}\n className=\"mt-1 resize-none\"\n />\n </div>\n\n {submitStatus === \"success\" && (\n <div className=\"p-4 bg-green-500/10 border border-green-500/30 rounded-lg\">\n <p className=\"text-green-600 dark:text-green-400 text-sm font-medium\">\n {t(\"success\", \"Message sent! We'll be in touch soon.\")}\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\", \"Something went wrong. Please try again.\")}\n </p>\n </div>\n )}\n\n <Button type=\"submit\" size=\"lg\" className=\"w-full\" disabled={isSubmitting}>\n {isSubmitting ? t(\"sending\", \"Sending...\") : t(\"submit\", \"Send Message\")}\n </Button>\n </form>\n </div>\n </div>\n </div>\n </div>\n </div>\n </Layout>\n );\n}\n\nexport default ContactPageSplit;\n"
|
|
27
|
+
"content": "import React, { useState } from \"react\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { usePageTitle } from \"@/hooks/use-page-title\";\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 usePageTitle({ title: t(\"pageTitle\", \"Contact Us\") });\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-[calc(100vh-200px)] py-8 md:py-12\", className)}>\r\n <div className=\"w-full max-w-[var(--container-max-width)] mx-auto px-4\">\r\n <div className=\"grid lg:grid-cols-2 h-full rounded-xl overflow-hidden shadow-lg\">\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 </div>\r\n </Layout>\r\n );\r\n}\r\n\r\nexport default ContactPageSplit;\r\n"
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
"path": "contact-page-split/lang/en.json",
|
|
31
31
|
"type": "registry:lang",
|
|
32
32
|
"target": "$modules$/contact-page-split/lang/en.json",
|
|
33
|
-
"content": "{\n \"pageTitle\": \"Contact Us\",\n \"title\": \"Let's Start a Conversation\",\n \"subtitle\": \"This welcoming message sets the tone for visitor communication. Explain why they should contact you, what kind of help you can provide, or your typical response time. Use Promake to create an inviting message that encourages engagement.\",\n \"emailLabel\": \"Email\",\n \"phoneLabel\": \"Phone\",\n \"addressLabel\": \"Address\",\n \"hoursLabel\": \"Hours\",\n \"hours\": \"Mon - Fri: 9:00 AM - 6:00 PM\",\n \"formTitle\": \"Send us a message\",\n \"formSubtitle\": \"Fill out the form below and we'll get back to you as soon as possible.\",\n \"nameLabel\": \"Full Name\",\n \"namePlaceholder\": \"John Doe\",\n \"emailInputLabel\": \"Email\",\n \"emailPlaceholder\": \"john@example.com\",\n \"phoneInputLabel\": \"Phone\",\n \"phonePlaceholder\": \"+1 234 567 890\",\n \"messageLabel\": \"Message\",\n \"messagePlaceholder\": \"Tell us about your project...\",\n \"submit\": \"Send Message\",\n \"sending\": \"Sending...\",\n \"success\": \"Message sent! We'll be in touch soon.\",\n \"error\": \"Something went wrong. Please try again.\"\n}\n"
|
|
33
|
+
"content": "{\r\n \"pageTitle\": \"Contact Us\",\r\n \"title\": \"Let's Start a Conversation\",\r\n \"subtitle\": \"This welcoming message sets the tone for visitor communication. Explain why they should contact you, what kind of help you can provide, or your typical response time. Use Promake to create an inviting message that encourages engagement.\",\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
34
|
},
|
|
35
35
|
{
|
|
36
36
|
"path": "contact-page-split/lang/tr.json",
|
|
37
37
|
"type": "registry:lang",
|
|
38
38
|
"target": "$modules$/contact-page-split/lang/tr.json",
|
|
39
|
-
"content": "{\n \"pageTitle\": \"İletişim\",\n \"title\": \"Bir Sohbet Başlatalım\",\n \"subtitle\": \"Bu karşılama mesajı ziyaretçi iletişimi için tonu belirler. Neden sizinle iletişime geçmeleri gerektiğini, ne tür yardım sağlayabileceğinizi veya tipik yanıt sürenizi açıklayın. Promake ile etkileşimi teşvik eden davetkar bir mesaj oluşturun.\",\n \"emailLabel\": \"E-posta\",\n \"phoneLabel\": \"Telefon\",\n \"addressLabel\": \"Adres\",\n \"hoursLabel\": \"Çalışma Saatleri\",\n \"hours\": \"Pazartesi - Cuma: 09:00 - 18:00\",\n \"formTitle\": \"Bize mesaj gönderin\",\n \"formSubtitle\": \"Aşağıdaki formu doldurun, en kısa sürede size döneceğiz.\",\n \"nameLabel\": \"Ad Soyad\",\n \"namePlaceholder\": \"Ahmet Yılmaz\",\n \"emailInputLabel\": \"E-posta\",\n \"emailPlaceholder\": \"ahmet@ornek.com\",\n \"phoneInputLabel\": \"Telefon\",\n \"phonePlaceholder\": \"+90 532 123 4567\",\n \"messageLabel\": \"Mesaj\",\n \"messagePlaceholder\": \"Projeniz hakkında bize bilgi verin...\",\n \"submit\": \"Mesaj Gönder\",\n \"sending\": \"Gönderiliyor...\",\n \"success\": \"Mesaj gönderildi! En kısa sürede iletişime geçeceğiz.\",\n \"error\": \"Bir şeyler yanlış gitti. Lütfen tekrar deneyin.\"\n}\n"
|
|
39
|
+
"content": "{\r\n \"pageTitle\": \"İletişim\",\r\n \"title\": \"Bir Sohbet Başlatalım\",\r\n \"subtitle\": \"Bu karşılama mesajı ziyaretçi iletişimi için tonu belirler. Neden sizinle iletişime geçmeleri gerektiğini, ne tür yardım sağlayabileceğinizi veya tipik yanıt sürenizi açıklayın. Promake ile etkileşimi teşvik eden davetkar bir mesaj oluşturun.\",\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
40
|
}
|
|
41
41
|
],
|
|
42
42
|
"exports": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"path": "contact-page/index.ts",
|
|
17
17
|
"type": "registry:index",
|
|
18
18
|
"target": "$modules$/contact-page/index.ts",
|
|
19
|
-
"content": "export * from './contact-page';\nexport { ContactPage as default } from './contact-page';\n"
|
|
19
|
+
"content": "export * from './contact-page';\r\nexport { ContactPage as default } from './contact-page';\r\n"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
"path": "contact-page/contact-page.tsx",
|
|
@@ -28,13 +28,13 @@
|
|
|
28
28
|
"path": "contact-page/lang/en.json",
|
|
29
29
|
"type": "registry:lang",
|
|
30
30
|
"target": "$modules$/contact-page/lang/en.json",
|
|
31
|
-
"content": "{\n \"title\": \"Contact Us\",\n \"getInTouch\": \"Get in Touch\",\n \"emailUs\": \"Email Us\",\n \"callUs\": \"Call Us\",\n \"visitUs\": \"Visit Us\",\n \"businessHours\": \"Hours\",\n \"sendMessage\": \"Send us a Message\",\n \"formNotAvailable\": \"Form is not available at the moment.\",\n \"fullName\": \"Full Name\",\n \"emailAddress\": \"Email Address\",\n \"phoneNumber\": \"Phone Number\",\n \"subject\": \"Subject\",\n \"message\": \"Message\",\n \"submit\": \"Send Message\",\n \"sending\": \"Sending...\",\n \"success\": \"Thank you for your message! We will get back to you soon.\",\n \"error\": \"Failed to send message. Please try again later.\",\n \"description\": \"Have a question or need support? We're here to help and typically respond within 24 hours.\",\n \"email\": \"Email\",\n \"phone\": \"Phone\",\n \"address\": \"Address\",\n \"fullNamePlaceholder\": \"Your full name\",\n \"emailPlaceholder\": \"your@email.com\",\n \"phonePlaceholder\": \"+1 (555) 123-4567\",\n \"subjectPlaceholder\": \"What is this regarding?\",\n \"messagePlaceholder\": \"Tell us how we can help you...\",\n \"loading\": \"Loading contact information...\",\n \"emailResponse\": \"We typically respond within 24 hours\",\n \"needSupport\": \"Need Support?\",\n \"supportDescription\": \"For technical support or general inquiries, contact our dedicated support team:\",\n \"supportEmail\": \"Support Email\",\n \"monday_friday\": \"Monday - Friday\",\n \"saturday\": \"Saturday\",\n \"sunday\": \"Sunday\",\n \"closed\": \"Closed\",\n \"am\": \"AM\",\n \"pm\": \"PM\"\n}"
|
|
31
|
+
"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\": \"Have a question or need support? We're here to help and typically respond within 24 hours.\",\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}"
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"path": "contact-page/lang/tr.json",
|
|
35
35
|
"type": "registry:lang",
|
|
36
36
|
"target": "$modules$/contact-page/lang/tr.json",
|
|
37
|
-
"content": "{\n \"title\": \"İletişim\",\n \"getInTouch\": \"Bize Ulaşın\",\n \"emailUs\": \"E-posta Gönderin\",\n \"callUs\": \"Bizi Arayın\",\n \"visitUs\": \"Bizi Ziyaret Edin\",\n \"businessHours\": \"Çalışma Saatleri\",\n \"sendMessage\": \"Bize Mesaj Gönderin\",\n \"formNotAvailable\": \"Form şu anda kullanılamıyor.\",\n \"fullName\": \"Ad Soyad\",\n \"emailAddress\": \"E-posta Adresi\",\n \"phoneNumber\": \"Telefon Numarası\",\n \"subject\": \"Konu\",\n \"message\": \"Mesaj\",\n \"submit\": \"Mesaj Gönder\",\n \"sending\": \"Gönderiliyor...\",\n \"success\": \"Mesajınız için teşekkürler! En kısa sürede size dönüş yapacağız.\",\n \"error\": \"Mesaj gönderilemedi. Lütfen tekrar deneyin.\",\n \"description\": \"İletişim seçenekleri ve müsaitlik bilgisi. Yanıt süreleri ve soru türlerini ekleyin.\",\n \"email\": \"E-posta\",\n \"phone\": \"Telefon\",\n \"address\": \"Adres\",\n \"fullNamePlaceholder\": \"Adınız ve soyadınız\",\n \"emailPlaceholder\": \"eposta@adresiniz.com\",\n \"phonePlaceholder\": \"+90 5XX XXX XX XX\",\n \"subjectPlaceholder\": \"Konu nedir?\",\n \"messagePlaceholder\": \"Size nasıl yardımcı olabiliriz...\",\n \"loading\": \"İletişim bilgileri yükleniyor...\",\n \"emailResponse\": \"Genellikle 24 saat içinde yanıt veririz\",\n \"needSupport\": \"Desteğe İhtiyacınız mı Var?\",\n \"supportDescription\": \"Teknik destek veya sipariş sorularınız için özel destek ekibimizle iletişime geçin:\",\n \"supportEmail\": \"Destek E-postası\",\n \"monday_friday\": \"Pazartesi - Cuma\",\n \"saturday\": \"Cumartesi\",\n \"sunday\": \"Pazar\",\n \"closed\": \"Kapalı\",\n \"am\": \"\",\n \"pm\": \"\"\n}"
|
|
37
|
+
"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\": \"İletişim seçenekleri ve müsaitlik bilgisi. Yanıt süreleri ve soru türlerini ekleyin.\",\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}"
|
|
38
38
|
}
|
|
39
39
|
],
|
|
40
40
|
"exports": {
|
|
@@ -10,25 +10,25 @@
|
|
|
10
10
|
"path": "content-section/index.ts",
|
|
11
11
|
"type": "registry:index",
|
|
12
12
|
"target": "$modules$/content-section/index.ts",
|
|
13
|
-
"content": "export * from './content-section';\n"
|
|
13
|
+
"content": "export * from './content-section';\r\n"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"path": "content-section/content-section.tsx",
|
|
17
17
|
"type": "registry:component",
|
|
18
18
|
"target": "$modules$/content-section/content-section.tsx",
|
|
19
|
-
"content": "import { Link } from \"react-router\";\nimport { ChevronRight } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\n\ninterface ContentSectionProps {\n image: string;\n imageAlt?: string;\n title: string;\n description: string;\n ctaText?: string;\n ctaLink?: string;\n grayscale?: boolean;\n className?: string;\n}\n\nexport function ContentSection({\n image,\n imageAlt,\n title,\n description,\n ctaText,\n ctaLink = \"#\",\n grayscale = false,\n className,\n}: ContentSectionProps) {\n\n return (\n <section className={cn(\"py-16 md:py-32\", className)}>\n <div className=\"mx-auto max-w-5xl space-y-8 px-6 md:space-y-12\">\n <img\n className={cn(\"rounded-lg w-full\", grayscale && \"grayscale\")}\n src={image}\n alt={imageAlt || title}\n loading=\"lazy\"\n />\n\n <div className=\"grid gap-6 md:grid-cols-2 md:gap-12\">\n <h2 className=\"text-3xl md:text-4xl font-medium leading-tight\">\n {title}\n </h2>\n <div className=\"space-y-6\">\n <p className=\"text-muted-foreground leading-relaxed\">\n {description}\n </p>\n\n {ctaText && (\n <Button asChild variant=\"secondary\" size=\"sm\" className=\"gap-1 pr-1.5\">\n <Link to={ctaLink}>\n <span>{ctaText}</span>\n <ChevronRight className=\"size-4\" />\n </Link>\n </Button>\n )}\n </div>\n </div>\n </div>\n </section>\n );\n}\n"
|
|
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
20
|
},
|
|
21
21
|
{
|
|
22
22
|
"path": "content-section/lang/en.json",
|
|
23
23
|
"type": "registry:lang",
|
|
24
24
|
"target": "$modules$/content-section/lang/en.json",
|
|
25
|
-
"content": "{\n \"learnMore\": \"Learn More\"\n}\n"
|
|
25
|
+
"content": "{\r\n \"learnMore\": \"Learn More\"\r\n}\r\n"
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"path": "content-section/lang/tr.json",
|
|
29
29
|
"type": "registry:lang",
|
|
30
30
|
"target": "$modules$/content-section/lang/tr.json",
|
|
31
|
-
"content": "{\n \"learnMore\": \"Daha Fazla\"\n}\n"
|
|
31
|
+
"content": "{\r\n \"learnMore\": \"Daha Fazla\"\r\n}\r\n"
|
|
32
32
|
}
|
|
33
33
|
],
|
|
34
34
|
"exports": {
|
|
@@ -13,25 +13,25 @@
|
|
|
13
13
|
"path": "cookie-consent/index.ts",
|
|
14
14
|
"type": "registry:index",
|
|
15
15
|
"target": "$modules$/cookie-consent/index.ts",
|
|
16
|
-
"content": "export { CookieConsent } from \"./cookie-consent\";\n"
|
|
16
|
+
"content": "export { CookieConsent } from \"./cookie-consent\";\r\n"
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
19
|
"path": "cookie-consent/cookie-consent.tsx",
|
|
20
20
|
"type": "registry:component",
|
|
21
21
|
"target": "$modules$/cookie-consent/cookie-consent.tsx",
|
|
22
|
-
"content": "import { useState, useEffect } from \"react\";\nimport { Link } from \"react-router\";\nimport { useTranslation } from \"react-i18next\";\nimport { X } from \"lucide-react\";\nimport { Button } from \"@/components/ui/button\";\nimport { cn } from \"@/lib/utils\";\nimport { motion, AnimatePresence } from \"motion/react\";\n\ninterface CookieConsentProps {\n className?: string;\n privacyPolicyUrl?: string;\n cookiePolicyUrl?: string;\n onAccept?: () => void;\n onDecline?: () => void;\n width?: \"full\" | \"compact\" | \"auto\";\n position?: \"left\" | \"right\" | \"center\";\n storageKey?: string;\n}\n\nconst DEFAULT_STORAGE_KEY = \"cookie-consent\";\n\nexport function CookieConsent({\n className,\n privacyPolicyUrl = \"/privacy\",\n cookiePolicyUrl = \"/cookies\",\n onAccept,\n onDecline,\n width = \"full\",\n position = \"center\",\n storageKey = DEFAULT_STORAGE_KEY,\n}: CookieConsentProps) {\n const { t } = useTranslation(\"cookie-consent\");\n const [isVisible, setIsVisible] = useState(false);\n const [isClosing, setIsClosing] = useState(false);\n\n useEffect(() => {\n const consent = localStorage.getItem(storageKey);\n if (!consent) {\n // Small delay for better UX\n const timer = setTimeout(() => setIsVisible(true), 1000);\n return () => clearTimeout(timer);\n }\n }, [storageKey]);\n\n const handleAccept = () => {\n localStorage.setItem(storageKey, \"accepted\");\n setIsClosing(true);\n setTimeout(() => {\n setIsVisible(false);\n onAccept?.();\n }, 300);\n };\n\n const handleDecline = () => {\n localStorage.setItem(storageKey, \"declined\");\n setIsClosing(true);\n setTimeout(() => {\n setIsVisible(false);\n onDecline?.();\n }, 300);\n };\n\n const handleClose = () => {\n setIsClosing(true);\n setTimeout(() => setIsVisible(false), 300);\n };\n\n if (!isVisible) return null;\n\n return (\n <AnimatePresence>\n {isVisible && (\n <motion.div\n initial={{ y: 100, opacity: 0 }}\n animate={{ y: isClosing ? 100 : 0, opacity: isClosing ? 0 : 1 }}\n exit={{ y: 100, opacity: 0 }}\n transition={{ type: \"spring\", damping: 25, stiffness: 300 }}\n className={cn(\n \"fixed bottom-0 z-50 p-4 md:p-6 left-0 right-0\",\n position === \"left\" && \"md:right-auto\",\n position === \"right\" && \"md:left-auto\",\n className\n )}\n >\n <div className={cn(\n \"w-full mx-auto\",\n width === \"full\" && \"max-w-[var(--container-max-width)]\",\n width === \"compact\" && \"md:max-w-md\",\n width === \"auto\" && \"md:w-auto\"\n )}>\n <div className=\"bg-card border border-border rounded-2xl shadow-2xl p-5 relative\">\n {/* Close button */}\n <button\n onClick={handleClose}\n className=\"absolute top-3 right-3 p-1 text-muted-foreground hover:text-foreground transition-colors\"\n aria-label={t(\"close\", \"Close\")}\n >\n <X className=\"h-4 w-4\" />\n </button>\n\n {/* Title & Description */}\n <div className=\"mb-4 pr-6\">\n <h3 className=\"text-base font-semibold text-foreground mb-1\">\n {t(\"title\", \"Cookie Notice\")}\n </h3>\n <p className=\"text-sm text-muted-foreground\">\n {t(\"description\", \"We use cookies to improve your experience.\")}{\" \"}\n <Link to={privacyPolicyUrl} className=\"text-primary hover:underline\">\n {t(\"privacyPolicy\", \"Privacy\")}\n </Link>\n {\" · \"}\n <Link to={cookiePolicyUrl} className=\"text-primary hover:underline\">\n {t(\"cookiePolicy\", \"Cookies\")}\n </Link>\n </p>\n </div>\n\n {/* Buttons */}\n <div className=\"flex flex-row gap-3\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleDecline}\n className=\"flex-1\"\n >\n {t(\"decline\", \"Decline\")}\n </Button>\n <Button\n size=\"sm\"\n onClick={handleAccept}\n className=\"flex-1\"\n >\n {t(\"accept\", \"Accept\")}\n </Button>\n </div>\n </div>\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n );\n}\n"
|
|
22
|
+
"content": "import { useState, useEffect } from \"react\";\r\nimport { Link } from \"react-router\";\r\nimport { useTranslation } from \"react-i18next\";\r\nimport { X } from \"lucide-react\";\r\nimport { Button } from \"@/components/ui/button\";\r\nimport { cn } from \"@/lib/utils\";\r\nimport { motion, AnimatePresence } from \"motion/react\";\r\n\r\ninterface CookieConsentProps {\r\n className?: string;\r\n privacyPolicyUrl?: string;\r\n cookiePolicyUrl?: string;\r\n onAccept?: () => void;\r\n onDecline?: () => void;\r\n width?: \"full\" | \"compact\" | \"auto\";\r\n position?: \"left\" | \"right\" | \"center\";\r\n storageKey?: string;\r\n}\r\n\r\nconst DEFAULT_STORAGE_KEY = \"cookie-consent\";\r\n\r\nexport function CookieConsent({\r\n className,\r\n privacyPolicyUrl = \"/privacy\",\r\n cookiePolicyUrl = \"/cookies\",\r\n onAccept,\r\n onDecline,\r\n width = \"full\",\r\n position = \"center\",\r\n storageKey = DEFAULT_STORAGE_KEY,\r\n}: CookieConsentProps) {\r\n const { t } = useTranslation(\"cookie-consent\");\r\n const [isVisible, setIsVisible] = useState(false);\r\n const [isClosing, setIsClosing] = useState(false);\r\n\r\n useEffect(() => {\r\n const consent = localStorage.getItem(storageKey);\r\n if (!consent) {\r\n // Small delay for better UX\r\n const timer = setTimeout(() => setIsVisible(true), 1000);\r\n return () => clearTimeout(timer);\r\n }\r\n }, [storageKey]);\r\n\r\n const handleAccept = () => {\r\n localStorage.setItem(storageKey, \"accepted\");\r\n setIsClosing(true);\r\n setTimeout(() => {\r\n setIsVisible(false);\r\n onAccept?.();\r\n }, 300);\r\n };\r\n\r\n const handleDecline = () => {\r\n localStorage.setItem(storageKey, \"declined\");\r\n setIsClosing(true);\r\n setTimeout(() => {\r\n setIsVisible(false);\r\n onDecline?.();\r\n }, 300);\r\n };\r\n\r\n const handleClose = () => {\r\n setIsClosing(true);\r\n setTimeout(() => setIsVisible(false), 300);\r\n };\r\n\r\n if (!isVisible) return null;\r\n\r\n return (\r\n <AnimatePresence>\r\n {isVisible && (\r\n <motion.div\r\n initial={{ y: 100, opacity: 0 }}\r\n animate={{ y: isClosing ? 100 : 0, opacity: isClosing ? 0 : 1 }}\r\n exit={{ y: 100, opacity: 0 }}\r\n transition={{ type: \"spring\", damping: 25, stiffness: 300 }}\r\n className={cn(\r\n \"fixed bottom-0 z-50 p-4 md:p-6 left-0 right-0\",\r\n position === \"left\" && \"md:right-auto\",\r\n position === \"right\" && \"md:left-auto\",\r\n className\r\n )}\r\n >\r\n <div className={cn(\r\n \"w-full mx-auto\",\r\n width === \"full\" && \"max-w-[var(--container-max-width)]\",\r\n width === \"compact\" && \"md:max-w-md\",\r\n width === \"auto\" && \"md:w-auto\"\r\n )}>\r\n <div className=\"bg-card border border-border rounded-2xl shadow-2xl p-5 relative\">\r\n {/* Close button */}\r\n <button\r\n onClick={handleClose}\r\n className=\"absolute top-3 right-3 p-1 text-muted-foreground hover:text-foreground transition-colors\"\r\n aria-label={t(\"close\", \"Close\")}\r\n >\r\n <X className=\"h-4 w-4\" />\r\n </button>\r\n\r\n {/* Title & Description */}\r\n <div className=\"mb-4 pr-6\">\r\n <h3 className=\"text-base font-semibold text-foreground mb-1\">\r\n {t(\"title\", \"Cookie Notice\")}\r\n </h3>\r\n <p className=\"text-sm text-muted-foreground\">\r\n {t(\"description\", \"We use cookies to improve your experience.\")}{\" \"}\r\n <Link to={privacyPolicyUrl} className=\"text-primary hover:underline\">\r\n {t(\"privacyPolicy\", \"Privacy\")}\r\n </Link>\r\n {\" · \"}\r\n <Link to={cookiePolicyUrl} className=\"text-primary hover:underline\">\r\n {t(\"cookiePolicy\", \"Cookies\")}\r\n </Link>\r\n </p>\r\n </div>\r\n\r\n {/* Buttons */}\r\n <div className=\"flex flex-row gap-3\">\r\n <Button\r\n variant=\"outline\"\r\n size=\"sm\"\r\n onClick={handleDecline}\r\n className=\"flex-1\"\r\n >\r\n {t(\"decline\", \"Decline\")}\r\n </Button>\r\n <Button\r\n size=\"sm\"\r\n onClick={handleAccept}\r\n className=\"flex-1\"\r\n >\r\n {t(\"accept\", \"Accept\")}\r\n </Button>\r\n </div>\r\n </div>\r\n </div>\r\n </motion.div>\r\n )}\r\n </AnimatePresence>\r\n );\r\n}\r\n"
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
25
|
"path": "cookie-consent/lang/en.json",
|
|
26
26
|
"type": "registry:lang",
|
|
27
27
|
"target": "$modules$/cookie-consent/lang/en.json",
|
|
28
|
-
"content": "{\n \"title\": \"Cookie Notice\",\n \"description\": \"We use cookies to improve your experience.\",\n \"privacyPolicy\": \"Privacy\",\n \"cookiePolicy\": \"Cookies\",\n \"accept\": \"Accept\",\n \"decline\": \"Decline\",\n \"close\": \"Close\"\n}\n"
|
|
28
|
+
"content": "{\r\n \"title\": \"Cookie Notice\",\r\n \"description\": \"We use cookies to improve your experience.\",\r\n \"privacyPolicy\": \"Privacy\",\r\n \"cookiePolicy\": \"Cookies\",\r\n \"accept\": \"Accept\",\r\n \"decline\": \"Decline\",\r\n \"close\": \"Close\"\r\n}\r\n"
|
|
29
29
|
},
|
|
30
30
|
{
|
|
31
31
|
"path": "cookie-consent/lang/tr.json",
|
|
32
32
|
"type": "registry:lang",
|
|
33
33
|
"target": "$modules$/cookie-consent/lang/tr.json",
|
|
34
|
-
"content": "{\n \"title\": \"Gizliliğinize değer veriyoruz\",\n \"description\": \"Göz atma deneyiminizi geliştirmek, kişiselleştirilmiş içerik sunmak ve trafiğimizi analiz etmek için çerezler kullanıyoruz. \\\"Tümünü Kabul Et\\\"e tıklayarak çerez kullanımımıza onay verirsiniz.\",\n \"privacyPolicy\": \"Gizlilik Politikası\",\n \"cookiePolicy\": \"Çerez Politikası\",\n \"accept\": \"Tümünü Kabul Et\",\n \"decline\": \"Reddet\",\n \"customize\": \"Özelleştir\",\n \"close\": \"Kapat\"\n}\n"
|
|
34
|
+
"content": "{\r\n \"title\": \"Gizliliğinize değer veriyoruz\",\r\n \"description\": \"Göz atma deneyiminizi geliştirmek, kişiselleştirilmiş içerik sunmak ve trafiğimizi analiz etmek için çerezler kullanıyoruz. \\\"Tümünü Kabul Et\\\"e tıklayarak çerez kullanımımıza onay verirsiniz.\",\r\n \"privacyPolicy\": \"Gizlilik Politikası\",\r\n \"cookiePolicy\": \"Çerez Politikası\",\r\n \"accept\": \"Tümünü Kabul Et\",\r\n \"decline\": \"Reddet\",\r\n \"customize\": \"Özelleştir\",\r\n \"close\": \"Kapat\"\r\n}\r\n"
|
|
35
35
|
}
|
|
36
36
|
],
|
|
37
37
|
"exports": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"path": "cookies-page/index.ts",
|
|
17
17
|
"type": "registry:index",
|
|
18
18
|
"target": "$modules$/cookies-page/index.ts",
|
|
19
|
-
"content": "export * from './cookies-page';\nexport { CookiesPage as default } from './cookies-page';\n"
|
|
19
|
+
"content": "export * from './cookies-page';\r\nexport { CookiesPage as default } from './cookies-page';\r\n"
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
22
|
"path": "cookies-page/cookies-page.tsx",
|
|
@@ -28,13 +28,13 @@
|
|
|
28
28
|
"path": "cookies-page/lang/en.json",
|
|
29
29
|
"type": "registry:lang",
|
|
30
30
|
"target": "$modules$/cookies-page/lang/en.json",
|
|
31
|
-
"content": "{\n \"title\": \"Cookie Policy\",\n \"lastUpdated\": \"Last Updated\",\n \"updateDate\": \"January 2026\",\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.\",\n \"whatTitle\": \"What Are Cookies?\",\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.\",\n \"typesTitle\": \"Types of Cookies We Use\",\n \"essentialTitle\": \"Essential Cookies\",\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.\",\n \"analyticsTitle\": \"Analytics Cookies\",\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.\",\n \"functionalTitle\": \"Functional Cookies\",\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.\",\n \"marketingTitle\": \"Marketing Cookies\",\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.\",\n \"managementTitle\": \"Managing Your Cookie Preferences\",\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.\",\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.\"\n}\n"
|
|
31
|
+
"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"
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"path": "cookies-page/lang/tr.json",
|
|
35
35
|
"type": "registry:lang",
|
|
36
36
|
"target": "$modules$/cookies-page/lang/tr.json",
|
|
37
|
-
"content": "{\n \"title\": \"Çerez Politikası\",\n \"lastUpdated\": \"Son Güncelleme\",\n \"updateDate\": \"Ocak 2026\",\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.\",\n \"whatTitle\": \"Çerez Nedir?\",\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.\",\n \"typesTitle\": \"Kullandığımız Çerez Türleri\",\n \"essentialTitle\": \"Temel Çerezler\",\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.\",\n \"analyticsTitle\": \"Analitik Çerezler\",\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.\",\n \"functionalTitle\": \"İşlevsel Çerezler\",\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.\",\n \"marketingTitle\": \"Pazarlama Çerezleri\",\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.\",\n \"managementTitle\": \"Çerez Tercihlerinizi Yönetme\",\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.\",\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.\"\n}\n"
|
|
37
|
+
"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"
|
|
38
38
|
}
|
|
39
39
|
],
|
|
40
40
|
"exports": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"path": "cta-section/index.ts",
|
|
11
11
|
"type": "registry:index",
|
|
12
12
|
"target": "$modules$/cta-section/index.ts",
|
|
13
|
-
"content": "export * from './cta-section';\n"
|
|
13
|
+
"content": "export * from './cta-section';\r\n"
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
"path": "cta-section/cta-section.tsx",
|
|
@@ -22,13 +22,13 @@
|
|
|
22
22
|
"path": "cta-section/lang/en.json",
|
|
23
23
|
"type": "registry:lang",
|
|
24
24
|
"target": "$modules$/cta-section/lang/en.json",
|
|
25
|
-
"content": "{\n \"title\": \"Ready to Start Your Project?\",\n \"description\": \"Join thousands of satisfied customers. Start your free trial today and see the difference.\",\n \"primaryButton\": \"Get Free Quote\",\n \"secondaryButton\": \"Learn About Us\"\n}"
|
|
25
|
+
"content": "{\r\n \"title\": \"Ready to Start Your Project?\",\r\n \"description\": \"Join thousands of satisfied customers. Start your free trial today and see the difference.\",\r\n \"primaryButton\": \"Get Free Quote\",\r\n \"secondaryButton\": \"Learn About Us\"\r\n}"
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
"path": "cta-section/lang/tr.json",
|
|
29
29
|
"type": "registry:lang",
|
|
30
30
|
"target": "$modules$/cta-section/lang/tr.json",
|
|
31
|
-
"content": "{\n \"title\": \"Projenizi Başlatmaya Hazır mısınız?\",\n \"description\": \"Binlerce memnun müşteriye katılın. Ücretsiz denemenizi bugün başlatın ve farkı görün.\",\n \"primaryButton\": \"Ücretsiz Teklif Al\",\n \"secondaryButton\": \"Hakkımızda\"\n}"
|
|
31
|
+
"content": "{\r\n \"title\": \"Projenizi Başlatmaya Hazır mısınız?\",\r\n \"description\": \"Binlerce memnun müşteriye katılın. Ücretsiz denemenizi bugün başlatın ve farkı görün.\",\r\n \"primaryButton\": \"Ücretsiz Teklif Al\",\r\n \"secondaryButton\": \"Hakkımızda\"\r\n}"
|
|
32
32
|
}
|
|
33
33
|
],
|
|
34
34
|
"exports": {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Reset Password Page
|
|
2
|
+
|
|
3
|
+
Split-screen password reset page with form on the left and full-height image on the right. Features new password input with confirmation, validates reset code from URL. Clean minimal design with API integration and responsive layout.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
| Target | Type |
|
|
8
|
+
|--------|------|
|
|
9
|
+
| `$modules$/reset-password-page/index.ts` | index |
|
|
10
|
+
| `$modules$/reset-password-page/reset-password-page.tsx` | page |
|
|
11
|
+
| `$modules$/reset-password-page/lang/en.json` | lang |
|
|
12
|
+
| `$modules$/reset-password-page/lang/tr.json` | lang |
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
import ResetPasswordPage from '@/modules/reset-password-page';
|
|
18
|
+
|
|
19
|
+
<ResetPasswordPage
|
|
20
|
+
image="/images/reset-bg.jpg"
|
|
21
|
+
/>
|
|
22
|
+
|
|
23
|
+
• Installed at: src/modules/reset-password-page/
|
|
24
|
+
• Customize text: src/modules/reset-password-page/lang/*.json
|
|
25
|
+
• Uses customerClient.auth.resetPassword() for API
|
|
26
|
+
• Expects ?code= URL parameter from email link
|
|
27
|
+
• Add to your router as a page component
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Dependencies
|
|
31
|
+
|
|
32
|
+
This component requires:
|
|
33
|
+
- `button`
|
|
34
|
+
- `input`
|
|
35
|
+
- `auth`
|
|
36
|
+
- `api`
|