Files
i-tools/app/cron/page.tsx
yfan 3d175d75af
Some checks failed
Build and Push Docker Image / build (push) Has been cancelled
Sync to CNB / sync (push) Has been cancelled
Delete old workflow runs / del_runs (push) Has been cancelled
Upstream Sync / Sync latest commits from upstream repo (push) Has been cancelled
first commit
2026-01-30 16:57:44 +08:00

117 lines
4.4 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState } from "react";
import { Timer, Info } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { toast } from "sonner";
export default function CronPage() {
const [expression, setExpression] = useState("*/5 * * * *");
const parts = expression.split(/\s+/);
const labels = ["分钟", "小时", "日期", "月份", "星期"];
const decodePart = (part: string, type: string) => {
if (!part) return "-";
if (part === "*") return `${type}`;
if (part.includes("/")) {
const [start, step] = part.split("/");
return `每隔 ${step} ${type}${start !== "*" ? ` (从第 ${start} 开始)` : ""}`;
}
if (part.includes("-")) {
return `${part.replace("-", " 到 ")} ${type}`;
}
if (part.includes(",")) {
return `${part} ${type}`;
}
return `${part} ${type}`;
};
return (
<div className="space-y-6 animate-in fade-in slide-in-from-bottom-4 duration-500">
<div className="flex items-center space-x-4 border-b pb-4">
<div className="flex h-12 w-12 items-center justify-center rounded-xl bg-linear-to-br from-orange-500 to-red-600 shadow-lg">
<Timer className="h-6 w-6 text-white" />
</div>
<div>
<h1 className="text-2xl font-bold tracking-tight">Cron </h1>
<p className="text-muted-foreground"> Cron </p>
</div>
</div>
<div className="grid gap-6">
<Card>
<CardHeader>
<CardTitle className="text-base"></CardTitle>
</CardHeader>
<CardContent>
<div className="flex gap-4">
<Input
value={expression}
onChange={(e) => setExpression(e.target.value)}
placeholder="如: */5 * * * *"
className="font-mono text-lg"
/>
<Button onClick={() => toast.success("解析成功")}></Button>
</div>
</CardContent>
</Card>
<div className="grid md:grid-cols-5 gap-4">
{labels.map((label, i) => (
<Card key={label} className="bg-muted/30 border-none">
<CardContent className="pt-6 text-center space-y-2">
<p className="text-xs text-muted-foreground font-bold">{label}</p>
<p className="font-mono text-xl font-bold text-primary">{parts[i] || "*"}</p>
<p className="text-xs text-muted-foreground">{decodePart(parts[i], label)}</p>
</CardContent>
</Card>
))}
</div>
<Card>
<CardHeader>
<CardTitle className="text-base flex items-center gap-2">
<Info className="h-4 w-4" />
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div className="p-4 rounded-lg bg-primary/5 border border-primary/10">
<p className="text-lg">
<span className="font-bold text-primary ml-2">
{parts.length >= 5
? labels.map((l, i) => decodePart(parts[i], l)).join("")
: "请输入完整的 5 位 Cron 表达式"}
</span>
</p>
</div>
<div className="grid grid-cols-2 md:grid-cols-3 gap-4 text-sm text-muted-foreground">
<div className="space-y-1">
<p className="font-bold text-foreground">*</p>
<p></p>
</div>
<div className="space-y-1">
<p className="font-bold text-foreground">/n</p>
<p> ( n)</p>
</div>
<div className="space-y-1">
<p className="font-bold text-foreground">-</p>
<p> ( x y)</p>
</div>
<div className="space-y-1">
<p className="font-bold text-foreground">,</p>
<p></p>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
);
}