Files
2026-02-06 21:44:04 -06:00

937 lines
36 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState, useEffect } from "react";
interface SocialMedia {
url: string;
display: boolean;
}
interface Socials {
facebook?: SocialMedia;
instagram?: SocialMedia;
twitter?: SocialMedia;
linkedin?: SocialMedia;
youtube?: SocialMedia;
}
interface OAuthProvider {
enabled: boolean;
clientId: string;
clientSecret: string;
}
interface OAuthConfig {
google?: OAuthProvider;
github?: OAuthProvider;
facebook?: OAuthProvider;
discord?: OAuthProvider;
}
export default function AdminSetupPage() {
const [config, setConfig] = useState({
googleAuth: {
enabled: false,
clientId: "",
clientSecret: "",
},
oauth: {
google: { enabled: false, clientId: "", clientSecret: "" },
github: { enabled: false, clientId: "", clientSecret: "" },
facebook: { enabled: false, clientId: "", clientSecret: "" },
discord: { enabled: false, clientId: "", clientSecret: "" },
} as OAuthConfig,
googleCalendar: {
enabled: false,
serviceAccountEmail: "",
serviceAccountKey: "",
calendarId: "",
},
socials: {} as Socials,
email: {
smtp: {
enabled: false,
host: "",
port: 587,
username: "",
password: "",
from: "",
},
},
pagination: {
itemsPerPage: 10,
},
});
const [loading, setLoading] = useState(true);
const [saving, setSaving] = useState(false);
const [message, setMessage] = useState("");
useEffect(() => {
fetchConfig();
}, []);
const fetchConfig = async () => {
try {
const response = await fetch("/api/admin/setup");
const data = await response.json();
if (data.ok) {
// Ensure oauth object exists with all providers
const fetchedConfig = data.data;
if (!fetchedConfig.oauth) {
fetchedConfig.oauth = {
google: { enabled: false, clientId: "", clientSecret: "" },
github: { enabled: false, clientId: "", clientSecret: "" },
facebook: { enabled: false, clientId: "", clientSecret: "" },
discord: { enabled: false, clientId: "", clientSecret: "" },
};
}
setConfig(fetchedConfig);
} else {
setMessage(`❌ Failed to load config: ${data.message}`);
}
} catch (error) {
console.error("Error fetching config:", error);
setMessage(`❌ Error loading configuration: ${error}`);
} finally {
setLoading(false);
}
};
const handleSave = async () => {
setSaving(true);
setMessage("");
try {
const response = await fetch("/api/admin/setup", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(config),
});
const data = await response.json();
if (data.ok) {
setMessage("✅ Settings saved successfully!");
} else {
setMessage(`${data.message}`);
}
} catch (error) {
setMessage("❌ Failed to save settings");
} finally {
setSaving(false);
setTimeout(() => setMessage(""), 3000);
}
};
const updateSocial = (platform: keyof Socials, field: "url" | "display", value: string | boolean) => {
setConfig({
...config,
socials: {
...config.socials,
[platform]: {
...config.socials[platform],
[field]: value,
},
},
});
};
if (loading) {
return (
<main className="max-w-5xl mx-auto px-6 py-16">
<div className="text-center">Loading configuration...</div>
</main>
);
}
return (
<main className="max-w-5xl mx-auto px-6 py-16">
<div className="mb-8">
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-primary/10 text-primary text-xs font-semibold mb-4">
🛠 Admin Settings
</div>
<h1 className="text-4xl font-bold text-slate-900 dark:text-white">
System Setup
</h1>
<p className="text-lg text-gray-600 dark:text-gray-400">
Configure authentication, social media, and email settings
</p>
</div>
<div className="space-y-6">
{/* Google OAuth Configuration */}
<div className="card p-6 border border-slate-200/60 dark:border-slate-700/60 shadow-lg">
<div className="flex items-center gap-3 mb-4">
<div className="text-2xl">🔐</div>
<div>
<h2 className="text-xl font-bold text-gray-900 dark:text-white">Google OAuth</h2>
<p className="text-sm text-gray-600 dark:text-gray-400">Enable Google sign-in for users</p>
</div>
</div>
<div className="space-y-4">
<div className="flex items-center gap-3">
<input
type="checkbox"
id="googleEnabled"
checked={config.googleAuth.enabled}
onChange={(e) =>
setConfig({
...config,
googleAuth: { ...config.googleAuth, enabled: e.target.checked },
})
}
className="w-5 h-5 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label
htmlFor="googleEnabled"
className="text-sm font-semibold text-gray-700 dark:text-gray-300"
>
Enable Google Sign-In
</label>
</div>
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
Google Client ID
</label>
<input
type="text"
className="input-field"
placeholder="Your Google OAuth Client ID"
value={config.googleAuth.clientId}
onChange={(e) =>
setConfig({
...config,
googleAuth: { ...config.googleAuth, clientId: e.target.value },
})
}
/>
</div>
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
Google Client Secret
</label>
<input
type="password"
className="input-field"
placeholder="Your Google OAuth Client Secret"
value={config.googleAuth.clientSecret}
onChange={(e) =>
setConfig({
...config,
googleAuth: { ...config.googleAuth, clientSecret: e.target.value },
})
}
/>
</div>
</div>
</div>
{/* BetterAuth OAuth Providers */}
<div className="border-t border-slate-200 dark:border-slate-700 pt-6 mt-6">
<div className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full bg-indigo-500/10 text-indigo-600 dark:text-indigo-400 text-xs font-semibold mb-4">
🔑 OAuth Providers (BetterAuth)
</div>
<p className="text-sm text-gray-600 dark:text-gray-400 mb-6">
Configure social OAuth providers for user authentication. Get credentials from each provider's developer console.
</p>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{/* Google OAuth */}
<div className="card p-6 border border-blue-200/40 dark:border-blue-900/30 bg-blue-50/30 dark:bg-blue-950/20">
<div className="flex items-center gap-2 mb-4">
<span className="text-2xl">🔍</span>
<h3 className="text-lg font-bold text-gray-900 dark:text-white">Google</h3>
</div>
<div className="space-y-3">
<div className="flex items-center gap-2">
<input
type="checkbox"
id="googleOAuthEnabled"
checked={config.oauth.google?.enabled || false}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
google: { ...(config.oauth.google || {}), enabled: e.target.checked } as OAuthProvider,
},
})
}
className="w-4 h-4 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label
htmlFor="googleOAuthEnabled"
className="text-sm font-semibold text-gray-700 dark:text-gray-300"
>
Enable Google OAuth
</label>
</div>
<input
type="text"
className="input-field text-sm"
placeholder="Client ID"
value={config.oauth.google?.clientId || ""}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
google: { ...(config.oauth.google || {}), clientId: e.target.value } as OAuthProvider,
},
})
}
/>
<input
type="password"
className="input-field text-sm"
placeholder="Client Secret"
value={config.oauth.google?.clientSecret || ""}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
google: { ...(config.oauth.google || {}), clientSecret: e.target.value } as OAuthProvider,
},
})
}
/>
</div>
</div>
{/* GitHub OAuth */}
<div className="card p-6 border border-gray-300/40 dark:border-gray-700/30 bg-gray-50/30 dark:bg-gray-950/20">
<div className="flex items-center gap-2 mb-4">
<span className="text-2xl">🐙</span>
<h3 className="text-lg font-bold text-gray-900 dark:text-white">GitHub</h3>
</div>
<div className="space-y-3">
<div className="flex items-center gap-2">
<input
type="checkbox"
id="githubOAuthEnabled"
checked={config.oauth.github?.enabled || false}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
github: { ...(config.oauth.github || {}), enabled: e.target.checked } as OAuthProvider,
},
})
}
className="w-4 h-4 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label
htmlFor="githubOAuthEnabled"
className="text-sm font-semibold text-gray-700 dark:text-gray-300"
>
Enable GitHub OAuth
</label>
</div>
<input
type="text"
className="input-field text-sm"
placeholder="Client ID"
value={config.oauth.github?.clientId || ""}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
github: { ...(config.oauth.github || {}), clientId: e.target.value } as OAuthProvider,
},
})
}
/>
<input
type="password"
className="input-field text-sm"
placeholder="Client Secret"
value={config.oauth.github?.clientSecret || ""}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
github: { ...(config.oauth.github || {}), clientSecret: e.target.value } as OAuthProvider,
},
})
}
/>
</div>
</div>
{/* Facebook OAuth */}
<div className="card p-6 border border-blue-600/40 dark:border-blue-900/30 bg-blue-50/30 dark:bg-blue-950/20">
<div className="flex items-center gap-2 mb-4">
<span className="text-2xl">👍</span>
<h3 className="text-lg font-bold text-gray-900 dark:text-white">Facebook</h3>
</div>
<div className="space-y-3">
<div className="flex items-center gap-2">
<input
type="checkbox"
id="facebookOAuthEnabled"
checked={config.oauth.facebook?.enabled || false}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
facebook: { ...(config.oauth.facebook || {}), enabled: e.target.checked } as OAuthProvider,
},
})
}
className="w-4 h-4 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label
htmlFor="facebookOAuthEnabled"
className="text-sm font-semibold text-gray-700 dark:text-gray-300"
>
Enable Facebook OAuth
</label>
</div>
<input
type="text"
className="input-field text-sm"
placeholder="App ID"
value={config.oauth.facebook?.clientId || ""}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
facebook: { ...(config.oauth.facebook || {}), clientId: e.target.value } as OAuthProvider,
},
})
}
/>
<input
type="password"
className="input-field text-sm"
placeholder="App Secret"
value={config.oauth.facebook?.clientSecret || ""}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
facebook: { ...(config.oauth.facebook || {}), clientSecret: e.target.value } as OAuthProvider,
},
})
}
/>
</div>
</div>
{/* Discord OAuth */}
<div className="card p-6 border border-indigo-500/40 dark:border-indigo-900/30 bg-indigo-50/30 dark:bg-indigo-950/20">
<div className="flex items-center gap-2 mb-4">
<span className="text-2xl">💬</span>
<h3 className="text-lg font-bold text-gray-900 dark:text-white">Discord</h3>
</div>
<div className="space-y-3">
<div className="flex items-center gap-2">
<input
type="checkbox"
id="discordOAuthEnabled"
checked={config.oauth.discord?.enabled || false}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
discord: { ...(config.oauth.discord || {}), enabled: e.target.checked } as OAuthProvider,
},
})
}
className="w-4 h-4 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label
htmlFor="discordOAuthEnabled"
className="text-sm font-semibold text-gray-700 dark:text-gray-300"
>
Enable Discord OAuth
</label>
</div>
<input
type="text"
className="input-field text-sm"
placeholder="Client ID"
value={config.oauth.discord?.clientId || ""}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
discord: { ...(config.oauth.discord || {}), clientId: e.target.value } as OAuthProvider,
},
})
}
/>
<input
type="password"
className="input-field text-sm"
placeholder="Client Secret"
value={config.oauth.discord?.clientSecret || ""}
onChange={(e) =>
setConfig({
...config,
oauth: {
...config.oauth,
discord: { ...(config.oauth.discord || {}), clientSecret: e.target.value } as OAuthProvider,
},
})
}
/>
</div>
</div>
</div>
</div>
{/* Google Calendar Configuration */}
<div className="card p-6 border border-slate-200/60 dark:border-slate-700/60 shadow-lg">
<div className="flex items-center gap-3 mb-4">
<div className="text-2xl">📅</div>
<div>
<h2 className="text-xl font-bold text-gray-900 dark:text-white">Google Calendar</h2>
<p className="text-sm text-gray-600 dark:text-gray-400">Enable calendar invites for webinar registrations</p>
</div>
</div>
<div className="space-y-4">
<div className="flex items-center gap-3">
<input
type="checkbox"
id="calendarEnabled"
checked={config.googleCalendar.enabled}
onChange={(e) =>
setConfig({
...config,
googleCalendar: { ...config.googleCalendar, enabled: e.target.checked },
})
}
className="w-5 h-5 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label
htmlFor="calendarEnabled"
className="text-sm font-semibold text-gray-700 dark:text-gray-300"
>
Enable Calendar Invites
</label>
</div>
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
Service Account Email
</label>
<input
type="email"
className="input-field"
placeholder="service-account@project.iam.gserviceaccount.com"
value={config.googleCalendar.serviceAccountEmail}
onChange={(e) =>
setConfig({
...config,
googleCalendar: { ...config.googleCalendar, serviceAccountEmail: e.target.value },
})
}
/>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
Create a service account in Google Cloud Console
</p>
</div>
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
Service Account Private Key (JSON)
</label>
<textarea
className="input-field font-mono text-xs"
rows={4}
placeholder='{"type": "service_account", "project_id": "...", "private_key": "...", ...}'
value={config.googleCalendar.serviceAccountKey}
onChange={(e) =>
setConfig({
...config,
googleCalendar: { ...config.googleCalendar, serviceAccountKey: e.target.value },
})
}
/>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
Paste the entire JSON key file content
</p>
</div>
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
Calendar ID
</label>
<input
type="text"
className="input-field"
placeholder="primary or your-calendar@group.calendar.google.com"
value={config.googleCalendar.calendarId}
onChange={(e) =>
setConfig({
...config,
googleCalendar: { ...config.googleCalendar, calendarId: e.target.value },
})
}
/>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
Use &quot;primary&quot; for the service account&apos;s calendar or specify a shared calendar ID
</p>
</div>
</div>
</div>
{/* Social Media Configuration */}
<div className="card p-6 border border-slate-200/60 dark:border-slate-700/60 shadow-lg">
<div className="flex items-center gap-3 mb-4">
<div className="text-2xl">🌐</div>
<div>
<h2 className="text-xl font-bold text-gray-900 dark:text-white">Social Media</h2>
<p className="text-sm text-gray-600 dark:text-gray-400">Configure social media links and visibility</p>
</div>
</div>
<div className="space-y-6">
{/* Facebook */}
<div className="border-b border-slate-200 dark:border-slate-700 pb-4">
<div className="flex items-center gap-2 mb-3">
<span className="text-xl">📘</span>
<span className="font-semibold text-gray-900 dark:text-white">Facebook</span>
</div>
<div className="space-y-3">
<input
type="url"
className="input-field"
placeholder="https://facebook.com/yourpage"
value={config.socials.facebook?.url || ""}
onChange={(e) => updateSocial("facebook", "url", e.target.value)}
/>
<div className="flex items-center gap-3">
<input
type="checkbox"
id="facebookDisplay"
checked={config.socials.facebook?.display || false}
onChange={(e) => updateSocial("facebook", "display", e.target.checked)}
className="w-5 h-5 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label htmlFor="facebookDisplay" className="text-sm text-gray-700 dark:text-gray-300">
Display on landing page
</label>
</div>
</div>
</div>
{/* Instagram */}
<div className="border-b border-slate-200 dark:border-slate-700 pb-4">
<div className="flex items-center gap-2 mb-3">
<span className="text-xl">📷</span>
<span className="font-semibold text-gray-900 dark:text-white">Instagram</span>
</div>
<div className="space-y-3">
<input
type="url"
className="input-field"
placeholder="https://instagram.com/yourprofile"
value={config.socials.instagram?.url || ""}
onChange={(e) => updateSocial("instagram", "url", e.target.value)}
/>
<div className="flex items-center gap-3">
<input
type="checkbox"
id="instagramDisplay"
checked={config.socials.instagram?.display || false}
onChange={(e) => updateSocial("instagram", "display", e.target.checked)}
className="w-5 h-5 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label htmlFor="instagramDisplay" className="text-sm text-gray-700 dark:text-gray-300">
Display on landing page
</label>
</div>
</div>
</div>
{/* Twitter */}
<div className="border-b border-slate-200 dark:border-slate-700 pb-4">
<div className="flex items-center gap-2 mb-3">
<span className="text-xl">🐦</span>
<span className="font-semibold text-gray-900 dark:text-white">Twitter</span>
</div>
<div className="space-y-3">
<input
type="url"
className="input-field"
placeholder="https://twitter.com/yourhandle"
value={config.socials.twitter?.url || ""}
onChange={(e) => updateSocial("twitter", "url", e.target.value)}
/>
<div className="flex items-center gap-3">
<input
type="checkbox"
id="twitterDisplay"
checked={config.socials.twitter?.display || false}
onChange={(e) => updateSocial("twitter", "display", e.target.checked)}
className="w-5 h-5 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label htmlFor="twitterDisplay" className="text-sm text-gray-700 dark:text-gray-300">
Display on landing page
</label>
</div>
</div>
</div>
{/* LinkedIn */}
<div className="border-b border-slate-200 dark:border-slate-700 pb-4">
<div className="flex items-center gap-2 mb-3">
<span className="text-xl">💼</span>
<span className="font-semibold text-gray-900 dark:text-white">LinkedIn</span>
</div>
<div className="space-y-3">
<input
type="url"
className="input-field"
placeholder="https://linkedin.com/company/yourcompany"
value={config.socials.linkedin?.url || ""}
onChange={(e) => updateSocial("linkedin", "url", e.target.value)}
/>
<div className="flex items-center gap-3">
<input
type="checkbox"
id="linkedinDisplay"
checked={config.socials.linkedin?.display || false}
onChange={(e) => updateSocial("linkedin", "display", e.target.checked)}
className="w-5 h-5 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label htmlFor="linkedinDisplay" className="text-sm text-gray-700 dark:text-gray-300">
Display on landing page
</label>
</div>
</div>
</div>
{/* YouTube */}
<div>
<div className="flex items-center gap-2 mb-3">
<span className="text-xl">📺</span>
<span className="font-semibold text-gray-900 dark:text-white">YouTube</span>
</div>
<div className="space-y-3">
<input
type="url"
className="input-field"
placeholder="https://youtube.com/channel/yourchannel"
value={config.socials.youtube?.url || ""}
onChange={(e) => updateSocial("youtube", "url", e.target.value)}
/>
<div className="flex items-center gap-3">
<input
type="checkbox"
id="youtubeDisplay"
checked={config.socials.youtube?.display || false}
onChange={(e) => updateSocial("youtube", "display", e.target.checked)}
className="w-5 h-5 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label htmlFor="youtubeDisplay" className="text-sm text-gray-700 dark:text-gray-300">
Display on landing page
</label>
</div>
</div>
</div>
</div>
</div>
{/* SMTP Email Configuration */}
<div className="card p-6 border border-slate-200/60 dark:border-slate-700/60 shadow-lg">
<div className="flex items-center gap-3 mb-4">
<div className="text-2xl">📧</div>
<div>
<h2 className="text-xl font-bold text-gray-900 dark:text-white">Email (SMTP)</h2>
<p className="text-sm text-gray-600 dark:text-gray-400">Configure email server for notifications and activation</p>
</div>
</div>
<div className="space-y-4">
<div className="flex items-center gap-3">
<input
type="checkbox"
id="smtpEnabled"
checked={config.email.smtp.enabled}
onChange={(e) =>
setConfig({
...config,
email: {
...config.email,
smtp: { ...config.email.smtp, enabled: e.target.checked },
},
})
}
className="w-5 h-5 text-primary border-gray-300 rounded focus:ring-primary"
/>
<label htmlFor="smtpEnabled" className="text-sm font-semibold text-gray-700 dark:text-gray-300">
Enable SMTP Email
</label>
</div>
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
SMTP Host
</label>
<input
type="text"
className="input-field"
placeholder="smtp.gmail.com"
value={config.email.smtp.host}
onChange={(e) =>
setConfig({
...config,
email: {
...config.email,
smtp: { ...config.email.smtp, host: e.target.value },
},
})
}
/>
</div>
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
Port
</label>
<input
type="number"
className="input-field"
placeholder="587"
value={config.email.smtp.port}
onChange={(e) =>
setConfig({
...config,
email: {
...config.email,
smtp: { ...config.email.smtp, port: parseInt(e.target.value) || 587 },
},
})
}
/>
</div>
</div>
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
Username
</label>
<input
type="text"
className="input-field"
placeholder="your-email@gmail.com"
value={config.email.smtp.username}
onChange={(e) =>
setConfig({
...config,
email: {
...config.email,
smtp: { ...config.email.smtp, username: e.target.value },
},
})
}
/>
</div>
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
Password
</label>
<input
type="password"
className="input-field"
placeholder="Your SMTP password or app password"
value={config.email.smtp.password}
onChange={(e) =>
setConfig({
...config,
email: {
...config.email,
smtp: { ...config.email.smtp, password: e.target.value },
},
})
}
/>
</div>
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
From Address
</label>
<input
type="email"
className="input-field"
placeholder="noreply@yourdomain.com"
value={config.email.smtp.from}
onChange={(e) =>
setConfig({
...config,
email: {
...config.email,
smtp: { ...config.email.smtp, from: e.target.value },
},
})
}
/>
</div>
</div>
</div>
{/* Pagination Configuration */}
<div className="card p-6 border border-slate-200/60 dark:border-slate-700/60 shadow-lg">
<div className="flex items-center gap-3 mb-4">
<div className="text-2xl">📄</div>
<div>
<h2 className="text-xl font-bold text-gray-900 dark:text-white">Pagination</h2>
<p className="text-sm text-gray-600 dark:text-gray-400">Configure pagination settings for lists</p>
</div>
</div>
<div className="space-y-4">
<div>
<label className="block text-sm font-semibold text-gray-700 dark:text-gray-300 mb-2">
Items Per Page
</label>
<input
type="number"
min="5"
max="100"
className="input-field"
placeholder="10"
value={config.pagination.itemsPerPage}
onChange={(e) =>
setConfig({
...config,
pagination: {
itemsPerPage: Math.max(5, Math.min(100, parseInt(e.target.value) || 10)),
},
})
}
/>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
Used for users and webinars list (min: 5, max: 100)
</p>
</div>
</div>
</div>
<div className="flex items-center gap-4">
<button onClick={handleSave} disabled={saving} className="btn-primary">
{saving ? "⏳ Saving..." : "💾 Save Settings"}
</button>
{message && (
<span
className={`px-4 py-2 rounded-lg text-sm font-semibold ${
message.includes("✅")
? "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400"
: "bg-red-500/10 text-red-600 dark:text-red-400"
}`}
>
{message}
</span>
)}
</div>
</div>
</main>
);
}