Redesign login, register, me pages with premium layout and i18n
This commit is contained in:
1 parent
063ac9ec40
commit
1ffd46713a
7 files changed
+621
-279
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -2,11 +2,6 @@
|
|||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies the user's referral link to the clipboard. Mirrors AtomCMS's
|
|
||||||
* copyCode() helper on the /me page, but resolves the link to an absolute URL
|
|
||||||
* (the server only knows a relative path, so we prepend the current origin).
|
|
||||||
*/
|
|
||||||
export default function CopyReferralButton({ value }: { value: string }) {
|
export default function CopyReferralButton({ value }: { value: string }) {
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
|
|
||||||
@@ -18,7 +13,6 @@ export default function CopyReferralButton({ value }: { value: string }) {
|
|||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(absolute);
|
await navigator.clipboard.writeText(absolute);
|
||||||
} catch {
|
} catch {
|
||||||
// Older browsers / insecure contexts: fall back to a hidden textarea.
|
|
||||||
const ta = document.createElement("textarea");
|
const ta = document.createElement("textarea");
|
||||||
ta.value = absolute;
|
ta.value = absolute;
|
||||||
ta.style.position = "fixed";
|
ta.style.position = "fixed";
|
||||||
@@ -37,7 +31,16 @@ export default function CopyReferralButton({ value }: { value: string }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button type="button" className="btn btn-secondary" onClick={copy}>
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={copy}
|
||||||
|
className="rounded-xl font-bold text-sm px-5 py-2.5 transition-all duration-200 hover:scale-[1.02] active:scale-95 shrink-0"
|
||||||
|
style={{
|
||||||
|
background: "color-mix(in srgb, var(--color-primary) 12%, transparent)",
|
||||||
|
color: "var(--color-primary-readable, var(--color-primary))",
|
||||||
|
border: `2px solid color-mix(in srgb, var(--color-primary) 20%, transparent)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
{copied ? "Copied!" : "Copy link"}
|
{copied ? "Copied!" : "Copy link"}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|||||||
+202
-107
File diff suppressed because it is too large.
Load diff
+89
-38
File diff suppressed because it is too large.
Load diff
@@ -10,7 +10,8 @@ import { captchaConfig } from "@/lib/services/captcha";
|
|||||||
import { siteSettings } from "@/lib/services/site-settings";
|
import { siteSettings } from "@/lib/services/site-settings";
|
||||||
|
|
||||||
export default async function RegisterPage() {
|
export default async function RegisterPage() {
|
||||||
const t = await getTranslations("header");
|
const th = await getTranslations("header");
|
||||||
|
const tpr = await getTranslations("pages.register");
|
||||||
const [hotelName, imagerRaw, cfg] = await Promise.all([
|
const [hotelName, imagerRaw, cfg] = await Promise.all([
|
||||||
siteSettings.get("hotel_name", "Hotel"),
|
siteSettings.get("hotel_name", "Hotel"),
|
||||||
siteSettings.get(
|
siteSettings.get(
|
||||||
@@ -67,26 +68,19 @@ export default async function RegisterPage() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span className="w-2 h-2 rounded-full bg-green-500" />
|
<span className="w-2 h-2 rounded-full bg-green-500" />
|
||||||
{online.toLocaleString()} online
|
{tpr("usersOnline", { count: online })}
|
||||||
</div>
|
</div>
|
||||||
<h1
|
<h1
|
||||||
className="text-xl font-black"
|
className="text-xl font-black"
|
||||||
style={{ color: "var(--color-text-readable)" }}
|
style={{ color: "var(--color-text-readable)" }}
|
||||||
>
|
>
|
||||||
Join{" "}
|
{tpr("title")} — {hotelName}
|
||||||
<span
|
|
||||||
style={{
|
|
||||||
color: "var(--color-primary-readable, var(--color-primary))",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{hotelName}
|
|
||||||
</span>
|
|
||||||
</h1>
|
</h1>
|
||||||
<p
|
<p
|
||||||
className="text-xs mt-1 mx-auto max-w-[200px] leading-relaxed"
|
className="text-xs mt-1 mx-auto max-w-[200px] leading-relaxed"
|
||||||
style={{ color: "var(--color-text-muted)" }}
|
style={{ color: "var(--color-text-muted)" }}
|
||||||
>
|
>
|
||||||
{t("tagline")}
|
{th("tagline")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -103,7 +97,7 @@ export default async function RegisterPage() {
|
|||||||
className="text-xs font-bold uppercase tracking-widest mb-3"
|
className="text-xs font-bold uppercase tracking-widest mb-3"
|
||||||
style={{ color: "var(--color-text-muted)" }}
|
style={{ color: "var(--color-text-muted)" }}
|
||||||
>
|
>
|
||||||
Who's online
|
{tpr("whoIsOnline")}
|
||||||
</h3>
|
</h3>
|
||||||
<div className="grid grid-cols-4 gap-1.5">
|
<div className="grid grid-cols-4 gap-1.5">
|
||||||
{recentUsers.map((u) => (
|
{recentUsers.map((u) => (
|
||||||
@@ -143,7 +137,7 @@ export default async function RegisterPage() {
|
|||||||
className="text-xs text-center"
|
className="text-xs text-center"
|
||||||
style={{ color: "var(--color-text-muted)" }}
|
style={{ color: "var(--color-text-muted)" }}
|
||||||
>
|
>
|
||||||
Already have an account?{" "}
|
{tpr("alreadyHaveAccountPre")}{" "}
|
||||||
<Link
|
<Link
|
||||||
href="/login"
|
href="/login"
|
||||||
className="font-extrabold hover:underline"
|
className="font-extrabold hover:underline"
|
||||||
@@ -151,7 +145,7 @@ export default async function RegisterPage() {
|
|||||||
color: "var(--color-primary-readable, var(--color-primary))",
|
color: "var(--color-primary-readable, var(--color-primary))",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Sign in
|
{tpr("alreadyHaveAccountLink")}
|
||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -163,13 +157,13 @@ export default async function RegisterPage() {
|
|||||||
className="text-2xl font-black tracking-tight"
|
className="text-2xl font-black tracking-tight"
|
||||||
style={{ color: "var(--color-text-readable)" }}
|
style={{ color: "var(--color-text-readable)" }}
|
||||||
>
|
>
|
||||||
Create your account
|
{tpr("title")}
|
||||||
</h2>
|
</h2>
|
||||||
<p
|
<p
|
||||||
className="text-sm mt-0.5"
|
className="text-sm mt-0.5"
|
||||||
style={{ color: "var(--color-text-muted)" }}
|
style={{ color: "var(--color-text-muted)" }}
|
||||||
>
|
>
|
||||||
Free and takes less than a minute
|
{tpr("subtitle")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<RegisterForm
|
<RegisterForm
|
||||||
|
|||||||
+122
-101
File diff suppressed because it is too large.
Load diff
+18
-1
@@ -234,7 +234,18 @@
|
|||||||
"noArticles": "No articles yet.",
|
"noArticles": "No articles yet.",
|
||||||
"noPhotos": "No photos yet.",
|
"noPhotos": "No photos yet.",
|
||||||
"noUsers": "No users online",
|
"noUsers": "No users online",
|
||||||
"latestArticle": "Latest Article"
|
"latestArticle": "Latest Article",
|
||||||
|
"statsOnline": "Online",
|
||||||
|
"statsCitizens": "Citizens",
|
||||||
|
"statsRooms": "Rooms",
|
||||||
|
"featuresAvatar": "Avatar",
|
||||||
|
"featuresAvatarDesc": "Create your unique look",
|
||||||
|
"featuresFurniture": "Furniture",
|
||||||
|
"featuresFurnitureDesc": "Decorate rooms with items",
|
||||||
|
"featuresCommunity": "Community",
|
||||||
|
"featuresCommunityDesc": "Make friends and chat",
|
||||||
|
"featuresGames": "Games",
|
||||||
|
"featuresGamesDesc": "Compete and have fun"
|
||||||
},
|
},
|
||||||
"news": {
|
"news": {
|
||||||
"title": "News",
|
"title": "News",
|
||||||
@@ -894,6 +905,8 @@
|
|||||||
"title": "Sign in",
|
"title": "Sign in",
|
||||||
"subtitle": "Welcome back — log in to enter the hotel.",
|
"subtitle": "Welcome back — log in to enter the hotel.",
|
||||||
"subtitle2fa": "Enter the 6-digit code from your authenticator.",
|
"subtitle2fa": "Enter the 6-digit code from your authenticator.",
|
||||||
|
"welcomeBack": "Welcome back",
|
||||||
|
"welcomeBackSub": "Sign in to continue to {hotelName}",
|
||||||
"usernamePlaceholder": "Username",
|
"usernamePlaceholder": "Username",
|
||||||
"passwordPlaceholder": "Password",
|
"passwordPlaceholder": "Password",
|
||||||
"codePlaceholder": "2FA code",
|
"codePlaceholder": "2FA code",
|
||||||
@@ -927,7 +940,11 @@
|
|||||||
"createAccount": "Create account",
|
"createAccount": "Create account",
|
||||||
"creatingAccount": "Creating account...",
|
"creatingAccount": "Creating account...",
|
||||||
"alreadyHaveAccount": "Already have an account? Login!",
|
"alreadyHaveAccount": "Already have an account? Login!",
|
||||||
|
"alreadyHaveAccountPre": "Already have an account?",
|
||||||
|
"alreadyHaveAccountLink": "Sign in",
|
||||||
"register": "Register",
|
"register": "Register",
|
||||||
|
"whoIsOnline": "Who's online",
|
||||||
|
"usersOnline": "{count} online",
|
||||||
"termsError": "You must accept the terms & rules to register.",
|
"termsError": "You must accept the terms & rules to register.",
|
||||||
"usernameError": "Username is required.",
|
"usernameError": "Username is required.",
|
||||||
"emailError": "Valid email is required.",
|
"emailError": "Valid email is required.",
|
||||||
|
|||||||
Reference in new issue
Block a user