From b4e06b641d9c926c6706225b510d83f6c305a6d3 Mon Sep 17 00:00:00 2001 From: Amirhossein Khalili Date: Sun, 7 Jun 2026 12:49:53 +0330 Subject: [PATCH] feat(about): add contact section --- src/content/about.json | 86 ++++++++++++++++++++++ src/pages/About.tsx | 163 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 249 insertions(+) diff --git a/src/content/about.json b/src/content/about.json index 8acc375..182f0ce 100644 --- a/src/content/about.json +++ b/src/content/about.json @@ -64,6 +64,49 @@ "Project access and user roles help limit what each person can see or use.", "Exports and logs are designed to make review easier, not to hide important details." ], + "contact": { + "eyebrow": "Contact", + "title": "Need help or want to talk about Qlockify?", + "description": "Send a note or reach out through the support channels below. The form opens an email draft with your message so you can review it before sending.", + "formTitle": "Send a note", + "fields": { + "firstName": "First name", + "lastName": "Last name", + "email": "Email", + "mobile": "Mobile", + "message": "Message" + }, + "placeholders": { + "firstName": "Your first name", + "lastName": "Your last name", + "email": "you@example.com", + "mobile": "09...", + "message": "Tell us what you need help with..." + }, + "submit": "Prepare email", + "channels": [ + { + "label": "Telegram support", + "value": "qlockify_support", + "href": "https://t.me/qlockify_support" + }, + { + "label": "Telegram channel", + "value": "qlockify", + "href": "https://t.me/qlockify" + }, + { + "label": "Support email", + "value": "qlockify@gmail.com", + "href": "mailto:qlockify@gmail.com" + }, + { + "label": "Mobile (message or call)", + "value": "09938228438", + "href": "tel:09938228438" + } + ] + }, "cta": { "title": "Start with one workspace and make time easier to explain.", "description": "Open Qlockify, track a real workday, and compare the report with the way your team reviews work today.", @@ -135,6 +178,49 @@ "دسترسی پروژه و نقش کاربران کمک می‌کند هر فرد فقط چیزی را ببیند یا استفاده کند که باید.", "خروجی‌ها و لاگ‌ها برای ساده‌تر کردن بررسی طراحی شده‌اند، نه برای پنهان کردن جزئیات مهم." ], + "contact": { + "eyebrow": "تماس", + "title": "کمک می‌خواهید یا می‌خواهید درباره Qlockify صحبت کنیم؟", + "description": "یک پیام بفرستید یا از مسیرهای پشتیبانی زیر با ما در ارتباط باشید. فرم یک پیش‌نویس ایمیل با پیام شما آماده می‌کند تا قبل از ارسال آن را بررسی کنید.", + "formTitle": "ارسال پیام", + "fields": { + "firstName": "نام", + "lastName": "نام خانوادگی", + "email": "ایمیل", + "mobile": "موبایل", + "message": "پیام" + }, + "placeholders": { + "firstName": "نام شما", + "lastName": "نام خانوادگی شما", + "email": "you@example.com", + "mobile": "09...", + "message": "بگویید برای چه چیزی به کمک نیاز دارید..." + }, + "submit": "آماده‌سازی ایمیل", + "channels": [ + { + "label": "پشتیبانی تلگرام", + "value": "qlockify_support", + "href": "https://t.me/qlockify_support" + }, + { + "label": "کانال تلگرام", + "value": "qlockify", + "href": "https://t.me/qlockify" + }, + { + "label": "ایمیل پشتیبانی", + "value": "qlockify@gmail.com", + "href": "mailto:qlockify@gmail.com" + }, + { + "label": "موبایل (پیام یا تماس)", + "value": "09938228438", + "href": "tel:09938228438" + } + ] + }, "cta": { "title": "با یک ورک‌اسپیس شروع کنید و توضیح زمان را ساده‌تر کنید.", "description": "Qlockify را باز کنید، یک روز کاری واقعی را ثبت کنید و گزارش آن را با روش فعلی مرور کار در تیم مقایسه کنید.", diff --git a/src/pages/About.tsx b/src/pages/About.tsx index 08e9a44..0aead4c 100644 --- a/src/pages/About.tsx +++ b/src/pages/About.tsx @@ -1,7 +1,9 @@ +import { useState, type FormEvent } from "react" import { Link, useNavigate } from "react-router-dom" import { ArrowLeft, ArrowRight, + AtSign, BarChart3, CheckCircle2, Command, @@ -9,7 +11,11 @@ import { Globe2, Layers3, LockKeyhole, + Mail, + MessageCircle, Moon, + Phone, + Send, ShieldCheck, Sparkles, Sun, @@ -19,6 +25,8 @@ import { } from "lucide-react" import { Button } from "../components/ui/button" +import { Input } from "../components/ui/input" +import { TextAreaInput } from "../components/ui/TextAreaInput" import { useTheme } from "../components/ThemeProvider" import { useTranslation } from "../hooks/useTranslation" import aboutContent from "../content/about.json" @@ -29,11 +37,19 @@ type AboutContent = typeof aboutContent.en const sectionIcons = [Sparkles, ShieldCheck, Layers3] const principleIcons = [TimerReset, Waypoints, BarChart3] const capabilityIcons = [TimerReset, Users, FileText, LockKeyhole] +const contactIcons = [MessageCircle, MessageCircle, Mail, Phone] export default function About() { const navigate = useNavigate() const { t, lang, setLanguage } = useTranslation() const { theme, setTheme } = useTheme() + const [contactForm, setContactForm] = useState({ + firstName: "", + lastName: "", + email: "", + mobile: "", + message: "", + }) const content = aboutContent[lang] as AboutContent const isAuthenticated = typeof window !== "undefined" && !!localStorage.getItem("accessToken") @@ -42,6 +58,27 @@ export default function About() { (theme === "system" && document.documentElement.classList.contains("dark")) const ctaTarget = isAuthenticated ? "/timesheet" : "/auth" + const updateContactField = (field: keyof typeof contactForm, value: string) => { + setContactForm((current) => ({ ...current, [field]: value })) + } + + const submitContactForm = (event: FormEvent) => { + event.preventDefault() + const subject = encodeURIComponent("Qlockify contact request") + const body = encodeURIComponent( + [ + `First name: ${contactForm.firstName}`, + `Last name: ${contactForm.lastName}`, + `Email: ${contactForm.email}`, + `Mobile: ${contactForm.mobile}`, + "", + "Message:", + contactForm.message, + ].join("\n"), + ) + window.location.href = `mailto:qlockify@gmail.com?subject=${subject}&body=${body}` + } + return (
@@ -291,6 +328,132 @@ export default function About() {
+
+
+
+ {content.contact.eyebrow} +
+

+ {content.contact.title} +

+

+ {content.contact.description} +

+ +
+ {content.contact.channels.map((channel, index) => { + const Icon = contactIcons[index] ?? AtSign + + return ( + + + + + + + + {channel.label} + + + {channel.value} + + + + {lang === "fa" ? ( + + ) : ( + + )} + + ) + })} +
+
+ +
+
+ + + +

+ {content.contact.formTitle} +

+
+ +
+ + + + +
+ + + + +
+
+