Files
users/components/dialogs/schedule-calendar-dialog.tsx
v0 b17b488f8e refactor: restructure navigation and module layout
Reorganize navigation and module structure based on new requirements.

Co-authored-by: null <4804959+fnvtk@users.noreply.github.com>
2026-01-31 04:32:36 +00:00

122 lines
4.5 KiB
TypeScript

"use client"
import { useState } from "react"
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { ChevronLeft, ChevronRight } from "lucide-react"
interface ScheduleCalendarDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
}
const MOCK_SCHEDULE = [
{
day: 12,
tasks: [
{ name: "数据同步", type: "sync" },
{ name: "CLV训练", type: "model" },
],
},
{ day: 13, tasks: [{ name: "标签计算", type: "tagging" }] },
{
day: 14,
tasks: [
{ name: "数据清洗", type: "cleaning" },
{ name: "RFM评估", type: "model" },
],
},
{ day: 15, tasks: [{ name: "流失预警", type: "model" }] },
{ day: 16, tasks: [{ name: "数据同步", type: "sync" }] },
{ day: 18, tasks: [{ name: "用户分群", type: "tagging" }] },
{ day: 20, tasks: [{ name: "数据清洗", type: "cleaning" }] },
]
const TYPE_COLORS: Record<string, string> = {
sync: "bg-blue-100 text-blue-700",
cleaning: "bg-green-100 text-green-700",
tagging: "bg-purple-100 text-purple-700",
model: "bg-orange-100 text-orange-700",
}
export function ScheduleCalendarDialog({ open, onOpenChange }: ScheduleCalendarDialogProps) {
const [currentMonth, setCurrentMonth] = useState(new Date(2025, 11))
const daysInMonth = new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1, 0).getDate()
const firstDayOfMonth = new Date(currentMonth.getFullYear(), currentMonth.getMonth(), 1).getDay()
const days = Array.from({ length: daysInMonth }, (_, i) => i + 1)
const emptyDays = Array.from({ length: firstDayOfMonth }, (_, i) => i)
const getTasksForDay = (day: number) => {
return MOCK_SCHEDULE.find((s) => s.day === day)?.tasks || []
}
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[800px]">
<DialogHeader>
<DialogTitle></DialogTitle>
</DialogHeader>
<div className="space-y-4">
<div className="flex items-center justify-between">
<Button
variant="ghost"
size="sm"
onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() - 1))}
>
<ChevronLeft className="w-4 h-4" />
</Button>
<span className="font-semibold">
{currentMonth.getFullYear()}{currentMonth.getMonth() + 1}
</span>
<Button
variant="ghost"
size="sm"
onClick={() => setCurrentMonth(new Date(currentMonth.getFullYear(), currentMonth.getMonth() + 1))}
>
<ChevronRight className="w-4 h-4" />
</Button>
</div>
<div className="grid grid-cols-7 gap-1">
{["日", "一", "二", "三", "四", "五", "六"].map((day) => (
<div key={day} className="text-center text-sm font-medium text-gray-500 py-2">
{day}
</div>
))}
{emptyDays.map((i) => (
<div key={`empty-${i}`} className="h-24" />
))}
{days.map((day) => {
const tasks = getTasksForDay(day)
return (
<div key={day} className="h-24 border border-gray-100 rounded-lg p-1 hover:bg-gray-50">
<div className="text-sm font-medium text-gray-700">{day}</div>
<div className="space-y-1 mt-1">
{tasks.slice(0, 2).map((task, i) => (
<Badge key={i} className={`text-xs px-1 py-0 ${TYPE_COLORS[task.type]}`}>
{task.name}
</Badge>
))}
{tasks.length > 2 && <span className="text-xs text-gray-400">+{tasks.length - 2}</span>}
</div>
</div>
)
})}
</div>
<div className="flex items-center gap-4 pt-4 border-t">
<span className="text-sm text-gray-500">:</span>
<Badge className="bg-blue-100 text-blue-700"></Badge>
<Badge className="bg-green-100 text-green-700"></Badge>
<Badge className="bg-purple-100 text-purple-700"></Badge>
<Badge className="bg-orange-100 text-orange-700"></Badge>
</div>
</div>
</DialogContent>
</Dialog>
)
}