更新管理后台布局,优化菜单项标签,新增支付配置项。同时,调整API响应字段命名,确保一致性,提升代码可读性和维护性。

This commit is contained in:
乘风
2026-02-09 14:33:41 +08:00
parent bee72dc7f8
commit dfbe3eb427
77 changed files with 3041 additions and 240 deletions

View File

@@ -1,2 +1,3 @@
# 开发环境:对接当前 Next 后端(与现网 API 路径完全一致,无缝切换
VITE_API_BASE_URL=http://localhost:3006
# 对接后端 base URL不改 API 路径,仅改此处即可切换 Next → Gin
# VITE_API_BASE_URL=http://localhost:3006
VITE_API_BASE_URL=http://localhost:8080

View File

@@ -1,2 +1,3 @@
# 对接后端 base URL不改 API 路径,仅改此处即可切换 Next → Gin
VITE_API_BASE_URL=http://localhost:3006
# VITE_API_BASE_URL=http://localhost:3006
VITE_API_BASE_URL=http://localhost:8080

View File

@@ -0,0 +1,2 @@
# 开发环境:对接当前 Next 后端(与现网 API 路径完全一致,无缝切换)
VITE_API_BASE_URL=http://localhost:8080

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -4,8 +4,8 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>管理后台 - Soul创业派对</title>
<script type="module" crossorigin src="/assets/index-DX3SXTVU.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-Z7C0sgIG.css">
<script type="module" crossorigin src="/assets/index-BV6dxvbB.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-C8xDvmbL.css">
</head>
<body>
<div id="root"></div>

View File

