feat(auth): add stepped auth and password recovery flows
This commit is contained in:
@@ -6,11 +6,11 @@ export const en = {
|
||||
confirmLogoutMessage: "Are you sure you want to log out of your account?",
|
||||
confirmLeave: "You have unsaved changes. Are you sure you want to leave?",
|
||||
cancel: "Cancel",
|
||||
save: "Save",
|
||||
lightMode: "Light Mode",
|
||||
darkMode: "Dark Mode",
|
||||
settings: "Settings",
|
||||
loadingText: "Loading...",
|
||||
save: "Save",
|
||||
lightMode: "Light Mode",
|
||||
darkMode: "Dark Mode",
|
||||
settings: "Settings",
|
||||
loadingText: "Loading...",
|
||||
loading: "Loading...",
|
||||
add: "Add",
|
||||
create: "Create",
|
||||
@@ -27,21 +27,54 @@ export const en = {
|
||||
|
||||
login: {
|
||||
welcome: (title: string = "Qlockifiy") => `Welcome to ${title}`,
|
||||
loginTitle: "Sign in to your account",
|
||||
loginDescription: "Enter your mobile number and we will send a one-time code.",
|
||||
loginCta: "Login",
|
||||
createAccount: "Create account",
|
||||
haveNoAccount: "Need an account?",
|
||||
haveAccount: "Already have an account?",
|
||||
loginOtpTitle: "Verify your login code",
|
||||
passwordLoginTitle: "Login with password",
|
||||
passwordLoginDescription: (mobile: string) => `Enter the password for ${mobile}`,
|
||||
usePasswordInstead: "Use password instead",
|
||||
useOtpInstead: "Use OTP instead",
|
||||
backToMobile: "Back to mobile step",
|
||||
backToPasswordLogin: "Back to password login",
|
||||
forgotPassword: "Forgot password?",
|
||||
signupTitle: "Create your account",
|
||||
signupDescription: "Start with your mobile number to receive a verification code.",
|
||||
sendSignupCode: "Send verification code",
|
||||
signupVerifyTitle: "Verify your mobile number",
|
||||
continueToPassword: "Continue to password",
|
||||
signupPasswordTitle: "Set your password",
|
||||
signupPasswordDescription: "Choose a password for your new account.",
|
||||
createAccountPasswordCta: "Create account",
|
||||
forgotPasswordTitle: "Recover your password",
|
||||
forgotPasswordDescription: "Enter your mobile number and we will send a verification code for password reset.",
|
||||
sendResetCode: "Send reset code",
|
||||
forgotPasswordVerifyTitle: "Enter your reset code",
|
||||
continueToResetPassword: "Continue to reset password",
|
||||
resetPasswordTitle: "Choose a new password",
|
||||
resetPasswordDescription: "Set a new password for your account and confirm it.",
|
||||
resetPasswordCta: "Reset password",
|
||||
newPasswordPlaceholder: "New password",
|
||||
confirmPasswordPlaceholder: "Confirm password",
|
||||
passwordMismatch: "The password confirmation does not match.",
|
||||
enterPassword: "Enter your password",
|
||||
verifyNumber: "Verify your number",
|
||||
enterMobileDesc: "Enter your mobile number to continue",
|
||||
signInDesc: "Sign in using your account password",
|
||||
sentCodeDesc: (mobile: string) => `We sent a 6-digit code to ${mobile}`,
|
||||
mobilePlaceholder: "Mobile Number (e.g. 09123456789)",
|
||||
continueWithPassword: "Continue with Password",
|
||||
continueWithGoogle: "Continue with Google",
|
||||
orContinueWith: "Or continue with",
|
||||
sentCodeDesc: (mobile: string) => `We sent a 5-digit code to ${mobile}`,
|
||||
mobilePlaceholder: "Mobile Number (e.g. 09123456789)",
|
||||
continueWithPassword: "Continue with Password",
|
||||
continueWithGoogle: "Continue with Google",
|
||||
orContinueWith: "Or continue with",
|
||||
otpLogin: "OTP Login",
|
||||
register: "Register",
|
||||
passwordPlaceholder: "Password",
|
||||
signIn: "Sign In",
|
||||
back: "Back",
|
||||
otpPlaceholder: "6-digit code",
|
||||
otpPlaceholder: "5-digit code",
|
||||
verifyAndContinue: "Verify & Continue",
|
||||
terms: "By clicking continue, you agree to our Terms of Service and Privacy Policy.",
|
||||
brandingQuote: "Manage your time and workspaces efficiently with our minimal, fast, and secure platform.",
|
||||
@@ -51,40 +84,44 @@ export const en = {
|
||||
failedOtp: "Failed to send OTP",
|
||||
fillAll: "Please fill all fields",
|
||||
successLogin: "Successfully logged in!",
|
||||
accountCreated: "Account created successfully!",
|
||||
failedSignup: "Failed to complete sign up",
|
||||
invalidCreds: "Invalid credentials",
|
||||
enterOtp: "Please enter the OTP code",
|
||||
invalidOtp: "Invalid OTP code"
|
||||
invalidOtp: "Invalid OTP code",
|
||||
passwordResetSuccess: "Password reset successfully.",
|
||||
passwordResetFailed: "Failed to reset password.",
|
||||
},
|
||||
throttle: {
|
||||
title: "Too many attempts",
|
||||
throttle: {
|
||||
title: "Too many attempts",
|
||||
genericMessage: (time: string) => `Too many requests. Try again in ${time}.`,
|
||||
otpSendMessage: (time: string) => `Too many OTP requests. Try again in ${time}.`,
|
||||
passwordLoginMessage: (time: string) => `Too many password login attempts. Try again in ${time}.`,
|
||||
otpLoginMessage: (time: string) => `Too many OTP login attempts. Try again in ${time}.`,
|
||||
countdownLabel: (time: string) => `Retry in ${time}`,
|
||||
fallback: "Too many requests. Please wait and try again.",
|
||||
},
|
||||
google: {
|
||||
loadingTitle: "Completing Google sign in",
|
||||
loadingDescription: "We are validating your Google account and preparing the next step.",
|
||||
collectMobileTitle: "Finish your account setup",
|
||||
collectMobileDescription: (email: string) =>
|
||||
`Google verified ${email}. Enter your mobile number to finish creating your account.`,
|
||||
claimTitle: "Verify your existing account",
|
||||
claimDescription: (mobile: string) =>
|
||||
`An account with ${mobile} already exists. Enter the verification code sent to that number to attach Google.`,
|
||||
errorTitle: "Google sign in could not be completed",
|
||||
missingFlow: "The Google sign-in flow is missing or has expired.",
|
||||
loadFailed: "We could not load your Google sign-in state.",
|
||||
completeFailed: "We could not finish your Google account setup.",
|
||||
claimOtpSent: "Verification code sent successfully.",
|
||||
googleAccount: "Google account",
|
||||
completeButton: "Continue and create account",
|
||||
verifyClaimButton: "Verify and continue",
|
||||
resendClaimOtp: "Resend verification code",
|
||||
restartGoogle: "Start Google sign in again",
|
||||
},
|
||||
},
|
||||
fallback: "Too many requests. Please wait and try again.",
|
||||
},
|
||||
google: {
|
||||
loadingTitle: "Completing Google sign in",
|
||||
loadingDescription: "We are validating your Google account and preparing the next step.",
|
||||
collectMobileTitle: "Finish your account setup",
|
||||
collectMobileDescription: (email: string) =>
|
||||
`Google verified ${email}. Enter your mobile number to finish creating your account.`,
|
||||
claimTitle: "Verify your existing account",
|
||||
claimDescription: (mobile: string) =>
|
||||
`An account with ${mobile} already exists. Enter the verification code sent to that number to attach Google.`,
|
||||
errorTitle: "Google sign in could not be completed",
|
||||
missingFlow: "The Google sign-in flow is missing or has expired.",
|
||||
loadFailed: "We could not load your Google sign-in state.",
|
||||
completeFailed: "We could not finish your Google account setup.",
|
||||
claimOtpSent: "Verification code sent successfully.",
|
||||
googleAccount: "Google account",
|
||||
completeButton: "Continue and create account",
|
||||
verifyClaimButton: "Verify and continue",
|
||||
resendClaimOtp: "Resend verification code",
|
||||
restartGoogle: "Start Google sign in again",
|
||||
},
|
||||
},
|
||||
|
||||
loginTerms: {
|
||||
prefix: "By logging in, you agree to our ",
|
||||
@@ -159,6 +196,20 @@ export const en = {
|
||||
upload: "Upload",
|
||||
remove: "Remove",
|
||||
imageInput: "Click to select or drag & drop",
|
||||
password: {
|
||||
trigger: "Change password",
|
||||
title: "Change password",
|
||||
description: "Enter your current password and choose a new one.",
|
||||
currentPassword: "Current password",
|
||||
newPassword: "New password",
|
||||
confirmPassword: "Confirm new password",
|
||||
submit: "Save password",
|
||||
saving: "Saving...",
|
||||
toasts: {
|
||||
success: "Password changed successfully.",
|
||||
error: "Failed to change password.",
|
||||
},
|
||||
},
|
||||
toasts: {
|
||||
successEdit: "Profile updated successfully!",
|
||||
successImage: "Profile picture updated!",
|
||||
@@ -313,108 +364,108 @@ export const en = {
|
||||
next: "Next",
|
||||
},
|
||||
|
||||
sidebar: {
|
||||
timesheet: "Timesheet",
|
||||
reports: "Reports",
|
||||
logs: "Logs",
|
||||
sidebar: {
|
||||
timesheet: "Timesheet",
|
||||
reports: "Reports",
|
||||
logs: "Logs",
|
||||
workspaces: 'Workspaces',
|
||||
clients: 'Clients',
|
||||
projects: "Projects",
|
||||
tags: "Tags",
|
||||
expand: 'Expand',
|
||||
collapse: 'Collapse',
|
||||
},
|
||||
|
||||
landing: {
|
||||
brandLabel: "Operating system for time",
|
||||
eyebrow: "Built for high-discipline teams that need clean time intelligence",
|
||||
nav: {
|
||||
demo: "Product demo",
|
||||
features: "Core capabilities",
|
||||
workflow: "How it works",
|
||||
},
|
||||
actions: {
|
||||
switchToEnglish: "English",
|
||||
switchToPersian: "فارسی",
|
||||
signIn: "Sign in",
|
||||
openApp: "Open app",
|
||||
openWorkspace: "Open workspace",
|
||||
startNow: "Start tracking with control",
|
||||
watchDemo: "See the product demo",
|
||||
readTerms: "Read terms",
|
||||
},
|
||||
hero: {
|
||||
titleTop: "Turn every working hour into a reliable operating signal.",
|
||||
titleAccent: "Qlockify makes time visible, accountable, and billable.",
|
||||
description:
|
||||
"A focused workspace for modern teams that need fast time capture, trustworthy project tracking, structured reports, and a log trail that management can actually use.",
|
||||
},
|
||||
metrics: {
|
||||
capture: "cleaner billable capture",
|
||||
visibility: "faster reporting visibility",
|
||||
decision: "from raw entries to management context",
|
||||
},
|
||||
trust: {
|
||||
first: "Precise timers with manual control when needed",
|
||||
second: "Workspace permissions, logs, and rate-aware reporting",
|
||||
third: "Built for agencies, consultancies, product teams, and operators",
|
||||
},
|
||||
capabilities: {
|
||||
time: {
|
||||
title: "Capture work without friction",
|
||||
description:
|
||||
"Start a timer, adjust historical entries, and keep project and tag context attached to every hour without slowing the team down.",
|
||||
},
|
||||
reports: {
|
||||
title: "Read the business in minutes",
|
||||
description:
|
||||
"See daily output, billable performance, project distribution, and exportable report packs without spreadsheet cleanup.",
|
||||
},
|
||||
control: {
|
||||
title: "Keep operations explainable",
|
||||
description:
|
||||
"Track who changed what, keep workspace roles explicit, and give management a cleaner operational trail than ad hoc chat or manual files.",
|
||||
},
|
||||
},
|
||||
demo: {
|
||||
timerTag: "Live timer",
|
||||
timerTitle: "Current execution window",
|
||||
timerText: "Design system refinement synced to the correct project, tags, and billable rate.",
|
||||
panelLabel: "Interactive product preview",
|
||||
panelTitle: "One surface for tracking, reporting, and operational clarity",
|
||||
runningCard: "Active entry",
|
||||
currentTask: "Enterprise landing page rollout",
|
||||
currentTaskMeta: "Project: Qlockify Marketing · Tags: Design, Review, Delivery",
|
||||
billableLabel: "Live billable rate",
|
||||
reportCard: "Daily report trend",
|
||||
opsCard: "Operational health",
|
||||
opsLabels: ["Coverage", "Team focus", "Billing readiness"],
|
||||
logCard: "Recent workspace activity",
|
||||
logItems: [
|
||||
{ title: "Rate updated for product design", meta: "Owner action · 3 minutes ago" },
|
||||
{ title: "Client-facing project moved to archived", meta: "Admin action · 18 minutes ago" },
|
||||
{ title: "Historic tag preserved on edited entry", meta: "Member action · 41 minutes ago" },
|
||||
],
|
||||
outcomeTag: "Management result",
|
||||
outcomeText: "Less ambiguity at month end, fewer missing billable hours, and faster operational reviews.",
|
||||
},
|
||||
workflowTag: "Operational workflow",
|
||||
workflowTitle: "A tighter loop from raw effort to usable management data.",
|
||||
workflowDescription:
|
||||
"Qlockify is designed to keep the path short: capture accurately, structure context once, and reuse the result everywhere from timesheets to reports to workspace-level decisions.",
|
||||
workflow: {
|
||||
capture: "Capture time at the source with project, tags, and billing context attached immediately.",
|
||||
structure: "Keep every workspace action, membership change, and rate update visible and reviewable.",
|
||||
improve: "Review daily and monthly performance with reports that are ready to export or act on.",
|
||||
},
|
||||
finalCtaTag: "Ready for production teams",
|
||||
finalCtaTitle: "If your team sells expertise or ships client work, your time system should look this serious.",
|
||||
finalCtaDescription:
|
||||
"Open the app, create a workspace, and see how fast your reporting discipline improves when the product stops leaking context.",
|
||||
},
|
||||
|
||||
ordering: {
|
||||
createdAtDesc: "Newest First",
|
||||
collapse: 'Collapse',
|
||||
},
|
||||
|
||||
landing: {
|
||||
brandLabel: "Operating system for time",
|
||||
eyebrow: "Built for high-discipline teams that need clean time intelligence",
|
||||
nav: {
|
||||
demo: "Product demo",
|
||||
features: "Core capabilities",
|
||||
workflow: "How it works",
|
||||
},
|
||||
actions: {
|
||||
switchToEnglish: "English",
|
||||
switchToPersian: "فارسی",
|
||||
signIn: "Sign in",
|
||||
openApp: "Open app",
|
||||
openWorkspace: "Open workspace",
|
||||
startNow: "Start tracking with control",
|
||||
watchDemo: "See the product demo",
|
||||
readTerms: "Read terms",
|
||||
},
|
||||
hero: {
|
||||
titleTop: "Turn every working hour into a reliable operating signal.",
|
||||
titleAccent: "Qlockify makes time visible, accountable, and billable.",
|
||||
description:
|
||||
"A focused workspace for modern teams that need fast time capture, trustworthy project tracking, structured reports, and a log trail that management can actually use.",
|
||||
},
|
||||
metrics: {
|
||||
capture: "cleaner billable capture",
|
||||
visibility: "faster reporting visibility",
|
||||
decision: "from raw entries to management context",
|
||||
},
|
||||
trust: {
|
||||
first: "Precise timers with manual control when needed",
|
||||
second: "Workspace permissions, logs, and rate-aware reporting",
|
||||
third: "Built for agencies, consultancies, product teams, and operators",
|
||||
},
|
||||
capabilities: {
|
||||
time: {
|
||||
title: "Capture work without friction",
|
||||
description:
|
||||
"Start a timer, adjust historical entries, and keep project and tag context attached to every hour without slowing the team down.",
|
||||
},
|
||||
reports: {
|
||||
title: "Read the business in minutes",
|
||||
description:
|
||||
"See daily output, billable performance, project distribution, and exportable report packs without spreadsheet cleanup.",
|
||||
},
|
||||
control: {
|
||||
title: "Keep operations explainable",
|
||||
description:
|
||||
"Track who changed what, keep workspace roles explicit, and give management a cleaner operational trail than ad hoc chat or manual files.",
|
||||
},
|
||||
},
|
||||
demo: {
|
||||
timerTag: "Live timer",
|
||||
timerTitle: "Current execution window",
|
||||
timerText: "Design system refinement synced to the correct project, tags, and billable rate.",
|
||||
panelLabel: "Interactive product preview",
|
||||
panelTitle: "One surface for tracking, reporting, and operational clarity",
|
||||
runningCard: "Active entry",
|
||||
currentTask: "Enterprise landing page rollout",
|
||||
currentTaskMeta: "Project: Qlockify Marketing · Tags: Design, Review, Delivery",
|
||||
billableLabel: "Live billable rate",
|
||||
reportCard: "Daily report trend",
|
||||
opsCard: "Operational health",
|
||||
opsLabels: ["Coverage", "Team focus", "Billing readiness"],
|
||||
logCard: "Recent workspace activity",
|
||||
logItems: [
|
||||
{ title: "Rate updated for product design", meta: "Owner action · 3 minutes ago" },
|
||||
{ title: "Client-facing project moved to archived", meta: "Admin action · 18 minutes ago" },
|
||||
{ title: "Historic tag preserved on edited entry", meta: "Member action · 41 minutes ago" },
|
||||
],
|
||||
outcomeTag: "Management result",
|
||||
outcomeText: "Less ambiguity at month end, fewer missing billable hours, and faster operational reviews.",
|
||||
},
|
||||
workflowTag: "Operational workflow",
|
||||
workflowTitle: "A tighter loop from raw effort to usable management data.",
|
||||
workflowDescription:
|
||||
"Qlockify is designed to keep the path short: capture accurately, structure context once, and reuse the result everywhere from timesheets to reports to workspace-level decisions.",
|
||||
workflow: {
|
||||
capture: "Capture time at the source with project, tags, and billing context attached immediately.",
|
||||
structure: "Keep every workspace action, membership change, and rate update visible and reviewable.",
|
||||
improve: "Review daily and monthly performance with reports that are ready to export or act on.",
|
||||
},
|
||||
finalCtaTag: "Ready for production teams",
|
||||
finalCtaTitle: "If your team sells expertise or ships client work, your time system should look this serious.",
|
||||
finalCtaDescription:
|
||||
"Open the app, create a workspace, and see how fast your reporting discipline improves when the product stops leaking context.",
|
||||
},
|
||||
|
||||
ordering: {
|
||||
createdAtDesc: "Newest First",
|
||||
createdAt: "Olders First",
|
||||
updatedAtDesc: "Recently Updated",
|
||||
name: "Name (A-Z)",
|
||||
|
||||
Reference in New Issue
Block a user