diff --git a/src/content/about.json b/src/content/about.json new file mode 100644 index 0000000..8acc375 --- /dev/null +++ b/src/content/about.json @@ -0,0 +1,144 @@ +{ + "en": { + "eyebrow": "About Qlockify", + "hero": { + "title": "A focused operating layer for time, work, and accountability.", + "accent": "Qlockify turns daily work into context your team can trust.", + "description": "Qlockify is built for teams that need more than a stopwatch. It connects time entries to workspaces, projects, clients, tags, rates, exports, and activity logs so time becomes useful operational data." + }, + "sections": [ + { + "title": "Why it exists", + "description": "Most teams lose context between the moment work happens and the moment reports are reviewed. Qlockify keeps that context attached from the first timer click to the final exported report." + }, + { + "title": "What it protects", + "description": "The product is designed to reduce missing billable work, unclear project history, manual spreadsheet cleanup, and undocumented workspace changes." + }, + { + "title": "How it feels", + "description": "The interface stays minimal because time tracking should not become another heavy workflow. Teams can record work quickly while managers still receive structured, reviewable data." + } + ], + "principles": [ + { + "title": "Capture first", + "description": "Recording work should be fast enough to happen at the source, with project and billing context attached immediately." + }, + { + "title": "Explain every change", + "description": "Workspace roles, rates, access changes, and report actions should remain visible instead of disappearing into chat or memory." + }, + { + "title": "Make reports usable", + "description": "Reports should be ready for review, export, and decision-making without rebuilding them in spreadsheets." + } + ], + "capabilities": [ + { + "title": "Time tracking", + "description": "Run timers, adjust historical entries, and keep work tied to the correct project, client, and tags." + }, + { + "title": "Workspace control", + "description": "Manage members, roles, project access, and rates without making everyday users deal with unnecessary complexity." + }, + { + "title": "Operational reports", + "description": "Review daily summaries, project distribution, billable work, and exportable reports for management or client review." + }, + { + "title": "Activity history", + "description": "Keep a clear trail of important actions so teams can understand what changed and when." + } + ], + "audience": [ + "Agencies", + "Consulting teams", + "Product teams", + "Operations teams", + "Client-service businesses" + ], + "trust": [ + "Data is organized around workspaces so each team can keep its own operational context.", + "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." + ], + "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.", + "button": "Open Qlockify" + } + }, + "fa": { + "eyebrow": "درباره Qlockify", + "hero": { + "title": "یک لایه عملیاتی متمرکز برای زمان، کار و پاسخ‌گویی.", + "accent": "Qlockify کار روزانه را به داده‌ای تبدیل می‌کند که تیم بتواند به آن اعتماد کند.", + "description": "Qlockify برای تیم‌هایی ساخته شده که فقط یک تایمر ساده نمی‌خواهند. این محصول ورودی‌های زمان را به ورک‌اسپیس، پروژه، مشتری، تگ، نرخ، خروجی گزارش و لاگ فعالیت‌ها وصل می‌کند تا زمان به داده عملیاتی قابل استفاده تبدیل شود." + }, + "sections": [ + { + "title": "چرا ساخته شده است", + "description": "بیشتر تیم‌ها بین لحظه انجام کار و زمان مرور گزارش‌ها، بستر و جزئیات مهم را از دست می‌دهند. Qlockify این بستر را از اولین کلیک تایمر تا گزارش خروجی نهایی نگه می‌دارد." + }, + { + "title": "چه چیزی را حفظ می‌کند", + "description": "محصول برای کاهش کارکرد ثبت‌نشده، تاریخچه نامشخص پروژه، پاک‌سازی دستی فایل‌های گزارش و تغییرات ثبت‌نشده در ورک‌اسپیس طراحی شده است." + }, + { + "title": "چه حسی دارد", + "description": "رابط کاربری مینیمال می‌ماند، چون ردیابی زمان نباید خودش به یک فرایند سنگین تبدیل شود. تیم می‌تواند سریع کار را ثبت کند و مدیر همچنان داده ساختارمند و قابل بررسی داشته باشد." + } + ], + "principles": [ + { + "title": "اول ثبت دقیق", + "description": "ثبت کار باید آن‌قدر سریع باشد که در همان لحظه انجام شود و پروژه و بستر مالی همان ابتدا به آن وصل شود." + }, + { + "title": "هر تغییر قابل توضیح", + "description": "نقش‌ها، نرخ‌ها، دسترسی پروژه‌ها و عملیات گزارش باید قابل مشاهده بمانند، نه این‌که در چت یا حافظه افراد گم شوند." + }, + { + "title": "گزارش قابل استفاده", + "description": "گزارش باید برای بررسی، خروجی گرفتن و تصمیم‌گیری آماده باشد، بدون این‌که دوباره در فایل‌های اکسل ساخته شود." + } + ], + "capabilities": [ + { + "title": "ردیابی زمان", + "description": "تایمر اجرا کنید، ورودی‌های گذشته را اصلاح کنید و کار را به پروژه، مشتری و تگ درست وصل نگه دارید." + }, + { + "title": "کنترل ورک‌اسپیس", + "description": "اعضا، نقش‌ها، دسترسی پروژه‌ها و نرخ‌ها را مدیریت کنید، بدون این‌که کاربران روزمره درگیر پیچیدگی اضافه شوند." + }, + { + "title": "گزارش عملیاتی", + "description": "خلاصه روزانه، توزیع پروژه‌ها، کارکرد قابل صورت‌حساب و گزارش‌های خروجی را برای مدیریت یا مرور مشتری بررسی کنید." + }, + { + "title": "تاریخچه فعالیت‌ها", + "description": "رد روشنی از عملیات مهم نگه دارید تا تیم بداند چه چیزی، چه زمانی و توسط چه کسی تغییر کرده است." + } + ], + "audience": [ + "آژانس‌ها", + "تیم‌های مشاوره", + "تیم‌های محصول", + "تیم‌های عملیات", + "کسب‌وکارهای مشتری‌محور" + ], + "trust": [ + "داده‌ها حول ورک‌اسپیس سازمان‌دهی می‌شوند تا هر تیم بستر عملیاتی خودش را داشته باشد.", + "دسترسی پروژه و نقش کاربران کمک می‌کند هر فرد فقط چیزی را ببیند یا استفاده کند که باید.", + "خروجی‌ها و لاگ‌ها برای ساده‌تر کردن بررسی طراحی شده‌اند، نه برای پنهان کردن جزئیات مهم." + ], + "cta": { + "title": "با یک ورک‌اسپیس شروع کنید و توضیح زمان را ساده‌تر کنید.", + "description": "Qlockify را باز کنید، یک روز کاری واقعی را ثبت کنید و گزارش آن را با روش فعلی مرور کار در تیم مقایسه کنید.", + "button": "باز کردن Qlockify" + } + } +} diff --git a/src/pages/About.tsx b/src/pages/About.tsx new file mode 100644 index 0000000..08e9a44 --- /dev/null +++ b/src/pages/About.tsx @@ -0,0 +1,323 @@ +import { Link, useNavigate } from "react-router-dom" +import { + ArrowLeft, + ArrowRight, + BarChart3, + CheckCircle2, + Command, + FileText, + Globe2, + Layers3, + LockKeyhole, + Moon, + ShieldCheck, + Sparkles, + Sun, + TimerReset, + Users, + Waypoints, +} from "lucide-react" + +import { Button } from "../components/ui/button" +import { useTheme } from "../components/ThemeProvider" +import { useTranslation } from "../hooks/useTranslation" +import aboutContent from "../content/about.json" +import { cn } from "../lib/utils" + +type AboutContent = typeof aboutContent.en + +const sectionIcons = [Sparkles, ShieldCheck, Layers3] +const principleIcons = [TimerReset, Waypoints, BarChart3] +const capabilityIcons = [TimerReset, Users, FileText, LockKeyhole] + +export default function About() { + const navigate = useNavigate() + const { t, lang, setLanguage } = useTranslation() + const { theme, setTheme } = useTheme() + + const content = aboutContent[lang] as AboutContent + const isAuthenticated = typeof window !== "undefined" && !!localStorage.getItem("accessToken") + const isDarkMode = + theme === "dark" || + (theme === "system" && document.documentElement.classList.contains("dark")) + const ctaTarget = isAuthenticated ? "/timesheet" : "/auth" + + return ( +
+
+
+
+
+ +
+
+ + + + +
+ + +
+
+ +
+
+
+
+
+ + {content.eyebrow} +
+

+ {content.hero.title} + + {content.hero.accent} + +

+

+ {content.hero.description} +

+
+ +
+ + +
+
+ +
+
+
+
+
+
+
+ {lang === "fa" ? "مدل محصول" : "Product model"} +
+
+ {lang === "fa" ? "از ثبت تا تصمیم" : "From capture to decision"} +
+
+
+ {lang === "fa" ? "شفاف" : "Clear"} +
+
+ +
+ {content.sections.map((section, index) => { + const Icon = sectionIcons[index] ?? Sparkles + + return ( +
+
+
+ +
+
+

+ {section.title} +

+

+ {section.description} +

+
+
+
+ ) + })} +
+
+
+
+
+ +
+ {content.principles.map((principle, index) => { + const Icon = principleIcons[index] ?? CheckCircle2 + + return ( +
+
+ +
+

+ {principle.title} +

+

+ {principle.description} +

+
+ ) + })} +
+ +
+
+
+ {lang === "fa" ? "برای چه تیم‌هایی" : "Who it serves"} +
+

+ {lang === "fa" ? "برای تیم‌هایی که زمان را بخشی از عملیات می‌دانند." : "For teams that treat time as part of operations."} +

+
+ {content.audience.map((item) => ( + + {item} + + ))} +
+
+ +
+ {content.capabilities.map((capability, index) => { + const Icon = capabilityIcons[index] ?? Waypoints + + return ( +
+
+
+ +
+

+ {capability.title} +

+
+

+ {capability.description} +

+
+ ) + })} +
+
+ +
+
+
+
+
+ {lang === "fa" ? "اعتماد و کنترل" : "Trust and control"} +
+

+ {lang === "fa" ? "جزئیات مهم باید قابل بررسی بمانند." : "Important details should remain reviewable."} +

+
+
+ +
+ {content.trust.map((item, index) => ( +
+ + {item} +
+ {lang === "fa" ? `نکته ${new Intl.NumberFormat("fa-IR").format(index + 1)}` : `Note ${index + 1}`} +
+
+ ))} +
+
+
+ +
+
+
+
+
+
+ {lang === "fa" ? "شروع ساده" : "Simple start"} +
+

+ {content.cta.title} +

+

{content.cta.description}

+
+ +
+
+
+
+
+
+ ) +} diff --git a/tsconfig.app.json b/tsconfig.app.json index ab4554d..e3fec1b 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -11,6 +11,7 @@ /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, + "resolveJsonModule": true, "verbatimModuleSyntax": true, "moduleDetection": "force", "noEmit": true,