This commit is contained in:
ryan
2026-07-13 15:44:03 +08:00
parent 0548a8a5d4
commit 26be762c3a
102 changed files with 909 additions and 490 deletions
@@ -4,7 +4,13 @@ import {Search} from 'lucide-react';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from '@/components/ui/select'; import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import type { AccessLogTab, SearchDraft } from './access-log-utils'; import type { AccessLogTab, SearchDraft } from './access-log-utils';
import { PAGE_SIZE_OPTIONS } from './access-log-utils'; import { PAGE_SIZE_OPTIONS } from './access-log-utils';
@@ -15,7 +15,13 @@ import {
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from '@/components/ui/select'; import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
const CLEANUP_PRESETS = [3, 7, 30]; const CLEANUP_PRESETS = [3, 7, 30];
@@ -5,7 +5,13 @@ import {useCallback, useEffect, useState} from 'react';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { HardDrive, RefreshCw, Trash2 } from 'lucide-react'; import { HardDrive, RefreshCw, Trash2 } from 'lucide-react';
import {Card, CardContent, CardDescription, CardHeader, CardTitle,} from '@/components/ui/card'; import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Skeleton } from '@/components/ui/skeleton'; import { Skeleton } from '@/components/ui/skeleton';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
@@ -5,10 +5,22 @@
import * as React from 'react'; import * as React from 'react';
import { Code } from 'lucide-react'; import { Code } from 'lucide-react';
import {Card, CardContent, CardDescription, CardHeader, CardTitle,} from '@/components/ui/card'; import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from '@/components/ui/select'; import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Checkbox } from '@/components/ui/checkbox'; import { Checkbox } from '@/components/ui/checkbox';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
@@ -23,7 +23,14 @@ import {Button} from '@/components/ui/button';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { Checkbox } from '@/components/ui/checkbox'; import { Checkbox } from '@/components/ui/checkbox';
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow,} from '@/components/ui/table'; import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import { import {
AlertDialog, AlertDialog,
AlertDialogAction, AlertDialogAction,
@@ -34,7 +41,13 @@ import {
AlertDialogHeader, AlertDialogHeader,
AlertDialogTitle, AlertDialogTitle,
} from '@/components/ui/alert-dialog'; } from '@/components/ui/alert-dialog';
import {Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle,} from '@/components/ui/sheet'; import {
Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
} from '@/components/ui/sheet';
import { FileImagePreview } from '@/components/common/file-image-preview'; import { FileImagePreview } from '@/components/common/file-image-preview';
import services, { formatFileSize } from '@/lib/services'; import services, { formatFileSize } from '@/lib/services';
import type { Upload as UploadRecord } from '@/lib/services/upload/types'; import type { Upload as UploadRecord } from '@/lib/services/upload/types';
@@ -2,11 +2,34 @@
import * as React from 'react'; import * as React from 'react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import {Database, Files, HardDrive, Info, Loader2, TrendingUp, Upload,} from 'lucide-react'; import {
import {Area, AreaChart, CartesianGrid, Cell, Pie, PieChart, XAxis, YAxis,} from 'recharts'; Database,
Files,
HardDrive,
Info,
Loader2,
TrendingUp,
Upload,
} from 'lucide-react';
import {
Area,
AreaChart,
CartesianGrid,
Cell,
Pie,
PieChart,
XAxis,
YAxis,
} from 'recharts';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import {Card, CardContent, CardDescription, CardHeader, CardTitle,} from '@/components/ui/card'; import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { import {
ChartConfig, ChartConfig,
ChartContainer, ChartContainer,
@@ -17,7 +17,14 @@ limitations under the License.
'use client'; 'use client';
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import {BarChart3, Globe, RefreshCw, TrendingUp, Users, XCircle,} from 'lucide-react'; import {
BarChart3,
Globe,
RefreshCw,
TrendingUp,
Users,
XCircle,
} from 'lucide-react';
import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts'; import { Area, AreaChart, CartesianGrid, XAxis, YAxis } from 'recharts';
import services from '@/lib/services'; import services from '@/lib/services';
@@ -26,8 +33,19 @@ import {LoadingStateWithBorder} from '@/components/layout/loading';
import { EmptyStateWithBorder } from '@/components/layout/empty'; import { EmptyStateWithBorder } from '@/components/layout/empty';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import {Card, CardContent, CardDescription, CardHeader, CardTitle,} from '@/components/ui/card'; import {
import {ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent,} from '@/components/ui/chart'; Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import {
ChartConfig,
ChartContainer,
ChartTooltip,
ChartTooltipContent,
} from '@/components/ui/chart';
import { Spinner } from '@/components/ui/spinner'; import { Spinner } from '@/components/ui/spinner';
interface TrendData { interface TrendData {
@@ -20,7 +20,16 @@ import {useMemo, useState} from 'react';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { format } from 'date-fns'; import { format } from 'date-fns';
import {Activity, ChevronLeft, ChevronRight, Copy, Eye, RotateCcw, Search, XCircle,} from 'lucide-react'; import {
Activity,
ChevronLeft,
ChevronRight,
Copy,
Eye,
RotateCcw,
Search,
XCircle,
} from 'lucide-react';
import services from '@/lib/services'; import services from '@/lib/services';
import { ErrorInline } from '@/components/layout/error'; import { ErrorInline } from '@/components/layout/error';
@@ -30,8 +39,21 @@ import {Badge} from '@/components/ui/badge';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import {Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle,} from '@/components/ui/sheet'; import {
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow,} from '@/components/ui/table'; Sheet,
SheetContent,
SheetDescription,
SheetHeader,
SheetTitle,
} from '@/components/ui/sheet';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
interface AccessLog { interface AccessLog {
id: string; id: string;
@@ -6,7 +6,14 @@
import * as React from 'react'; import * as React from 'react';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner'; import { toast } from 'sonner';
import {ChevronDown, Edit2, Layers, Loader2, Plus, Trash2,} from 'lucide-react'; import {
ChevronDown,
Edit2,
Layers,
Loader2,
Plus,
Trash2,
} from 'lucide-react';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
@@ -14,8 +21,20 @@ import {Label} from '@/components/ui/label';
import { Textarea } from '@/components/ui/textarea'; import { Textarea } from '@/components/ui/textarea';
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow,} from '@/components/ui/table'; import {
import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger,} from '@/components/ui/tooltip'; Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from '@/components/ui/tooltip';
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@@ -24,16 +43,30 @@ import {
DialogHeader, DialogHeader,
DialogTitle, DialogTitle,
} from '@/components/ui/dialog'; } from '@/components/ui/dialog';
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from '@/components/ui/select'; import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Checkbox } from '@/components/ui/checkbox'; import { Checkbox } from '@/components/ui/checkbox';
import {Popover, PopoverContent, PopoverTrigger,} from '@/components/ui/popover'; import {
Popover,
PopoverContent,
PopoverTrigger,
} from '@/components/ui/popover';
import { ErrorInline } from '@/components/layout/error'; import { ErrorInline } from '@/components/layout/error';
import { LoadingStateWithBorder } from '@/components/layout/loading'; import { LoadingStateWithBorder } from '@/components/layout/loading';
import { EmptyStateWithBorder } from '@/components/layout/empty'; import { EmptyStateWithBorder } from '@/components/layout/empty';
import services from '@/lib/services'; import services from '@/lib/services';
import type {CreatePushEventRequest, PushEvent, UpdatePushEventRequest,} from '@/lib/services/push'; import type {
CreatePushEventRequest,
PushEvent,
UpdatePushEventRequest,
} from '@/lib/services/push';
import { PushService } from '@/lib/services/push'; import { PushService } from '@/lib/services/push';
export function EventsTab() { export function EventsTab() {
@@ -2,7 +2,13 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import {Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle,} from '@/components/ui/dialog'; import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
@@ -2,7 +2,13 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import {Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle,} from '@/components/ui/dialog'; import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
@@ -1,7 +1,13 @@
'use client'; 'use client';
import { TrendChart } from '@/components/data/trend-chart'; import { TrendChart } from '@/components/data/trend-chart';
import {Card, CardContent, CardDescription, CardHeader, CardTitle,} from '@/components/ui/card'; import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import type { CapacityTrendPoint } from '@/lib/services/openflare'; import type { CapacityTrendPoint } from '@/lib/services/openflare';
import { formatPercent, formatTrendHour } from './dashboard-utils'; import { formatPercent, formatTrendHour } from './dashboard-utils';
@@ -1,8 +1,17 @@
'use client'; 'use client';
import { RankChart } from '@/components/data/rank-chart'; import { RankChart } from '@/components/data/rank-chart';
import {Card, CardContent, CardDescription, CardHeader, CardTitle,} from '@/components/ui/card'; import {
import type {DistributionItem, TrafficDistributions,} from '@/lib/services/openflare'; Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import type {
DistributionItem,
TrafficDistributions,
} from '@/lib/services/openflare';
function toRankItems(items: DistributionItem[]) { function toRankItems(items: DistributionItem[]) {
return items.map((item) => ({ return items.map((item) => ({
@@ -2,7 +2,13 @@
import { Globe2 } from 'lucide-react'; import { Globe2 } from 'lucide-react';
import {Card, CardContent, CardDescription, CardHeader, CardTitle,} from '@/components/ui/card'; import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Progress } from '@/components/ui/progress'; import { Progress } from '@/components/ui/progress';
import type { DistributionItem } from '@/lib/services/openflare'; import type { DistributionItem } from '@/lib/services/openflare';
@@ -3,8 +3,21 @@
import { Loader2 } from 'lucide-react'; import { Loader2 } from 'lucide-react';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
import {Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle,} from '@/components/ui/dialog'; import {
import {Table, TableBody, TableCell, TableHead, TableHeader, TableRow,} from '@/components/ui/table'; Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import type { ConfigDiffResult } from '@/lib/services/openflare'; import type { ConfigDiffResult } from '@/lib/services/openflare';
interface DiffDialogProps { interface DiffDialogProps {
@@ -14,7 +14,11 @@ import {
DialogTitle, DialogTitle,
} from '@/components/ui/dialog'; } from '@/components/ui/dialog';
import { formatDateTime } from '@/lib/utils'; import { formatDateTime } from '@/lib/utils';
import type {NodeAgentReleaseInfo, NodeItem, ReleaseChannel,} from '@/lib/services/openflare'; import type {
NodeAgentReleaseInfo,
NodeItem,
ReleaseChannel,
} from '@/lib/services/openflare';
import { NodeService } from '@/lib/services/openflare'; import { NodeService } from '@/lib/services/openflare';
import { NodeStatusBadge } from './node-status-badge'; import { NodeStatusBadge } from './node-status-badge';
@@ -1,10 +1,19 @@
'use client'; 'use client';
import { TrendChart } from '@/components/data/trend-chart'; import { TrendChart } from '@/components/data/trend-chart';
import {Card, CardContent, CardDescription, CardHeader, CardTitle,} from '@/components/ui/card'; import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import type { DiskIOTrendPoint } from '@/lib/services/openflare'; import type { DiskIOTrendPoint } from '@/lib/services/openflare';
import {formatBytes, formatTrendHour,} from '../../components/dashboard/dashboard-utils'; import {
formatBytes,
formatTrendHour,
} from '../../components/dashboard/dashboard-utils';
export function DiskIOTrendChart({ export function DiskIOTrendChart({
points, points,
@@ -4,7 +4,17 @@ import Link from 'next/link';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useMutation, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useState } from 'react'; import { useState } from 'react';
import {Activity, Cpu, FileText, Fingerprint, Package, RefreshCw, RotateCcw, Trash2, Upload,} from 'lucide-react'; import {
Activity,
Cpu,
FileText,
Fingerprint,
Package,
RefreshCw,
RotateCcw,
Trash2,
Upload,
} from 'lucide-react';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { import {
@@ -19,12 +29,20 @@ import {
} from '@/components/ui/alert-dialog'; } from '@/components/ui/alert-dialog';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { formatDateTime } from '@/lib/utils'; import { formatDateTime } from '@/lib/utils';
import type {NodeAgentReleaseInfo, NodeItem, ReleaseChannel,} from '@/lib/services/openflare'; import type {
NodeAgentReleaseInfo,
NodeItem,
ReleaseChannel,
} from '@/lib/services/openflare';
import { NodeService } from '@/lib/services/openflare'; import { NodeService } from '@/lib/services/openflare';
import { AgentUpdateDialog } from './agent-update-dialog'; import { AgentUpdateDialog } from './agent-update-dialog';
import { NodeDetailShell } from './node-detail-shell'; import { NodeDetailShell } from './node-detail-shell';
import {NodeErrorBanner, NodeInfoRow, NodeSectionCard,} from './node-detail-primitives'; import {
NodeErrorBanner,
NodeInfoRow,
NodeSectionCard,
} from './node-detail-primitives';
import { NodeEditorDialog } from './node-editor-dialog'; import { NodeEditorDialog } from './node-editor-dialog';
import { NodeObservability } from './node-observability'; import { NodeObservability } from './node-observability';
import { NodeStatusBadge } from './node-status-badge'; import { NodeStatusBadge } from './node-status-badge';
@@ -20,7 +20,12 @@ import {Progress} from '@/components/ui/progress';
import { PagesService } from '@/lib/services/openflare'; import { PagesService } from '@/lib/services/openflare';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import {deploymentsQueryKey, formatBytes, projectQueryKey, projectsQueryKey,} from './pages-utils'; import {
deploymentsQueryKey,
formatBytes,
projectQueryKey,
projectsQueryKey,
} from './pages-utils';
interface DeploymentUploadDialogProps { interface DeploymentUploadDialogProps {
open: boolean; open: boolean;
@@ -6,9 +6,23 @@ import {useForm} from 'react-hook-form';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { z } from 'zod'; import { z } from 'zod';
import {Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage,} from '@/components/ui/form'; import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from '@/components/ui/select'; import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import type { ProxyRouteItem } from '@/lib/services/openflare'; import type { ProxyRouteItem } from '@/lib/services/openflare';
import { proxyRouteFormIds } from '../helpers'; import { proxyRouteFormIds } from '../helpers';
@@ -5,13 +5,30 @@ import {zodResolver} from '@hookform/resolvers/zod';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { z } from 'zod'; import { z } from 'zod';
import {Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage,} from '@/components/ui/form'; import {
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from '@/components/ui/select'; Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
import { Textarea } from '@/components/ui/textarea'; import { Textarea } from '@/components/ui/textarea';
import type { ProxyRouteItem } from '@/lib/services/openflare'; import type { ProxyRouteItem } from '@/lib/services/openflare';
import {linesFromTextarea, validateCacheRules,} from '../../components/helpers'; import {
linesFromTextarea,
validateCacheRules,
} from '../../components/helpers';
import { proxyRouteFormIds } from '../helpers'; import { proxyRouteFormIds } from '../helpers';
import { useRouteSectionSave } from '../hooks/use-route-section-save'; import { useRouteSectionSave } from '../hooks/use-route-section-save';
import { SectionShell } from './section-shell'; import { SectionShell } from './section-shell';
@@ -6,7 +6,15 @@ import {useQuery} from '@tanstack/react-query';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { z } from 'zod'; import { z } from 'zod';
import {Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage,} from '@/components/ui/form'; import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
import type { ProxyRouteItem } from '@/lib/services/openflare'; import type { ProxyRouteItem } from '@/lib/services/openflare';
@@ -7,16 +7,35 @@ import {useForm} from 'react-hook-form';
import { ChevronDown, Loader2 } from 'lucide-react'; import { ChevronDown, Loader2 } from 'lucide-react';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import {Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle,} from '@/components/ui/dialog'; import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from '@/components/ui/select'; import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
import { Textarea } from '@/components/ui/textarea'; import { Textarea } from '@/components/ui/textarea';
import type { TlsCertificateItem } from '@/lib/services/openflare'; import type { TlsCertificateItem } from '@/lib/services/openflare';
import {DnsAccountService, TlsCertificateService,} from '@/lib/services/openflare'; import {
DnsAccountService,
TlsCertificateService,
} from '@/lib/services/openflare';
import {type AcmeApplyFormValues, acmeApplySchema, defaultAcmeApplyValues,} from './schemas'; import {
type AcmeApplyFormValues,
acmeApplySchema,
defaultAcmeApplyValues,
} from './schemas';
import { getErrorMessage } from './website-utils'; import { getErrorMessage } from './website-utils';
const certificatesQueryKey = ['openflare', 'tls-certificates']; const certificatesQueryKey = ['openflare', 'tls-certificates'];
@@ -24,7 +24,11 @@ import {Textarea} from '@/components/ui/textarea';
import type { TlsCertificateItem } from '@/lib/services/openflare'; import type { TlsCertificateItem } from '@/lib/services/openflare';
import { TlsCertificateService } from '@/lib/services/openflare'; import { TlsCertificateService } from '@/lib/services/openflare';
import {defaultManualImportValues, type ManualImportFormValues, manualImportSchema,} from './schemas'; import {
defaultManualImportValues,
type ManualImportFormValues,
manualImportSchema,
} from './schemas';
import { getErrorMessage, toManualPayload } from './website-utils'; import { getErrorMessage, toManualPayload } from './website-utils';
const certificatesQueryKey = ['openflare', 'tls-certificates']; const certificatesQueryKey = ['openflare', 'tls-certificates'];
@@ -7,7 +7,13 @@ import {useForm} from 'react-hook-form';
import { Loader2 } from 'lucide-react'; import { Loader2 } from 'lucide-react';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import {Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle,} from '@/components/ui/dialog'; import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
@@ -22,7 +28,11 @@ import {
type ManualImportFormValues, type ManualImportFormValues,
manualImportSchema, manualImportSchema,
} from './schemas'; } from './schemas';
import {getErrorMessage, toFilePayload, toManualPayload,} from './website-utils'; import {
getErrorMessage,
toFilePayload,
toManualPayload,
} from './website-utils';
const certificatesQueryKey = ['openflare', 'tls-certificates']; const certificatesQueryKey = ['openflare', 'tls-certificates'];
@@ -18,7 +18,13 @@ import {
} from '@/components/ui/dialog'; } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import {Select, SelectContent, SelectItem, SelectTrigger, SelectValue,} from '@/components/ui/select'; import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
import type { DnsAccountMutationPayload } from '@/lib/services/openflare'; import type { DnsAccountMutationPayload } from '@/lib/services/openflare';
import { DnsAccountService } from '@/lib/services/openflare'; import { DnsAccountService } from '@/lib/services/openflare';
@@ -3,7 +3,12 @@
import * as React from 'react'; import * as React from 'react';
import { motion, type Variants } from 'motion/react'; import { motion, type Variants } from 'motion/react';
import {getVariants, type IconProps, IconWrapper, useAnimateIconContext,} from '@/components/animate-ui/icons/icon'; import {
getVariants,
type IconProps,
IconWrapper,
useAnimateIconContext,
} from '@/components/animate-ui/icons/icon';
type CheckProps = IconProps<keyof typeof animations>; type CheckProps = IconProps<keyof typeof animations>;
@@ -3,7 +3,12 @@
import * as React from 'react'; import * as React from 'react';
import { motion, type Variants } from 'motion/react'; import { motion, type Variants } from 'motion/react';
import {getVariants, type IconProps, IconWrapper, useAnimateIconContext,} from '@/components/animate-ui/icons/icon'; import {
getVariants,
type IconProps,
IconWrapper,
useAnimateIconContext,
} from '@/components/animate-ui/icons/icon';
type ChevronDownProps = IconProps<keyof typeof animations>; type ChevronDownProps = IconProps<keyof typeof animations>;
@@ -3,7 +3,12 @@
import * as React from 'react'; import * as React from 'react';
import { motion, type Variants } from 'motion/react'; import { motion, type Variants } from 'motion/react';
import {getVariants, type IconProps, IconWrapper, useAnimateIconContext,} from '@/components/animate-ui/icons/icon'; import {
getVariants,
type IconProps,
IconWrapper,
useAnimateIconContext,
} from '@/components/animate-ui/icons/icon';
type ChevronLeftProps = IconProps<keyof typeof animations>; type ChevronLeftProps = IconProps<keyof typeof animations>;
@@ -3,7 +3,12 @@
import * as React from 'react'; import * as React from 'react';
import { motion, type Variants } from 'motion/react'; import { motion, type Variants } from 'motion/react';
import {getVariants, type IconProps, IconWrapper, useAnimateIconContext,} from '@/components/animate-ui/icons/icon'; import {
getVariants,
type IconProps,
IconWrapper,
useAnimateIconContext,
} from '@/components/animate-ui/icons/icon';
type ChevronRightProps = IconProps<keyof typeof animations>; type ChevronRightProps = IconProps<keyof typeof animations>;
@@ -3,7 +3,12 @@
import * as React from 'react'; import * as React from 'react';
import { motion, type Variants } from 'motion/react'; import { motion, type Variants } from 'motion/react';
import {getVariants, type IconProps, IconWrapper, useAnimateIconContext,} from '@/components/animate-ui/icons/icon'; import {
getVariants,
type IconProps,
IconWrapper,
useAnimateIconContext,
} from '@/components/animate-ui/icons/icon';
type CircleCheckProps = IconProps<keyof typeof animations>; type CircleCheckProps = IconProps<keyof typeof animations>;
@@ -3,7 +3,10 @@
import * as React from 'react'; import * as React from 'react';
import { type HTMLMotionProps, motion } from 'motion/react'; import { type HTMLMotionProps, motion } from 'motion/react';
import {Slot, type WithAsChild,} from '@/components/animate-ui/primitives/animate/slot'; import {
Slot,
type WithAsChild,
} from '@/components/animate-ui/primitives/animate/slot';
type ButtonProps = WithAsChild< type ButtonProps = WithAsChild<
HTMLMotionProps<'button'> & { HTMLMotionProps<'button'> & {
+7 -1
View File
@@ -1,7 +1,13 @@
'use client'; 'use client';
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import {CheckCircle2, Loader2, ShieldAlert, ShieldCheck, ShieldQuestion,} from 'lucide-react'; import {
CheckCircle2,
Loader2,
ShieldAlert,
ShieldCheck,
ShieldQuestion,
} from 'lucide-react';
import { getCapToken } from '@/lib/cap-solver'; import { getCapToken } from '@/lib/cap-solver';
type CapStatus = 'idle' | 'solving' | 'solved' | 'error'; type CapStatus = 'idle' | 'solving' | 'solved' | 'error';
@@ -4,10 +4,27 @@ import * as React from 'react';
import Link from 'next/link'; import Link from 'next/link';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { motion } from 'motion/react'; import { motion } from 'motion/react';
import {AlertTriangle, Check, Copy, Info, Key, Loader2, Plus, RefreshCw, Shield, Trash2,} from 'lucide-react'; import {
AlertTriangle,
Check,
Copy,
Info,
Key,
Loader2,
Plus,
RefreshCw,
Shield,
Trash2,
} from 'lucide-react';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import {Card, CardContent, CardDescription, CardHeader, CardTitle,} from '@/components/ui/card'; import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge'; import { Badge } from '@/components/ui/badge';
@@ -3,7 +3,13 @@
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import {Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle,} from '@/components/ui/dialog'; import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label'; import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch'; import { Switch } from '@/components/ui/switch';
+5 -1
View File
@@ -1,7 +1,11 @@
'use client'; 'use client';
import * as React from 'react'; import * as React from 'react';
import {ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon,} from 'lucide-react'; import {
ChevronDownIcon,
ChevronLeftIcon,
ChevronRightIcon,
} from 'lucide-react';
import { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker'; import { DayButton, DayPicker, getDefaultClassNames } from 'react-day-picker';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
+3 -1
View File
@@ -1,7 +1,9 @@
'use client'; 'use client';
import * as React from 'react'; import * as React from 'react';
import useEmblaCarousel, {type UseEmblaCarouselType,} from 'embla-carousel-react'; import useEmblaCarousel, {
type UseEmblaCarouselType,
} from 'embla-carousel-react';
import { ArrowLeft, ArrowRight } from 'lucide-react'; import { ArrowLeft, ArrowRight } from 'lucide-react';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
+7 -1
View File
@@ -6,7 +6,13 @@ import {SearchIcon} from 'lucide-react';
import { motion } from 'motion/react'; import { motion } from 'motion/react';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import {Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle,} from '@/components/ui/dialog'; import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
function Command({ function Command({
className, className,
+11 -2
View File
@@ -1,10 +1,19 @@
'use client'; 'use client';
import * as React from 'react'; import * as React from 'react';
import {createContext, useCallback, useContext, useRef, useState} from 'react'; import {
createContext,
useCallback,
useContext,
useRef,
useState,
} from 'react';
import { useQueryClient } from '@tanstack/react-query'; import { useQueryClient } from '@tanstack/react-query';
import type {SystemConfig, UpdateSystemConfigRequest,} from '@/lib/services/admin'; import type {
SystemConfig,
UpdateSystemConfigRequest,
} from '@/lib/services/admin';
import services from '@/lib/services'; import services from '@/lib/services';
import { handleContextError } from '@/lib/utils/error-handling'; import { handleContextError } from '@/lib/utils/error-handling';
+14 -2
View File
@@ -1,9 +1,21 @@
'use client'; 'use client';
import * as React from 'react'; import * as React from 'react';
import {createContext, useCallback, useContext, useEffect, useRef, useState} from 'react'; import {
createContext,
useCallback,
useContext,
useEffect,
useRef,
useState,
} from 'react';
import { toast } from 'sonner'; import { toast } from 'sonner';
import type {AdminUser, CreateUserRequest, ListUsersRequest, UpdateUserRequest,} from '@/lib/services/admin'; import type {
AdminUser,
CreateUserRequest,
ListUsersRequest,
UpdateUserRequest,
} from '@/lib/services/admin';
import services from '@/lib/services'; import services from '@/lib/services';
/** 用户列表查询参数 */ /** 用户列表查询参数 */
+7 -1
View File
@@ -1,6 +1,12 @@
'use client'; 'use client';
import {createContext, useCallback, useContext, useRef, useState,} from 'react'; import {
createContext,
useCallback,
useContext,
useRef,
useState,
} from 'react';
interface BellRingContextType { interface BellRingContextType {
isRinging: boolean; isRinging: boolean;
@@ -1,5 +1,9 @@
import { BaseService } from '@/lib/services/core'; import { BaseService } from '@/lib/services/core';
import type {AuthSource, AuthSourceRequest, ToggleAuthSourceRequest,} from './types'; import type {
AuthSource,
AuthSourceRequest,
ToggleAuthSourceRequest,
} from './types';
export class AdminAuthSourceService extends BaseService { export class AdminAuthSourceService extends BaseService {
protected static readonly basePath = '/api/v1/admin'; protected static readonly basePath = '/api/v1/admin';
+6 -1
View File
@@ -1,4 +1,9 @@
import axios, {AxiosError, AxiosResponse, CancelTokenSource, InternalAxiosRequestConfig,} from 'axios'; import axios, {
AxiosError,
AxiosResponse,
CancelTokenSource,
InternalAxiosRequestConfig,
} from 'axios';
import { toast } from 'sonner'; import { toast } from 'sonner';
import { apiConfig, getApiBaseUrl } from './config'; import { apiConfig, getApiBaseUrl } from './config';
import { import {
@@ -2,7 +2,11 @@ import type {InternalAxiosRequestConfig} from 'axios';
import apiClient from '@/lib/services/core/api-client'; import apiClient from '@/lib/services/core/api-client';
import { BaseService } from '@/lib/services/core'; import { BaseService } from '@/lib/services/core';
import type {DBOverview, ExecuteSQLResponse, TableDataResponse,} from './types'; import type {
DBOverview,
ExecuteSQLResponse,
TableDataResponse,
} from './types';
/** /**
* 数据库管理服务类 * 数据库管理服务类
@@ -1,5 +1,10 @@
import { OpenFlareBaseService } from './base.service'; import { OpenFlareBaseService } from './base.service';
import type {ApplyLogCleanupPayload, ApplyLogCleanupResult, ApplyLogList, ApplyLogListQuery,} from './types'; import type {
ApplyLogCleanupPayload,
ApplyLogCleanupResult,
ApplyLogList,
ApplyLogListQuery,
} from './types';
export class ApplyLogService extends OpenFlareBaseService { export class ApplyLogService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/d/apply-logs'; protected static override readonly basePath: string = '/api/v1/d/apply-logs';
+7 -1
View File
@@ -1,6 +1,12 @@
'use client'; 'use client';
import React, {createContext, useCallback, useContext, useEffect, useState,} from 'react'; import React, {
createContext,
useCallback,
useContext,
useEffect,
useState,
} from 'react';
import { useTheme as useNextTheme } from 'next-themes'; import { useTheme as useNextTheme } from 'next-themes';
import type { Theme } from './types'; import type { Theme } from './types';
import { getStoredThemeId, setStoredThemeId } from './storage'; import { getStoredThemeId, setStoredThemeId } from './storage';