Initial commit

This commit is contained in:
Developer
2026-02-06 21:44:04 -06:00
commit f85e93c7a6
151 changed files with 22916 additions and 0 deletions

936
app/admin/setup/page.tsx Normal file
View File

@@ -0,0 +1,936 @@
"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>
);
}