@@ -39,20 +39,20 @@ interface UserDetail {
phone?: string
nickname: string
avatar?: string
wechat_id?: string
open_id?: string
referral_code: string
referred_by?: string
has_full_book?: boolean
is_admin?: boolean
wechatId?: string
openId?: string
referralCode?: string
referredBy?: string
hasFullBook?: boolean
isAdmin?: boolean
earnings?: number
pending_earnings?: number
referral_count?: number
created_at?: string
updated_at?: string
pendingEarnings?: number
referralCount?: number
createdAt?: string
updatedAt?: string
tags?: string
ckb_tags?: string
ckb_synced_at?: string
ckbTags?: string
ckbSyncedAt?: string
}
interface UserTrack {
@@ -234,19 +234,19 @@ export function UserDetailModal({
<div className="flex-1">
<div className="flex items-center gap-2">
<h3 className="text-lg font-bold text-white">{user.nickname}</h3>
{user.is_admin && (
{user.isAdmin && (
<Badge className="bg-purple-500/20 text-purple-400 border-0"></Badge>
)}
{user.has_full_book && (
{user.hasFullBook && (
<Badge className="bg-green-500/20 text-green-400 border-0"></Badge>
)}
</div>
<p className="text-gray-400 text-sm mt-1">
{user.phone ? `📱 ${user.phone}` : '未绑定手机'}
{user.wechat_id && ` · 💬 ${user.wechat_id}`}
{user.wechatId && ` · 💬 ${user.wechatId}`}
</p>
<p className="text-gray-500 text-xs mt-1">
ID: {user.id} · 广: {user.referral_code}
ID: {user.id} · 广: {user.referralCode ?? '-'}
</p>
</div>
<div className="text-right">
@@ -295,18 +295,18 @@ export function UserDetailModal({
<div className="grid grid-cols-3 gap-4">
<div className="p-4 bg-[#0a1628] rounded-lg">
<p className="text-gray-400 text-sm"></p>
<p className="text-2xl font-bold text-white">{user.referral_count || 0}</p>
<p className="text-2xl font-bold text-white">{user.referralCount ?? 0}</p>
</div>
<div className="p-4 bg-[#0a1628] rounded-lg">
<p className="text-gray-400 text-sm"></p>
<p className="text-2xl font-bold text-yellow-400">
¥{(user.pending_earnings || 0).toFixed(2)}
¥{(user.pendingEarnings ?? 0).toFixed(2)}
</p>
</div>
<div className="p-4 bg-[#0a1628] rounded-lg">
<p className="text-gray-400 text-sm"></p>
<p className="text-sm text-white">
{user.created_at ? new Date(user.created_at).toLocaleDateString() : '-'}
{user.createdAt ? new Date(user.createdAt).toLocaleDateString() : '-'}
</p>
</div>
</div>
@@ -336,7 +336,7 @@ export function UserDetailModal({
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<span className="text-gray-500"></span>
{user.ckb_synced_at ? (
{user.ckbSyncedAt ? (
<Badge className="bg-green-500/20 text-green-400 border-0 ml-1"></Badge>
) : (
<Badge className="bg-gray-500/20 text-gray-400 border-0 ml-1"></Badge>
@@ -345,7 +345,7 @@ export function UserDetailModal({
<div>
<span className="text-gray-500"></span>
<span className="text-gray-300 ml-1">
{user.ckb_synced_at ? new Date(user.ckb_synced_at).toLocaleString() : '-'}
{user.ckbSyncedAt ? new Date(user.ckbSyncedAt).toLocaleString() : '-'}
</span>
</div>
</div>

View File

@@ -119,10 +119,10 @@ function buildTree(sections: SectionListItem[]): Part[] {
}))
}
function parseTxtToJson(content: string, fileName: string): { id: string; title: string; price: number; content?: string; is_free?: boolean }[] {
function parseTxtToJson(content: string, fileName: string): { id: string; title: string; price: number; content?: string; isFree?: boolean }[] {
const lines = content.split('\n')
const sections: { id: string; title: string; price: number; content?: string; is_free?: boolean }[] = []
let currentSection: { id: string; title: string; price: number; content?: string; is_free?: boolean } | null = null
const sections: { id: string; title: string; price: number; content?: string; isFree?: boolean }[] = []
let currentSection: { id: string; title: string; price: number; content?: string; isFree?: boolean } | null = null
let currentContent: string[] = []
let sectionIndex = 1
@@ -137,7 +137,7 @@ function parseTxtToJson(content: string, fileName: string): { id: string; title:
id: `import-${sectionIndex}`,
title: titleMatch[1].replace(/^#+\s*/, '').trim(),
price: 1,
is_free: sectionIndex <= 3,
isFree: sectionIndex <= 3,
}
currentContent = []
sectionIndex++
@@ -148,7 +148,7 @@ function parseTxtToJson(content: string, fileName: string): { id: string; title:
id: `import-${sectionIndex}`,
title: fileName.replace(/\.(txt|md|markdown)$/i, ''),
price: 1,
is_free: true,
isFree: true,
}
currentContent.push(line)
sectionIndex++

View File

@@ -23,7 +23,7 @@ interface UserRow {
id: string
nickname?: string
phone?: string
referral_code?: string
referralCode?: string
createdAt?: string
}
@@ -201,7 +201,7 @@ export function DashboardPage() {
: undefined
const inviteCode =
p.referralCode ||
referrer?.referral_code ||
referrer?.referralCode ||
referrer?.nickname ||
(p.referrerId ? String(p.referrerId).slice(0, 8) : '')
const product = formatOrderProduct(p)

View File

@@ -42,24 +42,22 @@ interface DistributionOverview {
interface Binding {
id: string
referrer_id: string
referrer_name?: string
referrer_code: string
referee_id: string
referee_phone?: string
referee_nickname?: string
bound_at: string
expires_at: string
referrerId: string
referrerName?: string
referrerCode: string
refereeId: string
refereePhone?: string
refereeNickname?: string
boundAt: string
expiresAt: string
status: 'active' | 'converted' | 'expired' | 'cancelled'
commission?: number
}
interface Withdrawal {
id: string
user_id?: string
userId?: string
user_name?: string
userNickname?: string
userName?: string
userPhone?: string
userAvatar?: string
amount: number
@@ -67,17 +65,15 @@ interface Withdrawal {
account?: string
name?: string
status: string
created_at?: string
createdAt?: string
processedAt?: string
completed_at?: string
}
interface User {
id: string
nickname: string
phone: string
referral_code: string
referralCode?: string
}
interface Order {
@@ -165,7 +161,7 @@ export function DistributionPage() {
userNickname: user?.nickname || order.userNickname || '未知用户',
userPhone: user?.phone || order.userPhone || '-',
referrerNickname: referrer?.nickname || null,
referrerCode: referrer?.referral_code || null,
referrerCode: referrer?.referralCode ?? null,
type: order.productType || order.type,
}
})
@@ -197,9 +193,6 @@ export function DistributionPage() {
if (withdrawalsData?.success && withdrawalsData.withdrawals) {
const formatted = withdrawalsData.withdrawals.map((w) => ({
...w,
user_name: w.userNickname ?? w.user_name,
created_at: w.created_at ?? w.createdAt,
completed_at: w.processedAt ?? w.completed_at,
account: w.account ?? '未绑定微信号',
status:
w.status === 'success' ? 'completed' : w.status === 'failed' ? 'rejected' : w.status,
@@ -294,10 +287,10 @@ export function DistributionPage() {
if (searchTerm) {
const term = searchTerm.toLowerCase()
return (
b.referee_nickname?.toLowerCase().includes(term) ||
b.referee_phone?.includes(term) ||
b.referrer_name?.toLowerCase().includes(term) ||
b.referrer_code?.toLowerCase().includes(term)
b.refereeNickname?.toLowerCase().includes(term) ||
b.refereePhone?.includes(term) ||
b.referrerName?.toLowerCase().includes(term) ||
b.referrerCode?.toLowerCase().includes(term)
)
}
return true
@@ -308,7 +301,7 @@ export function DistributionPage() {
if (searchTerm) {
const term = searchTerm.toLowerCase()
return (
w.user_name?.toLowerCase().includes(term) || w.account?.toLowerCase().includes(term)
w.userName?.toLowerCase().includes(term) || w.account?.toLowerCase().includes(term)
)
}
return true
@@ -776,27 +769,27 @@ export function DistributionPage() {
<td className="p-4">
<div>
<p className="text-white font-medium">
{binding.referee_nickname || '匿名用户'}
{binding.refereeNickname || '匿名用户'}
</p>
<p className="text-gray-500 text-xs">{binding.referee_phone}</p>
<p className="text-gray-500 text-xs">{binding.refereePhone}</p>
</div>
</td>
<td className="p-4">
<div>
<p className="text-white">{binding.referrer_name || '-'}</p>
<p className="text-white">{binding.referrerName || '-'}</p>
<p className="text-gray-500 text-xs font-mono">
{binding.referrer_code}
{binding.referrerCode}
</p>
</div>
</td>
<td className="p-4 text-gray-400">
{binding.bound_at
? new Date(binding.bound_at).toLocaleDateString('zh-CN')
{binding.boundAt
? new Date(binding.boundAt).toLocaleDateString('zh-CN')
: '-'}
</td>
<td className="p-4 text-gray-400">
{binding.expires_at
? new Date(binding.expires_at).toLocaleDateString('zh-CN')
{binding.expiresAt
? new Date(binding.expiresAt).toLocaleDateString('zh-CN')
: '-'}
</td>
<td className="p-4">{getStatusBadge(binding.status)}</td>
@@ -874,11 +867,11 @@ export function DistributionPage() {
/>
) : (
<div className="w-8 h-8 rounded-full bg-gray-600 flex items-center justify-center text-white text-sm font-medium">
{(withdrawal.user_name || withdrawal.name || '?').slice(0, 1)}
{(withdrawal.userName || withdrawal.name || '?').slice(0, 1)}
</div>
)}
<p className="text-white font-medium">
{withdrawal.user_name || withdrawal.name}
{withdrawal.userName || withdrawal.name}
</p>
</div>
</td>
@@ -907,10 +900,8 @@ export function DistributionPage() {
</div>
</td>
<td className="p-4 text-gray-400">
{(withdrawal.created_at || withdrawal.createdAt)
? new Date(
withdrawal.created_at || withdrawal.createdAt || '',
).toLocaleString('zh-CN')
{withdrawal.createdAt
? new Date(withdrawal.createdAt).toLocaleString('zh-CN')
: '-'}
</td>
<td className="p-4">{getStatusBadge(withdrawal.status)}</td>

View File

@@ -60,7 +60,7 @@ export function ReferralSettingsPage() {
}
const body = {
key: 'referral_config',
config: safeConfig,
value: safeConfig,
description: '分销 / 推广规则配置',
}
const res = await post<{ success?: boolean; error?: string }>('/api/db/config', body)

View File

@@ -115,13 +115,13 @@ function mergeFromConfigList(list: unknown[]): ReturnType<typeof parseConfigResp
const out: ReturnType<typeof parseConfigResponse> = {}
for (const item of list) {
if (!item || typeof item !== 'object') continue
const row = item as { config_key?: string; config_value?: string }
const key = row.config_key
const row = item as { configKey?: string; configValue?: string }
const key = row.configKey
let val: unknown
try {
val = typeof row.config_value === 'string' ? JSON.parse(row.config_value) : row.config_value
val = typeof row.configValue === 'string' ? JSON.parse(row.configValue) : row.configValue
} catch {
val = row.config_value
val = row.configValue
}
if (key === 'feature_config' && val && typeof val === 'object') out.features = val as Partial<FeatureConfig>
if (key === 'mp_config' && val && typeof val === 'object') out.mpConfig = val as Partial<MpConfig>
@@ -205,7 +205,6 @@ export function SettingsPage() {
const handleSave = async () => {
setIsSaving(true)
try {
await post('/api/db/settings', localSettings).catch(() => {})
await post('/api/db/config', {
key: 'free_chapters',
value: freeChapters,

View File

@@ -37,20 +37,20 @@ import { get, del, post, put } from '@/api/client'
interface User {
id: string
open_id?: string | null
openId?: string | null
phone?: string | null
nickname: string
wechat_id?: string | null
wechatId?: string | null
avatar?: string | null
is_admin?: boolean | number
has_full_book?: boolean | number
referral_code: string
isAdmin?: boolean | number
hasFullBook?: boolean | number
referralCode?: string
earnings: number | string
pending_earnings?: number | string
withdrawn_earnings?: number | string
referral_count: number
created_at: string
updated_at?: string | null
pendingEarnings?: number | string
withdrawnEarnings?: number | string
referralCount?: number
createdAt: string
updatedAt?: string | null
}
export function UsersPage() {
@@ -77,8 +77,8 @@ export function UsersPage() {
phone: '',
nickname: '',
password: '',
is_admin: false,
has_full_book: false,
isAdmin: false,
hasFullBook: false,
})
async function loadUsers() {
@@ -126,8 +126,8 @@ export function UsersPage() {
phone: user.phone || '',
nickname: user.nickname || '',
password: '',
is_admin: !!(user.is_admin ?? false),
has_full_book: !!(user.has_full_book ?? false),
isAdmin: !!(user.isAdmin ?? false),
hasFullBook: !!(user.hasFullBook ?? false),
})
setShowUserModal(true)
}
@@ -138,8 +138,8 @@ export function UsersPage() {
phone: '',
nickname: '',
password: '',
is_admin: false,
has_full_book: false,
isAdmin: false,
hasFullBook: false,
})
setShowUserModal(true)
}
@@ -155,8 +155,8 @@ export function UsersPage() {
const data = await put<{ success?: boolean; error?: string }>('/api/db/users', {
id: editingUser.id,
nickname: formData.nickname,
is_admin: formData.is_admin,
has_full_book: formData.has_full_book,
isAdmin: formData.isAdmin,
hasFullBook: formData.hasFullBook,
...(formData.password && { password: formData.password }),
})
if (!data?.success) {
@@ -168,7 +168,7 @@ export function UsersPage() {
phone: formData.phone,
nickname: formData.nickname,
password: formData.password,
is_admin: formData.is_admin,
isAdmin: formData.isAdmin,
})
if (!data?.success) {
alert('创建失败: ' + (data?.error || '未知错误'))
@@ -329,15 +329,15 @@ export function UsersPage() {
<div className="flex items-center justify-between">
<Label className="text-gray-300"></Label>
<Switch
checked={formData.is_admin}
onCheckedChange={(checked) => setFormData({ ...formData, is_admin: checked })}
checked={formData.isAdmin}
onCheckedChange={(checked) => setFormData({ ...formData, isAdmin: checked })}
/>
</div>
<div className="flex items-center justify-between">
<Label className="text-gray-300"></Label>
<Switch
checked={formData.has_full_book}
onCheckedChange={(checked) => setFormData({ ...formData, has_full_book: checked })}
checked={formData.hasFullBook}
onCheckedChange={(checked) => setFormData({ ...formData, hasFullBook: checked })}
/>
</div>
</div>
@@ -559,19 +559,19 @@ export function UsersPage() {
<div>
<div className="flex items-center gap-2">
<p className="font-medium text-white">{user.nickname}</p>
{user.is_admin && (
{user.isAdmin && (
<Badge className="bg-purple-500/20 text-purple-400 hover:bg-purple-500/20 border-0 text-xs">
</Badge>
)}
{user.open_id && !user.id?.startsWith('user_') && (
{user.openId && !user.id?.startsWith('user_') && (
<Badge className="bg-green-500/20 text-green-400 hover:bg-green-500/20 border-0 text-xs">
</Badge>
)}
</div>
<p className="text-xs text-gray-500 font-mono">
{user.open_id ? user.open_id.slice(0, 12) + '...' : user.id?.slice(0, 12)}
{user.openId ? user.openId.slice(0, 12) + '...' : user.id?.slice(0, 12)}
</p>
</div>
</div>
@@ -584,27 +584,27 @@ export function UsersPage() {
<span className="text-gray-300">{user.phone}</span>
</div>
)}
{user.wechat_id && (
{user.wechatId && (
<div className="flex items-center gap-1 text-xs">
<span className="text-gray-500">💬</span>
<span className="text-gray-300">{user.wechat_id}</span>
<span className="text-gray-300">{user.wechatId}</span>
</div>
)}
{user.open_id && (
{user.openId && (
<div className="flex items-center gap-1 text-xs">
<span className="text-gray-500">🔗</span>
<span className="text-gray-500 truncate max-w-[100px]" title={user.open_id}>
{user.open_id.slice(0, 12)}...
<span className="text-gray-500 truncate max-w-[100px]" title={user.openId}>
{user.openId.slice(0, 12)}...
</span>
</div>
)}
{!user.phone && !user.wechat_id && !user.open_id && (
{!user.phone && !user.wechatId && !user.openId && (
<span className="text-gray-600 text-xs"></span>
)}
</div>
</TableCell>
<TableCell>
{user.has_full_book ? (
{user.hasFullBook ? (
<Badge className="bg-green-500/20 text-green-400 hover:bg-green-500/20 border-0">
</Badge>
@@ -619,9 +619,9 @@ export function UsersPage() {
<div className="text-white font-medium">
¥{parseFloat(String(user.earnings || 0)).toFixed(2)}
</div>
{parseFloat(String(user.pending_earnings || 0)) > 0 && (
{parseFloat(String(user.pendingEarnings || 0)) > 0 && (
<div className="text-xs text-yellow-400">
: ¥{parseFloat(String(user.pending_earnings || 0)).toFixed(2)}
: ¥{parseFloat(String(user.pendingEarnings || 0)).toFixed(2)}
</div>
)}
<div
@@ -632,17 +632,17 @@ export function UsersPage() {
tabIndex={0}
>
<Users className="w-3 h-3" />
{user.referral_count || 0}
{user.referralCount || 0}
</div>
</div>
</TableCell>
<TableCell>
<code className="text-[#38bdac] text-xs bg-[#38bdac]/10 px-2 py-0.5 rounded">
{user.referral_code || '-'}
{user.referralCode || '-'}
</code>
</TableCell>
<TableCell className="text-gray-400">
{user.created_at ? new Date(user.created_at).toLocaleDateString() : '-'}
{user.createdAt ? new Date(user.createdAt).toLocaleDateString() : '-'}
</TableCell>
<TableCell className="text-right">
<div className="flex items-center justify-end gap-1">

View File

@@ -7,10 +7,8 @@ import { get, put } from '@/api/client'
interface Withdrawal {
id: string
user_id?: string
userId?: string
userNickname?: string
user_name?: string
userName?: string
userPhone?: string
userAvatar?: string
referralCode?: string
@@ -20,9 +18,7 @@ interface Withdrawal {
transactionId?: string
errorMessage?: string
createdAt?: string
created_at?: string
processedAt?: string
completed_at?: string
method?: 'wechat' | 'alipay'
account?: string
name?: string
@@ -66,11 +62,7 @@ export function WithdrawalsPage() {
stats?: Partial<Stats>
}>(`/api/admin/withdrawals?status=${filter}`)
if (data?.success) {
const list = (data.withdrawals || []).map((w) => ({
...w,
createdAt: w.created_at ?? w.createdAt,
userNickname: w.user_name ?? w.userNickname,
}))
const list = data.withdrawals || []
setWithdrawals(list)
setStats({
total: data.stats?.total ?? list.length,
@@ -130,7 +122,7 @@ export function WithdrawalsPage() {
try {
const data = await put<{ success?: boolean; error?: string }>(
'/api/admin/withdrawals',
{ id, action: 'reject', reason },
{ id, action: 'reject', errorMessage: reason },
)
if (data?.success) loadWithdrawals()
else alert('操作失败: ' + (data?.error ?? ''))
@@ -310,27 +302,27 @@ export function WithdrawalsPage() {
{withdrawals.map((w) => (
<tr key={w.id} className="hover:bg-[#0a1628] transition-colors">
<td className="p-4 text-gray-400">
{new Date(w.created_at ?? w.createdAt ?? '').toLocaleString()}
{new Date(w.createdAt ?? '').toLocaleString()}
</td>
<td className="p-4">
<div className="flex items-center gap-2">
{w.userAvatar ? (
<img
src={w.userAvatar}
alt={w.userNickname ?? w.user_name ?? ''}
alt={w.userName ?? ''}
className="w-8 h-8 rounded-full object-cover"
/>
) : (
<div className="w-8 h-8 rounded-full bg-[#38bdac]/20 flex items-center justify-center text-sm text-[#38bdac]">
{(w.userNickname ?? w.user_name ?? '?').charAt(0)}
{(w.userName ?? '?').charAt(0)}
</div>
)}
<div>
<p className="font-medium text-white">
{w.userNickname ?? w.user_name ?? '未知'}
{w.userName ?? '未知'}
</p>
<p className="text-xs text-gray-500">
{w.userPhone ?? w.referralCode ?? (w.user_id ?? w.userId ?? '').slice(0, 10)}
{w.userPhone ?? w.referralCode ?? (w.userId ?? '').slice(0, 10)}
</p>
</div>
</div>
@@ -385,9 +377,7 @@ export function WithdrawalsPage() {
)}
</td>
<td className="p-4 text-gray-400">
{(w.processedAt ?? w.completed_at)
? new Date(w.processedAt ?? w.completed_at ?? '').toLocaleString()
: '-'}
{w.processedAt ? new Date(w.processedAt).toLocaleString() : '-'}
</td>
<td className="p-4 text-right">
{(w.status === 'pending' || w.status === 'pending_confirm') && (

View File

@@ -1 +1 @@
{"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/client.ts","./src/components/modules/user/userdetailmodal.tsx","./src/components/ui/badge.tsx","./src/components/ui/button.tsx","./src/components/ui/card.tsx","./src/components/ui/dialog.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/select.tsx","./src/components/ui/slider.tsx","./src/components/ui/switch.tsx","./src/components/ui/table.tsx","./src/components/ui/tabs.tsx","./src/components/ui/textarea.tsx","./src/layouts/adminlayout.tsx","./src/lib/utils.ts","./src/pages/chapters/chapterspage.tsx","./src/pages/content/contentpage.tsx","./src/pages/dashboard/dashboardpage.tsx","./src/pages/distribution/distributionpage.tsx","./src/pages/login/loginpage.tsx","./src/pages/match/matchpage.tsx","./src/pages/orders/orderspage.tsx","./src/pages/payment/paymentpage.tsx","./src/pages/qrcodes/qrcodespage.tsx","./src/pages/referral-settings/referralsettingspage.tsx","./src/pages/settings/settingspage.tsx","./src/pages/site/sitepage.tsx","./src/pages/users/userspage.tsx","./src/pages/withdrawals/withdrawalspage.tsx"],"version":"5.6.3"}
{"root":["./src/app.tsx","./src/main.tsx","./src/vite-env.d.ts","./src/api/client.ts","./src/components/modules/user/userdetailmodal.tsx","./src/components/ui/badge.tsx","./src/components/ui/button.tsx","./src/components/ui/card.tsx","./src/components/ui/dialog.tsx","./src/components/ui/input.tsx","./src/components/ui/label.tsx","./src/components/ui/select.tsx","./src/components/ui/slider.tsx","./src/components/ui/switch.tsx","./src/components/ui/table.tsx","./src/components/ui/tabs.tsx","./src/components/ui/textarea.tsx","./src/layouts/adminlayout.tsx","./src/lib/utils.ts","./src/pages/chapters/chapterspage.tsx","./src/pages/content/contentpage.tsx","./src/pages/dashboard/dashboardpage.tsx","./src/pages/distribution/distributionpage.tsx","./src/pages/login/loginpage.tsx","./src/pages/match/matchpage.tsx","./src/pages/not-found/notfoundpage.tsx","./src/pages/orders/orderspage.tsx","./src/pages/payment/paymentpage.tsx","./src/pages/qrcodes/qrcodespage.tsx","./src/pages/referral-settings/referralsettingspage.tsx","./src/pages/settings/settingspage.tsx","./src/pages/site/sitepage.tsx","./src/pages/users/userspage.tsx","./src/pages/withdrawals/withdrawalspage.tsx"],"version":"5.6.3"}