index.tsx 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. import { ConfigDrawer } from '@/components/config-drawer'
  2. import { Header } from '@/components/layout/header'
  3. import { Main } from '@/components/layout/main'
  4. import { ProfileDropdown } from '@/components/profile-dropdown'
  5. import { Search } from '@/components/search'
  6. import { ThemeSwitch } from '@/components/theme-switch'
  7. import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
  8. import {
  9. Video,
  10. Users,
  11. Eye,
  12. TrendingUp,
  13. Play,
  14. Clock,
  15. CheckCircle,
  16. } from 'lucide-react'
  17. export function Dashboard() {
  18. return (
  19. <>
  20. <Header>
  21. <Search className='me-auto' />
  22. <ThemeSwitch />
  23. <ConfigDrawer />
  24. <ProfileDropdown />
  25. </Header>
  26. <Main>
  27. <div className='mb-6 flex items-center justify-between'>
  28. <div>
  29. <h2 className='text-2xl font-bold tracking-tight'>داشبورد</h2>
  30. <p className='text-muted-foreground'>
  31. به پنل ادمین تلنت‌یار خوش آمدید.
  32. </p>
  33. </div>
  34. </div>
  35. {/* کارت‌های آماری */}
  36. <div className='mb-6 grid gap-4 md:grid-cols-2 lg:grid-cols-4'>
  37. <Card>
  38. <CardHeader className='flex flex-row items-center justify-between pb-2'>
  39. <CardTitle className='text-sm font-medium'>کل ویدیوها</CardTitle>
  40. <Video className='h-4 w-4 text-muted-foreground' />
  41. </CardHeader>
  42. <CardContent>
  43. <div className='text-2xl font-bold'>2,847</div>
  44. <p className='mt-1 text-xs text-muted-foreground'>+156 این ماه</p>
  45. </CardContent>
  46. </Card>
  47. <Card>
  48. <CardHeader className='flex flex-row items-center justify-between pb-2'>
  49. <CardTitle className='text-sm font-medium'>کل بازدیدها</CardTitle>
  50. <Eye className='h-4 w-4 text-muted-foreground' />
  51. </CardHeader>
  52. <CardContent>
  53. <div className='text-2xl font-bold'>45,231</div>
  54. <p className='mt-1 text-xs text-muted-foreground'>
  55. +18% نسبت به ماه قبل
  56. </p>
  57. </CardContent>
  58. </Card>
  59. <Card>
  60. <CardHeader className='flex flex-row items-center justify-between pb-2'>
  61. <CardTitle className='text-sm font-medium'>
  62. ورزشکاران فعال
  63. </CardTitle>
  64. <Users className='h-4 w-4 text-muted-foreground' />
  65. </CardHeader>
  66. <CardContent>
  67. <div className='text-2xl font-bold'>1,234</div>
  68. <p className='mt-1 text-xs text-muted-foreground'>
  69. 892 نفر این ماه فعال بودند
  70. </p>
  71. </CardContent>
  72. </Card>
  73. <Card>
  74. <CardHeader className='flex flex-row items-center justify-between pb-2'>
  75. <CardTitle className='text-sm font-medium'>
  76. ویدیوهای امروز
  77. </CardTitle>
  78. <TrendingUp className='h-4 w-4 text-muted-foreground' />
  79. </CardHeader>
  80. <CardContent>
  81. <div className='text-2xl font-bold'>23</div>
  82. <p className='mt-1 text-xs text-muted-foreground'>
  83. ویدیوی جدید آپلود شده
  84. </p>
  85. </CardContent>
  86. </Card>
  87. </div>
  88. <div className='grid gap-6 md:grid-cols-2'>
  89. {/* ویدیوهای اخیر */}
  90. <Card>
  91. <CardHeader>
  92. <CardTitle className='flex items-center gap-2'>
  93. <Play className='h-5 w-5' />
  94. ویدیوهای اخیر
  95. </CardTitle>
  96. </CardHeader>
  97. <CardContent>
  98. <div className='space-y-4'>
  99. {[
  100. {
  101. user: 'علی احمدی',
  102. sport: 'فوتبال',
  103. time: '5 دقیقه پیش',
  104. views: 124,
  105. status: 'pending',
  106. },
  107. {
  108. user: 'مریم رضایی',
  109. sport: 'والیبال',
  110. time: '15 دقیقه پیش',
  111. views: 89,
  112. status: 'approved',
  113. },
  114. {
  115. user: 'حسین محمدی',
  116. sport: 'بسکتبال',
  117. time: '30 دقیقه پیش',
  118. views: 256,
  119. status: 'approved',
  120. },
  121. {
  122. user: 'فاطمه کریمی',
  123. sport: 'تنیس',
  124. time: '1 ساعت پیش',
  125. views: 178,
  126. status: 'pending',
  127. },
  128. {
  129. user: 'رضا نوری',
  130. sport: 'شنا',
  131. time: '2 ساعت پیش',
  132. views: 312,
  133. status: 'approved',
  134. },
  135. ].map((video, i) => (
  136. <div
  137. key={i}
  138. className='flex items-center justify-between border-b pb-3 last:border-0 last:pb-0'
  139. >
  140. <div className='flex-1'>
  141. <div className='flex items-center gap-2'>
  142. <p className='font-medium'>{video.user}</p>
  143. {video.status === 'approved' ? (
  144. <CheckCircle className='h-4 w-4 text-green-500' />
  145. ) : (
  146. <Clock className='h-4 w-4 text-yellow-500' />
  147. )}
  148. </div>
  149. <p className='text-sm text-muted-foreground'>
  150. {video.sport}
  151. </p>
  152. </div>
  153. <div className='text-left'>
  154. <p className='flex items-center gap-1 text-sm font-medium'>
  155. <Eye className='h-3 w-3' />
  156. {video.views}
  157. </p>
  158. <span className='text-xs text-muted-foreground'>
  159. {video.time}
  160. </span>
  161. </div>
  162. </div>
  163. ))}
  164. </div>
  165. </CardContent>
  166. </Card>
  167. {/* ویدیوهای در انتظار تأیید */}
  168. <Card>
  169. <CardHeader>
  170. <CardTitle className='flex items-center gap-2'>
  171. <Clock className='h-5 w-5' />
  172. در انتظار بررسی
  173. </CardTitle>
  174. </CardHeader>
  175. <CardContent>
  176. <div className='space-y-4'>
  177. {[
  178. {
  179. user: 'محمد حسینی',
  180. sport: 'کاراته',
  181. time: '10 دقیقه پیش',
  182. duration: '2:34',
  183. },
  184. {
  185. user: 'زهرا اکبری',
  186. sport: 'ژیمناستیک',
  187. time: '25 دقیقه پیش',
  188. duration: '3:12',
  189. },
  190. {
  191. user: 'امیر رستمی',
  192. sport: 'دوومیدانی',
  193. time: '45 دقیقه پیش',
  194. duration: '1:45',
  195. },
  196. {
  197. user: 'سارا محمودی',
  198. sport: 'بدمینتون',
  199. time: '1 ساعت پیش',
  200. duration: '2:58',
  201. },
  202. {
  203. user: 'پویا کریمی',
  204. sport: 'کشتی',
  205. time: '2 ساعت پیش',
  206. duration: '4:21',
  207. },
  208. ].map((video, i) => (
  209. <div
  210. key={i}
  211. className='flex items-center justify-between border-b pb-3 last:border-0 last:pb-0'
  212. >
  213. <div className='flex-1'>
  214. <p className='font-medium'>{video.user}</p>
  215. <p className='text-sm text-muted-foreground'>
  216. {video.sport}
  217. </p>
  218. </div>
  219. <div className='text-left'>
  220. <p className='text-sm font-medium'>{video.duration}</p>
  221. <span className='text-xs text-muted-foreground'>
  222. {video.time}
  223. </span>
  224. </div>
  225. </div>
  226. ))}
  227. </div>
  228. </CardContent>
  229. </Card>
  230. </div>
  231. {/* محبوب‌ترین رشته‌ها */}
  232. <Card className='mt-6'>
  233. <CardHeader>
  234. <CardTitle>محبوب‌ترین رشته‌های ورزشی</CardTitle>
  235. </CardHeader>
  236. <CardContent>
  237. <div className='grid gap-4 md:grid-cols-3 lg:grid-cols-5'>
  238. {[
  239. { sport: 'فوتبال', count: 487, color: 'bg-secondary' },
  240. { sport: 'والیبال', count: 356, color: 'bg-secondary' },
  241. { sport: 'بسکتبال', count: 298, color: 'bg-secondary' },
  242. { sport: 'کاراته', count: 234, color: 'bg-secondary' },
  243. { sport: 'شنا', count: 189, color: 'bg-secondary' },
  244. ].map((item, i) => (
  245. <div
  246. key={i}
  247. className='flex flex-col items-center gap-2 rounded-lg border p-4'
  248. >
  249. <div
  250. className={`h-12 w-12 rounded-full ${item.color} flex items-center justify-center font-bold`}
  251. >
  252. {item.count}
  253. </div>
  254. <p className='font-medium'>{item.sport}</p>
  255. <p className='text-xs text-muted-foreground'>ویدیو</p>
  256. </div>
  257. ))}
  258. </div>
  259. </CardContent>
  260. </Card>
  261. </Main>
  262. </>
  263. )
  264. }