feat: add refferal feature
This commit is contained in:
@@ -7,10 +7,12 @@ import { packagesApi } from '@/lib/api/packages';
|
||||
import UserSearch from '@/components/admin/users/UserSearch';
|
||||
import UserInfo from '@/components/admin/users/UserInfo';
|
||||
import UserProducts from '@/components/admin/users/UserProducts';
|
||||
import UserEditForm from '@/components/admin/users/UserEditForm';
|
||||
import PackageSelector from '@/components/admin/users/PackageSelector';
|
||||
import { User, Product } from '@/types/user';
|
||||
import { User, Product, UpdateUserProfileData } from '@/types/user';
|
||||
import { PackageName } from '@/types/package';
|
||||
import { formatPrice, getProductTypeLabel } from '@/lib/utils';
|
||||
import { PencilSquareIcon, TrashIcon } from '@heroicons/react/24/outline';
|
||||
|
||||
export default function UsersPage() {
|
||||
const { token } = useAuth();
|
||||
@@ -21,6 +23,7 @@ export default function UsersPage() {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [success, setSuccess] = useState<string | null>(null);
|
||||
const [isEditing, setIsEditing] = useState(false);
|
||||
|
||||
// Load packages on mount
|
||||
useEffect(() => {
|
||||
@@ -145,6 +148,66 @@ export default function UsersPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const handleEditSubmit = async (data: UpdateUserProfileData) => {
|
||||
if (!user) return;
|
||||
|
||||
const identifier = user.email || user.mobile;
|
||||
|
||||
if (!identifier) {
|
||||
setError('کاربر فاقد ایمیل یا شماره موبایل است');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
setSuccess(null);
|
||||
|
||||
try {
|
||||
await usersApi.updateUserProfile(identifier, data, token!);
|
||||
setSuccess('اطلاعات کاربر با موفقیت بهروزرسانی شد');
|
||||
setIsEditing(false);
|
||||
// Refresh user data using the (possibly) new identifier
|
||||
const newIdentifier = data.email || data.mobile || identifier;
|
||||
if (selectedPackage) {
|
||||
const userData = await usersApi.getUserStatus(newIdentifier, selectedPackage, token!);
|
||||
setUser(userData);
|
||||
}
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'خطا در بهروزرسانی اطلاعات کاربر');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleDeleteUser = async () => {
|
||||
if (!user) return;
|
||||
|
||||
const identifier = user.email || user.mobile;
|
||||
|
||||
if (!identifier) {
|
||||
setError('کاربر فاقد ایمیل یا شماره موبایل است');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!confirm('آیا از حذف این کاربر اطمینان دارید؟ این عملیات قابل بازگشت نیست.')) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
setError(null);
|
||||
setSuccess(null);
|
||||
|
||||
try {
|
||||
await usersApi.deleteUser(identifier, token!);
|
||||
setSuccess('کاربر با موفقیت حذف شد');
|
||||
setUser(null);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'خطا در حذف کاربر');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePackageChange = (packageName: string) => {
|
||||
console.log('Package changed to:', packageName);
|
||||
setSelectedPackage(packageName);
|
||||
@@ -261,7 +324,29 @@ export default function UsersPage() {
|
||||
)}
|
||||
|
||||
{/* User Info */}
|
||||
{user && <UserInfo user={user} />}
|
||||
{user && (
|
||||
<>
|
||||
<UserInfo user={user} />
|
||||
<div className="flex justify-end gap-2 mb-6 -mt-2">
|
||||
<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"
|
||||
>
|
||||
<PencilSquareIcon className="h-5 w-5 ml-2" />
|
||||
ویرایش اطلاعات
|
||||
</button>
|
||||
<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"
|
||||
>
|
||||
<TrashIcon className="h-5 w-5 ml-2" />
|
||||
حذف کاربر
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* User Products */}
|
||||
{user && selectedPackage && (
|
||||
@@ -274,6 +359,16 @@ export default function UsersPage() {
|
||||
selectedPackage={selectedPackage}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Edit User Modal */}
|
||||
{user && isEditing && (
|
||||
<UserEditForm
|
||||
user={user}
|
||||
onSubmit={handleEditSubmit}
|
||||
onCancel={() => setIsEditing(false)}
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user