feat: dark and light mdoe
This commit is contained in:
@@ -2,94 +2,102 @@
|
||||
|
||||
import { useAuth } from '@/contexts/AuthContext';
|
||||
import Link from 'next/link';
|
||||
import { UsersIcon, CubeIcon, TagIcon , BellIcon, GiftIcon } from '@heroicons/react/24/outline';
|
||||
import { UsersIcon, CubeIcon, TagIcon , BellIcon, GiftIcon, PowerIcon } from '@heroicons/react/24/outline';
|
||||
import { MegaphoneIcon } from 'lucide-react';
|
||||
import ThemeToggle from '@/components/ThemeToggle';
|
||||
// import { BellIcon } from 'lucide-react';
|
||||
|
||||
export default function Dashboard() {
|
||||
const { user, logout } = useAuth();
|
||||
|
||||
const cards = [
|
||||
{
|
||||
href: '/admin/users',
|
||||
title: 'مدیریت کاربران',
|
||||
desc: 'مشاهده و مدیریت کاربران، اشتراکها و تراکنشها',
|
||||
Icon: UsersIcon,
|
||||
iconWrap: 'bg-indigo-100 text-indigo-600 dark:bg-indigo-500/15 dark:text-indigo-400',
|
||||
},
|
||||
{
|
||||
href: '/admin/packages',
|
||||
title: 'مدیریت پکیجها',
|
||||
desc: 'ایجاد و مدیریت پکیجهای نرمافزار',
|
||||
Icon: CubeIcon,
|
||||
iconWrap: 'bg-green-100 text-green-600 dark:bg-green-500/15 dark:text-green-400',
|
||||
},
|
||||
{
|
||||
href: '/admin/products',
|
||||
title: 'مدیریت محصولات',
|
||||
desc: 'ایجاد و مدیریت محصولات و اشتراکها',
|
||||
Icon: TagIcon,
|
||||
iconWrap: 'bg-purple-100 text-purple-600 dark:bg-purple-500/15 dark:text-purple-400',
|
||||
},
|
||||
{
|
||||
href: '/admin/reminders',
|
||||
title: 'مدیریت یادآوریها',
|
||||
desc: 'ایجاد و مدیریت یادآوریها و پیامهای انگیزشی',
|
||||
Icon: BellIcon,
|
||||
iconWrap: 'bg-yellow-100 text-yellow-600 dark:bg-yellow-500/15 dark:text-yellow-400',
|
||||
},
|
||||
{
|
||||
href: '/admin/promotions',
|
||||
title: 'مدیریت تبلیغات',
|
||||
desc: 'ایجاد و مدیریت تبلیغات، بنرها و اسلایدرها',
|
||||
Icon: MegaphoneIcon,
|
||||
iconWrap: 'bg-pink-100 text-pink-600 dark:bg-pink-500/15 dark:text-pink-400',
|
||||
},
|
||||
{
|
||||
href: '/admin/referral-rewards',
|
||||
title: 'پاداشهای معرفی',
|
||||
desc: 'اعطای اشتراک رایگان به کاربران واجد شرایط دعوت',
|
||||
Icon: GiftIcon,
|
||||
iconWrap: 'bg-emerald-100 text-emerald-600 dark:bg-emerald-500/15 dark:text-emerald-400',
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="p-8">
|
||||
<div className="p-4 sm:p-8">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="bg-white rounded-lg shadow-lg p-6">
|
||||
<div className="bg-white dark:bg-gray-900 rounded-2xl shadow-sm ring-1 ring-gray-200 dark:ring-gray-800 p-6">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
|
||||
داشبورد
|
||||
</h1>
|
||||
<button
|
||||
onClick={logout}
|
||||
className="px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700 transition-colors"
|
||||
>
|
||||
خروج
|
||||
</button>
|
||||
<div className="flex items-center gap-2">
|
||||
<ThemeToggle withLabel />
|
||||
<button
|
||||
onClick={logout}
|
||||
className="inline-flex items-center gap-2 px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 dark:focus:ring-offset-gray-900 transition-colors"
|
||||
>
|
||||
<PowerIcon className="h-5 w-5" />
|
||||
خروج
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="border-t pt-6">
|
||||
<h2 className="text-lg font-semibold mb-4 text-slate-900">خوش آمدید، {user?.email}</h2>
|
||||
<div className="border-t border-gray-200 dark:border-gray-800 pt-6">
|
||||
<h2 className="text-lg font-semibold mb-1 text-gray-900 dark:text-gray-100">خوش آمدید، {user?.email}</h2>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6">یکی از بخشهای زیر را برای مدیریت انتخاب کنید.</p>
|
||||
|
||||
{/* Dashboard Cards */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mt-6">
|
||||
<Link href="/admin/users" className="block">
|
||||
<div className="bg-indigo-50 hover:bg-indigo-100 rounded-lg p-6 transition-colors">
|
||||
<UsersIcon className="h-8 w-8 text-indigo-600 mb-3" />
|
||||
<h3 className="text-lg font-medium text-gray-900">مدیریت کاربران</h3>
|
||||
<p className="text-sm text-gray-600 mt-1">
|
||||
مشاهده و مدیریت کاربران، اشتراکها و تراکنشها
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link href="/admin/packages" className="block">
|
||||
<div className="bg-green-50 hover:bg-green-100 rounded-lg p-6 transition-colors">
|
||||
<CubeIcon className="h-8 w-8 text-green-600 mb-3" />
|
||||
<h3 className="text-lg font-medium text-gray-900">مدیریت پکیجها</h3>
|
||||
<p className="text-sm text-gray-600 mt-1">
|
||||
ایجاد و مدیریت پکیجهای نرمافزار
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<Link href="/admin/products" className="block">
|
||||
<div className="bg-purple-50 hover:bg-purple-100 rounded-lg p-6 transition-colors">
|
||||
<TagIcon className="h-8 w-8 text-purple-600 mb-3" />
|
||||
<h3 className="text-lg font-medium text-gray-900">مدیریت محصولات</h3>
|
||||
<p className="text-sm text-gray-600 mt-1">
|
||||
ایجاد و مدیریت محصولات و اشتراکها
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<Link href="/admin/reminders" className="block">
|
||||
<div className="bg-yellow-50 hover:bg-yellow-100 rounded-lg p-6 transition-colors">
|
||||
<BellIcon className="h-8 w-8 text-yellow-600 mb-3" />
|
||||
<h3 className="text-lg font-medium text-gray-900">مدیریت یادآوریها</h3>
|
||||
<p className="text-sm text-gray-600 mt-1">
|
||||
ایجاد و مدیریت یادآوریها و پیامهای انگیزشی
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<Link href="/admin/promotions" className="block">
|
||||
<div className="bg-pink-50 hover:bg-pink-100 rounded-lg p-6 transition-colors">
|
||||
<MegaphoneIcon className="h-8 w-8 text-pink-600 mb-3" />
|
||||
<h3 className="text-lg font-medium text-gray-900">مدیریت تبلیغات</h3>
|
||||
<p className="text-sm text-gray-600 mt-1">
|
||||
ایجاد و مدیریت تبلیغات، بنرها و اسلایدرها
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<Link href="/admin/referral-rewards" className="block">
|
||||
<div className="bg-emerald-50 hover:bg-emerald-100 rounded-lg p-6 transition-colors">
|
||||
<GiftIcon className="h-8 w-8 text-emerald-600 mb-3" />
|
||||
<h3 className="text-lg font-medium text-gray-900">پاداشهای معرفی</h3>
|
||||
<p className="text-sm text-gray-600 mt-1">
|
||||
اعطای اشتراک رایگان به کاربران واجد شرایط دعوت
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
|
||||
{cards.map(({ href, title, desc, Icon, iconWrap }) => (
|
||||
<Link key={href} href={href} className="block group">
|
||||
<div className="h-full bg-white dark:bg-gray-900 rounded-xl p-6 ring-1 ring-gray-200 dark:ring-gray-800 shadow-sm hover:shadow-md hover:ring-indigo-300 dark:hover:ring-indigo-700 hover:-translate-y-0.5 transition-all duration-200">
|
||||
<div className={`inline-flex h-12 w-12 items-center justify-center rounded-xl mb-4 ${iconWrap}`}>
|
||||
<Icon className="h-6 w-6" />
|
||||
</div>
|
||||
<h3 className="text-lg font-medium text-gray-900 dark:text-gray-100">{title}</h3>
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400 mt-1">
|
||||
{desc}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
|
||||
import { AuthProvider } from '@/contexts/AuthContext';
|
||||
import ThemeToggle from '@/components/ThemeToggle';
|
||||
|
||||
export default function AdminLayout({
|
||||
children,
|
||||
@@ -9,8 +10,9 @@ export default function AdminLayout({
|
||||
}) {
|
||||
return (
|
||||
<AuthProvider>
|
||||
<div className="min-h-screen bg-gray-100">
|
||||
<div className="min-h-screen bg-gray-100 dark:bg-gray-950">
|
||||
{children}
|
||||
<ThemeToggle floating />
|
||||
</div>
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
+66
-59
@@ -4,6 +4,7 @@ import { useState } from 'react';
|
||||
import { useAuth } from '@/contexts/AuthContext';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect } from 'react';
|
||||
import { LockClosedIcon } from '@heroicons/react/24/outline';
|
||||
|
||||
export default function LoginPage() {
|
||||
const [auth, setAuth] = useState('');
|
||||
@@ -36,72 +37,78 @@ export default function LoginPage() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-md w-full space-y-8">
|
||||
<div>
|
||||
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
|
||||
پنل ادمین اپروایجنسی
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
|
||||
<div className="min-h-screen flex items-center justify-center bg-gray-100 dark:bg-gray-950 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-md w-full">
|
||||
<div className="bg-white dark:bg-gray-900 rounded-2xl shadow-xl ring-1 ring-gray-200 dark:ring-gray-800 p-8 space-y-8">
|
||||
<div>
|
||||
<div className='py-2'>
|
||||
<label htmlFor="auth" className="sr-only">
|
||||
Email
|
||||
</label>
|
||||
<input
|
||||
id="auth"
|
||||
name="auth"
|
||||
type="text"
|
||||
required
|
||||
className="appearance-none relative block w-full px-3 py-3 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
|
||||
placeholder="ایمیل"
|
||||
value={auth}
|
||||
onChange={(e) => setAuth(e.target.value)}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="password" className="sr-only">
|
||||
Password
|
||||
</label>
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
required
|
||||
className="appearance-none rounded-md relative block w-full px-3 py-3 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-b-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm"
|
||||
placeholder="رمز عبور"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
<div className="mx-auto h-14 w-14 rounded-2xl bg-indigo-600 flex items-center justify-center mb-4">
|
||||
<LockClosedIcon className="h-7 w-7 text-white" />
|
||||
</div>
|
||||
<h2 className="text-center text-2xl font-bold text-gray-900 dark:text-gray-100">
|
||||
پنل ادمین اپروایجنسی
|
||||
</h2>
|
||||
<p className="mt-2 text-center text-sm text-gray-500 dark:text-gray-400">
|
||||
برای ادامه وارد حساب کاربری خود شوید
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{(error || localError) && (
|
||||
<div className="rounded-md bg-red-50 p-4">
|
||||
<div className="flex">
|
||||
<div className="ml-3">
|
||||
<h3 className="text-sm font-medium text-red-800">
|
||||
{localError || error}
|
||||
</h3>
|
||||
</div>
|
||||
<form className="space-y-5" onSubmit={handleSubmit}>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label htmlFor="auth" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
ایمیل
|
||||
</label>
|
||||
<input
|
||||
id="auth"
|
||||
name="auth"
|
||||
type="text"
|
||||
required
|
||||
className="appearance-none relative block w-full px-3 py-3 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 placeholder-gray-400 dark:placeholder-gray-500 text-gray-900 dark:text-gray-100 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm transition-colors"
|
||||
placeholder="example@email.com"
|
||||
value={auth}
|
||||
onChange={(e) => setAuth(e.target.value)}
|
||||
disabled={isLoading}
|
||||
dir="ltr"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label htmlFor="password" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">
|
||||
رمز عبور
|
||||
</label>
|
||||
<input
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
required
|
||||
className="appearance-none relative block w-full px-3 py-3 border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 placeholder-gray-400 dark:placeholder-gray-500 text-gray-900 dark:text-gray-100 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm transition-colors"
|
||||
placeholder="••••••••"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
disabled={isLoading}
|
||||
dir="ltr"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading}
|
||||
className="group relative w-full flex justify-center py-3 px-4 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{isLoading ? 'کمی صبر کنید' : 'ورود'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
{(error || localError) && (
|
||||
<div className="rounded-lg bg-red-50 dark:bg-red-900/20 p-4">
|
||||
<h3 className="text-sm font-medium text-red-800 dark:text-red-300 text-center">
|
||||
{localError || error}
|
||||
</h3>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading}
|
||||
className="group relative w-full flex justify-center py-3 px-4 border border-transparent text-sm font-medium rounded-lg text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-900 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
||||
>
|
||||
{isLoading ? 'کمی صبر کنید...' : 'ورود'}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -104,13 +104,13 @@ export default function PackagesPage() {
|
||||
<div className="p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
|
||||
مدیریت پکیجها
|
||||
</h1>
|
||||
{!isFormVisible && (
|
||||
<button
|
||||
onClick={handleCreate}
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-900 transition-colors"
|
||||
>
|
||||
<PlusIcon className="h-5 w-5 ml-2" />
|
||||
پکیج جدید
|
||||
@@ -120,14 +120,14 @@ export default function PackagesPage() {
|
||||
|
||||
{/* Messages */}
|
||||
{error && (
|
||||
<div className="mb-4 rounded-md bg-red-50 p-4">
|
||||
<p className="text-sm text-red-800">{error}</p>
|
||||
<div className="mb-4 rounded-md bg-red-50 dark:bg-red-900/20 p-4">
|
||||
<p className="text-sm text-red-800 dark:text-red-300">{error}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{success && (
|
||||
<div className="mb-4 rounded-md bg-green-50 p-4">
|
||||
<p className="text-sm text-green-800">{success}</p>
|
||||
<div className="mb-4 rounded-md bg-green-50 dark:bg-green-900/20 p-4">
|
||||
<p className="text-sm text-green-800 dark:text-green-300">{success}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -170,14 +170,14 @@ export default function ProductsPage() {
|
||||
<div className="p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
|
||||
مدیریت محصولات
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Package Selector */}
|
||||
<div className="bg-white p-4 rounded-lg shadow mb-6">
|
||||
<label htmlFor="package" className="block text-sm font-medium text-gray-700 mb-2">
|
||||
<div className="bg-white dark:bg-gray-900 p-4 rounded-lg shadow mb-6">
|
||||
<label htmlFor="package" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||
انتخاب پکیج
|
||||
</label>
|
||||
<select
|
||||
@@ -185,7 +185,7 @@ export default function ProductsPage() {
|
||||
value={selectedPackage?.name || ''}
|
||||
onChange={handlePackageChange}
|
||||
disabled={isLoadingPackages}
|
||||
className="block w-full px-3 py-2 text-slate-900 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:opacity-50"
|
||||
className="block w-full px-3 py-2 text-slate-900 dark:text-gray-100 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:opacity-50 dark:bg-gray-800 dark:placeholder-gray-500 transition-colors"
|
||||
>
|
||||
{isLoadingPackages ? (
|
||||
<option>در حال بارگذاری پکیجها...</option>
|
||||
@@ -201,14 +201,14 @@ export default function ProductsPage() {
|
||||
|
||||
{/* Messages */}
|
||||
{error && (
|
||||
<div className="mb-4 rounded-md bg-red-50 p-4">
|
||||
<p className="text-sm text-red-800">{error}</p>
|
||||
<div className="mb-4 rounded-md bg-red-50 dark:bg-red-900/20 p-4">
|
||||
<p className="text-sm text-red-800 dark:text-red-300">{error}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{success && (
|
||||
<div className="mb-4 rounded-md bg-green-50 p-4">
|
||||
<p className="text-sm text-green-800">{success}</p>
|
||||
<div className="mb-4 rounded-md bg-green-50 dark:bg-green-900/20 p-4">
|
||||
<p className="text-sm text-green-800 dark:text-green-300">{success}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -220,7 +220,7 @@ export default function ProductsPage() {
|
||||
<button
|
||||
onClick={handleCreate}
|
||||
disabled={isLoading}
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50"
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 focus:ring-indigo-500 disabled:opacity-50 transition-colors"
|
||||
>
|
||||
<PlusIcon className="h-5 w-5 ml-2" />
|
||||
محصول جدید
|
||||
|
||||
@@ -123,14 +123,14 @@ export default function PromotionsPage() {
|
||||
<div className="p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
|
||||
مدیریت تبلیغات
|
||||
</h1>
|
||||
{!isFormVisible && (
|
||||
<button
|
||||
onClick={handleCreate}
|
||||
disabled={isLoading}
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50"
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 focus:ring-indigo-500 disabled:opacity-50 transition-colors"
|
||||
>
|
||||
<PlusIcon className="h-5 w-5 ml-2" />
|
||||
تبلیغ جدید
|
||||
@@ -140,14 +140,14 @@ export default function PromotionsPage() {
|
||||
|
||||
{/* Messages */}
|
||||
{error && (
|
||||
<div className="mb-4 rounded-md bg-red-50 p-4">
|
||||
<p className="text-sm text-red-800">{error}</p>
|
||||
<div className="mb-4 rounded-md bg-red-50 dark:bg-red-900/20 p-4">
|
||||
<p className="text-sm text-red-800 dark:text-red-300">{error}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{success && (
|
||||
<div className="mb-4 rounded-md bg-green-50 p-4">
|
||||
<p className="text-sm text-green-800">{success}</p>
|
||||
<div className="mb-4 rounded-md bg-green-50 dark:bg-green-900/20 p-4">
|
||||
<p className="text-sm text-green-800 dark:text-green-300">{success}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
@@ -67,17 +67,17 @@ export default function ReferralRewardsPage() {
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-gray-900">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
|
||||
پاداشهای معرفی
|
||||
</h1>
|
||||
<p className="text-sm text-gray-500 mt-1">
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mt-1">
|
||||
کاربرانی که به حد نصاب دعوت موفق رسیدهاند و هنوز اشتراک رایگان دریافت نکردهاند.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
onClick={loadRewards}
|
||||
disabled={isLoading}
|
||||
className="inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50"
|
||||
className="inline-flex items-center px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-900 disabled:opacity-50 transition-colors"
|
||||
>
|
||||
<ArrowPathIcon className={`h-5 w-5 ml-2 ${isLoading ? 'animate-spin' : ''}`} />
|
||||
بروزرسانی
|
||||
@@ -86,20 +86,20 @@ export default function ReferralRewardsPage() {
|
||||
|
||||
{/* Messages */}
|
||||
{error && (
|
||||
<div className="mb-4 rounded-md bg-red-50 p-4">
|
||||
<p className="text-sm text-red-800">{error}</p>
|
||||
<div className="mb-4 rounded-md bg-red-50 dark:bg-red-900/20 p-4">
|
||||
<p className="text-sm text-red-800 dark:text-red-300">{error}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{success && (
|
||||
<div className="mb-4 rounded-md bg-green-50 p-4">
|
||||
<p className="text-sm text-green-800">{success}</p>
|
||||
<div className="mb-4 rounded-md bg-green-50 dark:bg-green-900/20 p-4">
|
||||
<p className="text-sm text-green-800 dark:text-green-300">{success}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isLoading && users.length === 0 ? (
|
||||
<div className="text-center py-12 bg-white rounded-lg shadow">
|
||||
<p className="text-gray-500">در حال بارگذاری...</p>
|
||||
<div className="text-center py-12 bg-white dark:bg-gray-900 rounded-xl shadow-sm ring-1 ring-gray-200 dark:ring-gray-800">
|
||||
<p className="text-gray-500 dark:text-gray-400">در حال بارگذاری...</p>
|
||||
</div>
|
||||
) : (
|
||||
<ReferralList
|
||||
|
||||
@@ -164,14 +164,14 @@ export default function RemindersPage() {
|
||||
<div className="p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<div className="flex justify-between items-center mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100">
|
||||
مدیریت یادآوریها
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Package Selector */}
|
||||
<div className="bg-white p-4 rounded-lg shadow mb-6">
|
||||
<label htmlFor="package" className="block text-sm font-medium text-gray-700 mb-2">
|
||||
<div className="bg-white dark:bg-gray-900 p-4 rounded-lg shadow mb-6 transition-colors">
|
||||
<label htmlFor="package" className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
|
||||
انتخاب پکیج
|
||||
</label>
|
||||
<select
|
||||
@@ -179,7 +179,7 @@ export default function RemindersPage() {
|
||||
value={selectedPackage?.name || ''}
|
||||
onChange={handlePackageChange}
|
||||
disabled={isLoadingPackages}
|
||||
className="block w-full px-3 py-2 text-slate-900 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:opacity-50"
|
||||
className="block w-full px-3 py-2 text-slate-900 dark:text-gray-100 border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:placeholder-gray-500 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm disabled:opacity-50 transition-colors"
|
||||
>
|
||||
{isLoadingPackages ? (
|
||||
<option>در حال بارگذاری پکیجها...</option>
|
||||
@@ -195,14 +195,14 @@ export default function RemindersPage() {
|
||||
|
||||
{/* Messages */}
|
||||
{error && (
|
||||
<div className="mb-4 rounded-md bg-red-50 p-4">
|
||||
<p className="text-sm text-red-800">{error}</p>
|
||||
<div className="mb-4 rounded-md bg-red-50 dark:bg-red-900/20 p-4">
|
||||
<p className="text-sm text-red-800 dark:text-red-300">{error}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{success && (
|
||||
<div className="mb-4 rounded-md bg-green-50 p-4">
|
||||
<p className="text-sm text-green-800">{success}</p>
|
||||
<div className="mb-4 rounded-md bg-green-50 dark:bg-green-900/20 p-4">
|
||||
<p className="text-sm text-green-800 dark:text-green-300">{success}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -214,7 +214,7 @@ export default function RemindersPage() {
|
||||
<button
|
||||
onClick={handleCreate}
|
||||
disabled={isLoading}
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50"
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 dark:focus:ring-offset-gray-900 focus:ring-indigo-500 disabled:opacity-50 transition-colors"
|
||||
>
|
||||
<PlusIcon className="h-5 w-5 ml-2" />
|
||||
یادآوری جدید
|
||||
|
||||
+19
-19
@@ -230,7 +230,7 @@ export default function UsersPage() {
|
||||
return (
|
||||
<div className="p-6">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
<h1 className="text-2xl font-bold text-gray-900 mb-6">
|
||||
<h1 className="text-2xl font-bold text-gray-900 dark:text-gray-100 mb-6">
|
||||
مدیریت کاربران
|
||||
</h1>
|
||||
|
||||
@@ -251,30 +251,30 @@ export default function UsersPage() {
|
||||
|
||||
{/* Messages */}
|
||||
{error && (
|
||||
<div className="mb-4 rounded-md bg-red-50 p-4">
|
||||
<div className="mb-4 rounded-md bg-red-50 dark:bg-red-900/20 p-4">
|
||||
<div className="flex">
|
||||
<div className="flex-shrink-0">
|
||||
<svg className="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<svg className="h-5 w-5 text-red-400 dark:text-red-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="mr-3">
|
||||
<p className="text-sm text-red-800">{error}</p>
|
||||
<p className="text-sm text-red-800 dark:text-red-300">{error}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{success && (
|
||||
<div className="mb-4 rounded-md bg-green-50 p-4">
|
||||
<div className="mb-4 rounded-md bg-green-50 dark:bg-green-900/20 p-4">
|
||||
<div className="flex">
|
||||
<div className="flex-shrink-0">
|
||||
<svg className="h-5 w-5 text-green-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<svg className="h-5 w-5 text-green-400 dark:text-green-400" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="mr-3">
|
||||
<p className="text-sm text-green-800">{success}</p>
|
||||
<p className="text-sm text-green-800 dark:text-green-300">{success}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -282,40 +282,40 @@ export default function UsersPage() {
|
||||
|
||||
{/* No Package Selected Message */}
|
||||
{!selectedPackage && packages.length === 0 && (
|
||||
<div className="text-center py-12 bg-white rounded-lg shadow">
|
||||
<p className="text-gray-500">هیچ پکیجی یافت نشد. ابتدا یک پکیج ایجاد کنید.</p>
|
||||
<div className="text-center py-12 bg-white dark:bg-gray-900 rounded-xl shadow-sm ring-1 ring-gray-200 dark:ring-gray-800">
|
||||
<p className="text-gray-500 dark:text-gray-400">هیچ پکیجی یافت نشد. ابتدا یک پکیج ایجاد کنید.</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Show products list even without user */}
|
||||
{selectedPackage && products.length > 0 && !user && (
|
||||
<div className="mb-6">
|
||||
<div className="bg-white shadow overflow-hidden sm:rounded-lg">
|
||||
<div className="bg-white dark:bg-gray-900 shadow-sm ring-1 ring-gray-200 dark:ring-gray-800 overflow-hidden sm:rounded-xl">
|
||||
<div className="px-4 py-5 sm:px-6">
|
||||
<h3 className="text-lg leading-6 font-medium text-gray-900">
|
||||
<h3 className="text-lg leading-6 font-medium text-gray-900 dark:text-gray-100">
|
||||
محصولات موجود در پکیج {selectedPackage}
|
||||
</h3>
|
||||
</div>
|
||||
<div className="border-t border-gray-200 px-4 py-5 sm:px-6">
|
||||
<div className="border-t border-gray-200 dark:border-gray-800 px-4 py-5 sm:px-6">
|
||||
<div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{products.map((product) => (
|
||||
<div
|
||||
key={product.id}
|
||||
className="relative block w-full border border-gray-200 rounded-lg p-4 text-right bg-gray-50"
|
||||
className="relative block w-full border border-gray-200 dark:border-gray-800 rounded-lg p-4 text-right bg-gray-50 dark:bg-gray-800/60"
|
||||
>
|
||||
<p className="text-sm font-medium text-gray-900">
|
||||
<p className="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||
{product.title || 'محصول'}
|
||||
</p>
|
||||
<p className="mt-1 text-xs text-gray-500">
|
||||
<p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
|
||||
قیمت: {formatPrice(product.price)} تومان
|
||||
</p>
|
||||
<p className="text-xs text-gray-500">
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
نوع: {getProductTypeLabel(product.type)}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-gray-500 text-center">
|
||||
<p className="mt-4 text-sm text-gray-500 dark:text-gray-400 text-center">
|
||||
برای افزودن اشتراک به کاربر، ابتدا یک کاربر جستجو کنید
|
||||
</p>
|
||||
</div>
|
||||
@@ -331,7 +331,7 @@ export default function UsersPage() {
|
||||
<button
|
||||
onClick={() => setIsEditing(true)}
|
||||
disabled={isLoading}
|
||||
className="inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50"
|
||||
className="inline-flex items-center px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:focus:ring-offset-gray-900 disabled:opacity-50 transition-colors"
|
||||
>
|
||||
<PencilSquareIcon className="h-5 w-5 ml-2" />
|
||||
ویرایش اطلاعات
|
||||
@@ -339,7 +339,7 @@ export default function UsersPage() {
|
||||
<button
|
||||
onClick={handleDeleteUser}
|
||||
disabled={isLoading}
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 disabled:opacity-50"
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 dark:focus:ring-offset-gray-900 disabled:opacity-50 transition-colors"
|
||||
>
|
||||
<TrashIcon className="h-5 w-5 ml-2" />
|
||||
حذف کاربر
|
||||
|
||||
Reference in New Issue
Block a user