optimization
Some checks failed
Deploy MyApp on Same Server / build-and-deploy (push) Failing after 1s
Some checks failed
Deploy MyApp on Same Server / build-and-deploy (push) Failing after 1s
This commit is contained in:
@@ -2,10 +2,13 @@
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { api } from '@/lib/api'
|
||||
import { getCurrentPersianYear } from '@/lib/persian-date'
|
||||
import { Calendar as CalendarIcon, ChevronRight, Database, TrendingUp } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { getCurrentPersianYear } from '@/lib/date/persian-date'
|
||||
import { Calendar as CalendarIcon, Database, TrendingUp } from 'lucide-react'
|
||||
import Loading from '@/components/Loading'
|
||||
import { PageHeader, BackLink, Card } from '@/components/common'
|
||||
import { YearSelector } from '@/components/calendar'
|
||||
import { MonthCard } from '@/components/cards'
|
||||
import { StatsCard } from '@/components/cards'
|
||||
|
||||
const monthNames = ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'مرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند']
|
||||
|
||||
@@ -75,54 +78,36 @@ export default function CalendarPage() {
|
||||
<div className="min-h-screen p-4 md:p-6">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
{/* Header */}
|
||||
<div className="mb-6">
|
||||
<Link
|
||||
href="/"
|
||||
className="inline-flex items-center gap-2 text-sm text-gray-600 hover:text-gray-900 transition-colors mb-4"
|
||||
>
|
||||
<ChevronRight className="w-4 h-4" />
|
||||
بازگشت به صفحه اصلی
|
||||
</Link>
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<div className="inline-flex items-center justify-center w-12 h-12 bg-gradient-to-br from-green-500 to-green-600 rounded-xl shadow-md">
|
||||
<CalendarIcon className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<h1 className="text-2xl md:text-3xl font-bold text-gray-900">انتخاب سال و ماه</h1>
|
||||
</div>
|
||||
</div>
|
||||
<BackLink href="/" label="بازگشت به صفحه اصلی" />
|
||||
<PageHeader
|
||||
icon={CalendarIcon}
|
||||
title="انتخاب سال و ماه"
|
||||
iconGradient="from-green-500 to-green-600"
|
||||
/>
|
||||
|
||||
{/* Main Card */}
|
||||
<div className="bg-white rounded-2xl shadow-lg border border-gray-100 p-6 md:p-8">
|
||||
<Card padding="lg">
|
||||
{/* Year Selector */}
|
||||
<div className="flex flex-wrap items-center justify-center gap-4 mb-6">
|
||||
<label className="text-sm font-medium text-gray-700 flex items-center gap-2">
|
||||
<CalendarIcon className="w-4 h-4 text-gray-500" />
|
||||
انتخاب سال:
|
||||
</label>
|
||||
<select
|
||||
className="px-4 py-2 border-2 border-gray-200 rounded-xl focus:border-green-500 focus:outline-none focus:ring-2 focus:ring-green-500/20 transition-all bg-white font-medium"
|
||||
value={year}
|
||||
onChange={e => setYear(Number(e.target.value))}
|
||||
>
|
||||
{years.map(y => <option key={y} value={y}>{y}</option>)}
|
||||
</select>
|
||||
</div>
|
||||
<YearSelector
|
||||
years={years}
|
||||
selectedYear={year}
|
||||
onYearChange={setYear}
|
||||
className="mb-6"
|
||||
/>
|
||||
|
||||
{/* Summary Stats */}
|
||||
<div className="bg-gradient-to-r from-green-50 to-emerald-50 border border-green-200 rounded-xl p-4 mb-6">
|
||||
<div className="flex items-center justify-center gap-6 flex-wrap">
|
||||
<div className="flex items-center gap-2">
|
||||
<Database className="w-5 h-5 text-green-600" />
|
||||
<span className="text-sm text-gray-700">
|
||||
<span className="font-semibold text-green-700">{totalDays}</span> روز دارای داده
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<TrendingUp className="w-5 h-5 text-green-600" />
|
||||
<span className="text-sm text-gray-700">
|
||||
<span className="font-semibold text-green-700">{totalRecords}</span> رکورد
|
||||
</span>
|
||||
</div>
|
||||
<StatsCard
|
||||
icon={Database}
|
||||
label="روز دارای داده"
|
||||
value={totalDays}
|
||||
/>
|
||||
<StatsCard
|
||||
icon={TrendingUp}
|
||||
label="رکورد"
|
||||
value={totalRecords}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -133,40 +118,17 @@ export default function CalendarPage() {
|
||||
const isActive = activeMonths.includes(m)
|
||||
const stats = monthDays[m]
|
||||
return (
|
||||
<button
|
||||
<MonthCard
|
||||
key={m}
|
||||
name={name}
|
||||
isActive={isActive}
|
||||
stats={stats}
|
||||
onClick={() => isActive && router.replace(`/day-details?deviceId=${deviceId}&year=${year}&month=${m}`)}
|
||||
disabled={!isActive}
|
||||
className={`group relative rounded-xl border-2 p-5 text-center transition-all duration-300 ${
|
||||
isActive
|
||||
? 'bg-white border-green-200 hover:border-green-400 hover:shadow-lg hover:-translate-y-1'
|
||||
: 'bg-gray-50 border-gray-200 opacity-50 cursor-not-allowed'
|
||||
}`}
|
||||
>
|
||||
<div className={`text-lg font-semibold mb-2 ${isActive ? 'text-gray-900' : 'text-gray-400'}`}>
|
||||
{name}
|
||||
</div>
|
||||
{isActive && stats ? (
|
||||
<div className="space-y-1">
|
||||
<div className="inline-flex items-center gap-1 bg-green-600 text-white text-xs rounded-full px-3 py-1.5 font-medium">
|
||||
<Database className="w-3 h-3" />
|
||||
{stats.days} روز
|
||||
</div>
|
||||
<div className="text-xs text-gray-600 mt-2">
|
||||
{stats.records} رکورد
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-xs text-gray-400">بدون داده</div>
|
||||
)}
|
||||
{isActive && (
|
||||
<div className="absolute bottom-0 left-0 right-0 h-1 bg-gradient-to-r from-green-500 to-green-600 rounded-b-xl transform scale-x-0 group-hover:scale-x-100 transition-transform duration-300" />
|
||||
)}
|
||||
</button>
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user