This commit is contained in:
parent
65c0033cca
commit
34dc5b0f87
|
|
@ -44,7 +44,7 @@ export default function AnalysisPage() {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-br from-blue-50 via-purple-50 to-pink-50 dark:from-gray-900 dark:via-purple-900/20 dark:to-blue-900/20">
|
<div className="min-h-screen bg-gradient-to-br from-purple-50/30 via-pink-50/20 to-purple-50/30 dark:from-gray-950 dark:via-purple-950/40 dark:to-gray-950">
|
||||||
<div className="container mx-auto px-4 py-12">
|
<div className="container mx-auto px-4 py-12">
|
||||||
<div className="max-w-6xl mx-auto space-y-8">
|
<div className="max-w-6xl mx-auto space-y-8">
|
||||||
{/* 標題區域 - 置中對齊 */}
|
{/* 標題區域 - 置中對齊 */}
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ export default function AnalysisResultsPage() {
|
||||||
const currentReport = getNestedValue(analysisResult.reports, currentAnalyst?.reportKey || "");
|
const currentReport = getNestedValue(analysisResult.reports, currentAnalyst?.reportKey || "");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-br from-blue-50 via-purple-50 to-pink-50 dark:from-gray-900 dark:via-purple-900/20 dark:to-blue-900/20">
|
<div className="min-h-screen bg-gradient-to-br from-purple-50/30 via-pink-50/20 to-purple-50/30 dark:from-gray-950 dark:via-purple-950/40 dark:to-gray-950">
|
||||||
<div className="container mx-auto px-4 py-12">
|
<div className="container mx-auto px-4 py-12">
|
||||||
<div className="max-w-7xl mx-auto space-y-8">
|
<div className="max-w-7xl mx-auto space-y-8">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
|
|
@ -180,7 +180,7 @@ export default function AnalysisResultsPage() {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 分析師報告 */}
|
{/* 分析師報告 */}
|
||||||
<Card className="animate-scale-up hover-lift gradient-card gradient-shine">
|
<Card className="animate-scale-up hover-lift">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>{analyst.label} 報告</CardTitle>
|
<CardTitle>{analyst.label} 報告</CardTitle>
|
||||||
<CardDescription>
|
<CardDescription>
|
||||||
|
|
|
||||||
|
|
@ -257,13 +257,13 @@
|
||||||
GRADIENT UTILITIES
|
GRADIENT UTILITIES
|
||||||
======================================== */
|
======================================== */
|
||||||
|
|
||||||
/* Gradient Backgrounds */
|
/* Gradient Backgrounds - Purple/Pink theme */
|
||||||
.gradient-bg-primary {
|
.gradient-bg-primary {
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: linear-gradient(135deg, #9333EA 0%, #EC4899 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .gradient-bg-primary {
|
.dark .gradient-bg-primary {
|
||||||
background: linear-gradient(135deg, #4c51bf 0%, #553c9a 100%);
|
background: linear-gradient(135deg, #7C3AED 0%, #DB2777 100%);
|
||||||
}
|
}
|
||||||
|
|
||||||
.gradient-bg-secondary {
|
.gradient-bg-secondary {
|
||||||
|
|
@ -410,9 +410,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gradient Text */
|
/* Gradient Text - Purple/Pink theme */
|
||||||
.gradient-text-primary {
|
.gradient-text-primary {
|
||||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
background: linear-gradient(135deg, #9333EA 0%, #EC4899 100%);
|
||||||
-webkit-background-clip: text;
|
-webkit-background-clip: text;
|
||||||
-webkit-text-fill-color: transparent;
|
-webkit-text-fill-color: transparent;
|
||||||
background-clip: text;
|
background-clip: text;
|
||||||
|
|
@ -535,181 +535,67 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========================================
|
/* ========================================
|
||||||
DATE PICKER CUSTOM STYLING
|
GLASSMORPHISM UTILITIES
|
||||||
======================================== */
|
======================================== */
|
||||||
|
|
||||||
/* Modern Date Input Styling */
|
/* Base glassmorphism style - Subtle white with hint of pink */
|
||||||
input[type="date"] {
|
.glass {
|
||||||
position: relative;
|
background: rgba(255, 255, 255, 0.95);
|
||||||
padding: 0.75rem 1rem;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 1.5;
|
|
||||||
color: var(--foreground);
|
|
||||||
background: linear-gradient(
|
|
||||||
135deg,
|
|
||||||
rgba(102, 126, 234, 0.05) 0%,
|
|
||||||
rgba(118, 75, 162, 0.05) 100%
|
|
||||||
);
|
|
||||||
border: 2px solid rgba(102, 126, 234, 0.3);
|
|
||||||
border-radius: 0.75rem;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
cursor: pointer;
|
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
-webkit-backdrop-filter: blur(10px);
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid rgba(147, 51, 234, 0.08);
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(147, 51, 234, 0.04);
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="date"]:hover {
|
.dark .glass {
|
||||||
|
background: rgba(30, 20, 40, 0.95);
|
||||||
|
border: 1px solid rgba(147, 51, 234, 0.15);
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enhanced glass with gradient - Very subtle pink/purple tint */
|
||||||
|
.glass-gradient {
|
||||||
background: linear-gradient(
|
background: linear-gradient(
|
||||||
135deg,
|
135deg,
|
||||||
rgba(102, 126, 234, 0.1) 0%,
|
rgba(255, 255, 255, 0.98) 0%,
|
||||||
rgba(118, 75, 162, 0.1) 100%
|
rgba(252, 248, 255, 0.98) 100%
|
||||||
);
|
);
|
||||||
border-color: rgba(102, 126, 234, 0.5);
|
backdrop-filter: blur(10px);
|
||||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
border: 1px solid rgba(147, 51, 234, 0.1);
|
||||||
|
box-shadow: 0 2px 16px 0 rgba(147, 51, 234, 0.06),
|
||||||
|
inset 0 1px 0 0 rgba(255, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .glass-gradient {
|
||||||
|
background: linear-gradient(
|
||||||
|
135deg,
|
||||||
|
rgba(30, 20, 40, 0.95) 0%,
|
||||||
|
rgba(40, 25, 50, 0.95) 100%
|
||||||
|
);
|
||||||
|
border: 1px solid rgba(147, 51, 234, 0.2);
|
||||||
|
box-shadow: 0 2px 16px 0 rgba(147, 51, 234, 0.15),
|
||||||
|
inset 0 1px 0 0 rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Glass hover effect - Subtle */
|
||||||
|
.glass-hover {
|
||||||
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.glass-hover:hover {
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
border-color: rgba(147, 51, 234, 0.15);
|
||||||
|
box-shadow: 0 4px 20px 0 rgba(147, 51, 234, 0.1),
|
||||||
|
inset 0 1px 0 0 rgba(255, 255, 255, 0.8);
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="date"]:focus {
|
.dark .glass-hover:hover {
|
||||||
outline: none;
|
background: rgba(30, 20, 40, 1);
|
||||||
background: linear-gradient(
|
border-color: rgba(147, 51, 234, 0.3);
|
||||||
135deg,
|
box-shadow: 0 4px 20px 0 rgba(147, 51, 234, 0.2),
|
||||||
rgba(102, 126, 234, 0.15) 0%,
|
inset 0 1px 0 0 rgba(255, 255, 255, 0.1);
|
||||||
rgba(118, 75, 162, 0.15) 100%
|
|
||||||
);
|
|
||||||
border-color: rgba(102, 126, 234, 0.6);
|
|
||||||
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1),
|
|
||||||
0 8px 16px rgba(102, 126, 234, 0.25);
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dark mode date input */
|
|
||||||
.dark input[type="date"] {
|
|
||||||
background: linear-gradient(
|
|
||||||
135deg,
|
|
||||||
rgba(76, 81, 191, 0.15) 0%,
|
|
||||||
rgba(85, 60, 154, 0.15) 100%
|
|
||||||
);
|
|
||||||
border-color: rgba(76, 81, 191, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark input[type="date"]:hover {
|
|
||||||
background: linear-gradient(
|
|
||||||
135deg,
|
|
||||||
rgba(76, 81, 191, 0.2) 0%,
|
|
||||||
rgba(85, 60, 154, 0.2) 100%
|
|
||||||
);
|
|
||||||
border-color: rgba(76, 81, 191, 0.6);
|
|
||||||
box-shadow: 0 4px 12px rgba(76, 81, 191, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark input[type="date"]:focus {
|
|
||||||
background: linear-gradient(
|
|
||||||
135deg,
|
|
||||||
rgba(76, 81, 191, 0.25) 0%,
|
|
||||||
rgba(85, 60, 154, 0.25) 100%
|
|
||||||
);
|
|
||||||
border-color: rgba(76, 81, 191, 0.7);
|
|
||||||
box-shadow: 0 0 0 3px rgba(76, 81, 191, 0.15),
|
|
||||||
0 8px 16px rgba(76, 81, 191, 0.35);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calendar icon styling */
|
|
||||||
input[type="date"]::-webkit-calendar-picker-indicator {
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0.8;
|
|
||||||
padding: 0.25rem;
|
|
||||||
border-radius: 0.375rem;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
filter: brightness(0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="date"]::-webkit-calendar-picker-indicator:hover {
|
|
||||||
opacity: 1;
|
|
||||||
background: rgba(102, 126, 234, 0.15);
|
|
||||||
transform: scale(1.1);
|
|
||||||
filter: brightness(1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark input[type="date"]::-webkit-calendar-picker-indicator {
|
|
||||||
filter: invert(1) brightness(0.9);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark input[type="date"]::-webkit-calendar-picker-indicator:hover {
|
|
||||||
background: rgba(76, 81, 191, 0.25);
|
|
||||||
filter: invert(1) brightness(1.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Date input inner elements (webkit) */
|
|
||||||
input[type="date"]::-webkit-datetime-edit-fields-wrapper {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="date"]::-webkit-datetime-edit-text {
|
|
||||||
padding: 0 0.25rem;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="date"]::-webkit-datetime-edit-month-field,
|
|
||||||
input[type="date"]::-webkit-datetime-edit-day-field,
|
|
||||||
input[type="date"]::-webkit-datetime-edit-year-field {
|
|
||||||
padding: 0.25rem 0.5rem;
|
|
||||||
border-radius: 0.375rem;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="date"]::-webkit-datetime-edit-month-field:hover,
|
|
||||||
input[type="date"]::-webkit-datetime-edit-day-field:hover,
|
|
||||||
input[type="date"]::-webkit-datetime-edit-year-field:hover {
|
|
||||||
background: rgba(102, 126, 234, 0.2);
|
|
||||||
color: var(--foreground);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="date"]::-webkit-datetime-edit-month-field:focus,
|
|
||||||
input[type="date"]::-webkit-datetime-edit-day-field:focus,
|
|
||||||
input[type="date"]::-webkit-datetime-edit-year-field:focus {
|
|
||||||
background: rgba(102, 126, 234, 0.25);
|
|
||||||
color: var(--foreground);
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark input[type="date"]::-webkit-datetime-edit-month-field:hover,
|
|
||||||
.dark input[type="date"]::-webkit-datetime-edit-day-field:hover,
|
|
||||||
.dark input[type="date"]::-webkit-datetime-edit-year-field:hover {
|
|
||||||
background: rgba(76, 81, 191, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark input[type="date"]::-webkit-datetime-edit-month-field:focus,
|
|
||||||
.dark input[type="date"]::-webkit-datetime-edit-day-field:focus,
|
|
||||||
.dark input[type="date"]::-webkit-datetime-edit-year-field:focus {
|
|
||||||
background: rgba(76, 81, 191, 0.35);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Placeholder styling when empty */
|
|
||||||
input[type="date"]:invalid::-webkit-datetime-edit {
|
|
||||||
color: var(--muted-foreground);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Animation for date picker open */
|
|
||||||
@keyframes datePickerSlide {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-10px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Additional polish */
|
|
||||||
input[type="date"]::before {
|
|
||||||
content: attr(placeholder);
|
|
||||||
width: 100%;
|
|
||||||
color: var(--muted-foreground);
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="date"]:focus::before,
|
|
||||||
input[type="date"]:valid::before {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import {
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-gradient-to-br from-blue-50 via-purple-50 to-pink-50 dark:from-gray-900 dark:via-purple-900/20 dark:to-blue-900/20">
|
<div className="min-h-screen bg-gradient-to-br from-purple-50/30 via-pink-50/20 to-purple-50/30 dark:from-gray-950 dark:via-purple-950/40 dark:to-gray-950">
|
||||||
<div className="container mx-auto px-4 py-12">
|
<div className="container mx-auto px-4 py-12">
|
||||||
{/* Hero Section */}
|
{/* Hero Section */}
|
||||||
<div className="text-center mb-16 animate-fade-in relative py-8">
|
<div className="text-center mb-16 animate-fade-in relative py-8">
|
||||||
|
|
@ -248,7 +248,7 @@ export default function HomePage() {
|
||||||
<p className="text-center text-gray-600 dark:text-gray-400 mb-8 max-w-3xl mx-auto">
|
<p className="text-center text-gray-600 dark:text-gray-400 mb-8 max-w-3xl mx-auto">
|
||||||
TradingAgentsX 模擬真實交易公司,配備專業化的 LLM 代理
|
TradingAgentsX 模擬真實交易公司,配備專業化的 LLM 代理
|
||||||
</p>
|
</p>
|
||||||
<Card className="shadow-lg gradient-card gradient-shine hover-lift">
|
<Card className="shadow-lg hover-lift">
|
||||||
<CardContent className="pt-6">
|
<CardContent className="pt-6">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<WorkflowStep
|
<WorkflowStep
|
||||||
|
|
@ -356,7 +356,7 @@ function FeatureCard({
|
||||||
icon: string;
|
icon: string;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Card className="hover-lift animate-slide-up gradient-shine gradient-card">
|
<Card className="hover-lift animate-slide-up">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<div className="text-4xl mb-2">{icon}</div>
|
<div className="text-4xl mb-2">{icon}</div>
|
||||||
<CardTitle className="text-lg">{title}</CardTitle>
|
<CardTitle className="text-lg">{title}</CardTitle>
|
||||||
|
|
@ -380,7 +380,7 @@ function AgentCard({
|
||||||
responsibilities: string[];
|
responsibilities: string[];
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Card className="hover-lift animate-scale-up gradient-card">
|
<Card className="hover-lift animate-scale-up">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-base">{name}</CardTitle>
|
<CardTitle className="text-base">{name}</CardTitle>
|
||||||
<CardDescription className="text-xs">{role}</CardDescription>
|
<CardDescription className="text-xs">{role}</CardDescription>
|
||||||
|
|
@ -421,7 +421,7 @@ function LLMProviderCard({
|
||||||
const logoSrc = logoMap[name];
|
const logoSrc = logoMap[name];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="hover-lift animate-slide-up animate-delay-100 gradient-card gradient-shine">
|
<Card className="hover-lift animate-slide-up animate-delay-100">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
{logoSrc ? (
|
{logoSrc ? (
|
||||||
|
|
@ -462,7 +462,7 @@ function TechnicalCard({
|
||||||
features: string[];
|
features: string[];
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<Card className="hover-lift animate-slide-up animate-delay-300 gradient-card">
|
<Card className="hover-lift animate-slide-up animate-delay-300">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="text-lg">{title}</CardTitle>
|
<CardTitle className="text-lg">{title}</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import * as z from "zod";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { DatePicker } from "@/components/ui/date-picker";
|
||||||
import {
|
import {
|
||||||
Form,
|
Form,
|
||||||
FormControl,
|
FormControl,
|
||||||
|
|
@ -122,7 +123,7 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="shadow-lg gradient-card gradient-shine hover-lift animate-scale-up">
|
<Card className="shadow-lg hover-lift animate-scale-up">
|
||||||
<CardContent className="pt-6">
|
<CardContent className="pt-6">
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
|
|
@ -225,7 +226,14 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
||||||
<FormItem>
|
<FormItem>
|
||||||
<FormLabel>分析日期</FormLabel>
|
<FormLabel>分析日期</FormLabel>
|
||||||
<FormControl>
|
<FormControl>
|
||||||
<Input type="date" {...field} />
|
<DatePicker
|
||||||
|
date={field.value ? new Date(field.value) : undefined}
|
||||||
|
onDateChange={(date) => {
|
||||||
|
field.onChange(date ? format(date, "yyyy-MM-dd") : "")
|
||||||
|
}}
|
||||||
|
placeholder="選擇分析日期"
|
||||||
|
className="w-full"
|
||||||
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormDescription>選擇分析日期</FormDescription>
|
<FormDescription>選擇分析日期</FormDescription>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ export function AnalystReport({ reports }: AnalystReportProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="shadow-lg gradient-card gradient-shine hover-lift animate-scale-up">
|
<Card className="shadow-lg hover-lift animate-scale-up">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>分析報告</CardTitle>
|
<CardTitle>分析報告</CardTitle>
|
||||||
<CardDescription>來自所有代理團隊的詳細報告</CardDescription>
|
<CardDescription>來自所有代理團隊的詳細報告</CardDescription>
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ export function DownloadReports({
|
||||||
const isAllSelected = selectedAnalysts.length === availableAnalysts.length && availableAnalysts.length > 0;
|
const isAllSelected = selectedAnalysts.length === availableAnalysts.length && availableAnalysts.length > 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="gradient-card gradient-shine hover-lift animate-scale-up">
|
<Card className="hover-lift animate-scale-up">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle className="flex items-center gap-2">
|
<CardTitle className="flex items-center gap-2">
|
||||||
<FileDown className="h-5 w-5" />
|
<FileDown className="h-5 w-5" />
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ export function PriceChart({ priceData, priceStats, ticker }: PriceChartProps) {
|
||||||
const priceRange = maxPrice - minPrice;
|
const priceRange = maxPrice - minPrice;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="w-full gradient-card gradient-shine hover-lift animate-scale-up">
|
<Card className="w-full hover-lift animate-scale-up">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<CardTitle className="text-2xl">{ticker} 價格走勢</CardTitle>
|
<CardTitle className="text-2xl">{ticker} 價格走勢</CardTitle>
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ export function TradingDecision({ result }: TradingDecisionProps) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="shadow-lg border-2 border-blue-500 gradient-card gradient-shine hover-lift animate-scale-up">
|
<Card className="shadow-lg border-2 border-blue-500 hover-lift animate-scale-up">
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<CardTitle>交易決策</CardTitle>
|
<CardTitle>交易決策</CardTitle>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const buttonVariants = cva(
|
||||||
destructive:
|
destructive:
|
||||||
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
||||||
outline:
|
outline:
|
||||||
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
"glass-gradient border-2 shadow-md hover:shadow-lg hover:scale-105 hover:border-primary/50",
|
||||||
secondary:
|
secondary:
|
||||||
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||||
ghost:
|
ghost:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,216 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import {
|
||||||
|
ChevronDownIcon,
|
||||||
|
ChevronLeftIcon,
|
||||||
|
ChevronRightIcon,
|
||||||
|
} from "lucide-react"
|
||||||
|
import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { Button, buttonVariants } from "@/components/ui/button"
|
||||||
|
|
||||||
|
function Calendar({
|
||||||
|
className,
|
||||||
|
classNames,
|
||||||
|
showOutsideDays = true,
|
||||||
|
captionLayout = "label",
|
||||||
|
buttonVariant = "ghost",
|
||||||
|
formatters,
|
||||||
|
components,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof DayPicker> & {
|
||||||
|
buttonVariant?: React.ComponentProps<typeof Button>["variant"]
|
||||||
|
}) {
|
||||||
|
const defaultClassNames = getDefaultClassNames()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DayPicker
|
||||||
|
showOutsideDays={showOutsideDays}
|
||||||
|
className={cn(
|
||||||
|
"bg-background group/calendar p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent",
|
||||||
|
String.raw`rtl:**:[.rdp-button\_next>svg]:rotate-180`,
|
||||||
|
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
captionLayout={captionLayout}
|
||||||
|
formatters={{
|
||||||
|
formatMonthDropdown: (date) =>
|
||||||
|
date.toLocaleString("default", { month: "short" }),
|
||||||
|
...formatters,
|
||||||
|
}}
|
||||||
|
classNames={{
|
||||||
|
root: cn("w-fit", defaultClassNames.root),
|
||||||
|
months: cn(
|
||||||
|
"flex gap-4 flex-col md:flex-row relative",
|
||||||
|
defaultClassNames.months
|
||||||
|
),
|
||||||
|
month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
|
||||||
|
nav: cn(
|
||||||
|
"flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
|
||||||
|
defaultClassNames.nav
|
||||||
|
),
|
||||||
|
button_previous: cn(
|
||||||
|
buttonVariants({ variant: buttonVariant }),
|
||||||
|
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
|
||||||
|
defaultClassNames.button_previous
|
||||||
|
),
|
||||||
|
button_next: cn(
|
||||||
|
buttonVariants({ variant: buttonVariant }),
|
||||||
|
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
|
||||||
|
defaultClassNames.button_next
|
||||||
|
),
|
||||||
|
month_caption: cn(
|
||||||
|
"flex items-center justify-center h-(--cell-size) w-full px-(--cell-size)",
|
||||||
|
defaultClassNames.month_caption
|
||||||
|
),
|
||||||
|
dropdowns: cn(
|
||||||
|
"w-full flex items-center text-sm font-medium justify-center h-(--cell-size) gap-1.5",
|
||||||
|
defaultClassNames.dropdowns
|
||||||
|
),
|
||||||
|
dropdown_root: cn(
|
||||||
|
"relative has-focus:border-ring border border-input shadow-xs has-focus:ring-ring/50 has-focus:ring-[3px] rounded-md",
|
||||||
|
defaultClassNames.dropdown_root
|
||||||
|
),
|
||||||
|
dropdown: cn(
|
||||||
|
"absolute bg-popover inset-0 opacity-0",
|
||||||
|
defaultClassNames.dropdown
|
||||||
|
),
|
||||||
|
caption_label: cn(
|
||||||
|
"select-none font-medium",
|
||||||
|
captionLayout === "label"
|
||||||
|
? "text-sm"
|
||||||
|
: "rounded-md pl-2 pr-1 flex items-center gap-1 text-sm h-8 [&>svg]:text-muted-foreground [&>svg]:size-3.5",
|
||||||
|
defaultClassNames.caption_label
|
||||||
|
),
|
||||||
|
table: "w-full border-collapse",
|
||||||
|
weekdays: cn("flex", defaultClassNames.weekdays),
|
||||||
|
weekday: cn(
|
||||||
|
"text-muted-foreground rounded-md flex-1 font-normal text-[0.8rem] select-none",
|
||||||
|
defaultClassNames.weekday
|
||||||
|
),
|
||||||
|
week: cn("flex w-full mt-2", defaultClassNames.week),
|
||||||
|
week_number_header: cn(
|
||||||
|
"select-none w-(--cell-size)",
|
||||||
|
defaultClassNames.week_number_header
|
||||||
|
),
|
||||||
|
week_number: cn(
|
||||||
|
"text-[0.8rem] select-none text-muted-foreground",
|
||||||
|
defaultClassNames.week_number
|
||||||
|
),
|
||||||
|
day: cn(
|
||||||
|
"relative w-full h-full p-0 text-center [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none",
|
||||||
|
props.showWeekNumber
|
||||||
|
? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md"
|
||||||
|
: "[&:first-child[data-selected=true]_button]:rounded-l-md",
|
||||||
|
defaultClassNames.day
|
||||||
|
),
|
||||||
|
range_start: cn(
|
||||||
|
"rounded-l-md bg-accent",
|
||||||
|
defaultClassNames.range_start
|
||||||
|
),
|
||||||
|
range_middle: cn("rounded-none", defaultClassNames.range_middle),
|
||||||
|
range_end: cn("rounded-r-md bg-accent", defaultClassNames.range_end),
|
||||||
|
today: cn(
|
||||||
|
"bg-accent text-accent-foreground rounded-md data-[selected=true]:rounded-none",
|
||||||
|
defaultClassNames.today
|
||||||
|
),
|
||||||
|
outside: cn(
|
||||||
|
"text-muted-foreground aria-selected:text-muted-foreground",
|
||||||
|
defaultClassNames.outside
|
||||||
|
),
|
||||||
|
disabled: cn(
|
||||||
|
"text-muted-foreground opacity-50",
|
||||||
|
defaultClassNames.disabled
|
||||||
|
),
|
||||||
|
hidden: cn("invisible", defaultClassNames.hidden),
|
||||||
|
...classNames,
|
||||||
|
}}
|
||||||
|
components={{
|
||||||
|
Root: ({ className, rootRef, ...props }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
data-slot="calendar"
|
||||||
|
ref={rootRef}
|
||||||
|
className={cn(className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
Chevron: ({ className, orientation, ...props }) => {
|
||||||
|
if (orientation === "left") {
|
||||||
|
return (
|
||||||
|
<ChevronLeftIcon className={cn("size-4", className)} {...props} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orientation === "right") {
|
||||||
|
return (
|
||||||
|
<ChevronRightIcon
|
||||||
|
className={cn("size-4", className)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ChevronDownIcon className={cn("size-4", className)} {...props} />
|
||||||
|
)
|
||||||
|
},
|
||||||
|
DayButton: CalendarDayButton,
|
||||||
|
WeekNumber: ({ children, ...props }) => {
|
||||||
|
return (
|
||||||
|
<td {...props}>
|
||||||
|
<div className="flex size-(--cell-size) items-center justify-center text-center">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
...components,
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function CalendarDayButton({
|
||||||
|
className,
|
||||||
|
day,
|
||||||
|
modifiers,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof DayButton>) {
|
||||||
|
const defaultClassNames = getDefaultClassNames()
|
||||||
|
|
||||||
|
const ref = React.useRef<HTMLButtonElement>(null)
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (modifiers.focused) ref.current?.focus()
|
||||||
|
}, [modifiers.focused])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
ref={ref}
|
||||||
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
data-day={day.date.toLocaleDateString()}
|
||||||
|
data-selected-single={
|
||||||
|
modifiers.selected &&
|
||||||
|
!modifiers.range_start &&
|
||||||
|
!modifiers.range_end &&
|
||||||
|
!modifiers.range_middle
|
||||||
|
}
|
||||||
|
data-range-start={modifiers.range_start}
|
||||||
|
data-range-end={modifiers.range_end}
|
||||||
|
data-range-middle={modifiers.range_middle}
|
||||||
|
className={cn(
|
||||||
|
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 dark:hover:text-accent-foreground flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md [&>span]:text-xs [&>span]:opacity-70",
|
||||||
|
defaultClassNames.day,
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Calendar, CalendarDayButton }
|
||||||
|
|
@ -7,7 +7,7 @@ function Card({ className, ...props }: React.ComponentProps<"div">) {
|
||||||
<div
|
<div
|
||||||
data-slot="card"
|
data-slot="card"
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
|
"glass-gradient flex flex-col gap-6 rounded-xl py-6 shadow-lg transition-all duration-300 hover:shadow-2xl",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,10 @@ function Checkbox({
|
||||||
<CheckboxPrimitive.Root
|
<CheckboxPrimitive.Root
|
||||||
data-slot="checkbox"
|
data-slot="checkbox"
|
||||||
className={cn(
|
className={cn(
|
||||||
"peer border-input dark:bg-input/30 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground dark:data-[state=checked]:bg-primary data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
|
"peer glass-gradient data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary size-4 shrink-0 rounded-md border-2 shadow-md transition-all outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
|
"hover:shadow-lg hover:scale-110",
|
||||||
|
"focus-visible:border-primary focus-visible:ring-4 focus-visible:ring-primary/20",
|
||||||
|
"aria-invalid:border-destructive aria-invalid:ring-4 aria-invalid:ring-destructive/20",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import { CalendarIcon } from "lucide-react"
|
||||||
|
import { format } from "date-fns"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
import { Button } from "@/components/ui/button"
|
||||||
|
import { Calendar } from "@/components/ui/calendar"
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
} from "@/components/ui/popover"
|
||||||
|
|
||||||
|
interface DatePickerProps {
|
||||||
|
date: Date | undefined
|
||||||
|
onDateChange: (date: Date | undefined) => void
|
||||||
|
placeholder?: string
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DatePicker({
|
||||||
|
date,
|
||||||
|
onDateChange,
|
||||||
|
placeholder = "選擇日期",
|
||||||
|
className,
|
||||||
|
}: DatePickerProps) {
|
||||||
|
const [open, setOpen] = React.useState(false)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popover open={open} onOpenChange={setOpen}>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
className={cn(
|
||||||
|
"justify-start text-left font-normal",
|
||||||
|
!date && "text-muted-foreground",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<CalendarIcon className="mr-2 h-4 w-4" />
|
||||||
|
{date ? format(date, "yyyy-MM-dd") : <span>{placeholder}</span>}
|
||||||
|
</Button>
|
||||||
|
</PopoverTrigger>
|
||||||
|
<PopoverContent className="w-auto p-0" align="start">
|
||||||
|
<Calendar
|
||||||
|
mode="single"
|
||||||
|
selected={date}
|
||||||
|
onSelect={(selectedDate) => {
|
||||||
|
onDateChange(selectedDate)
|
||||||
|
setOpen(false)
|
||||||
|
}}
|
||||||
|
initialFocus
|
||||||
|
/>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -8,9 +8,10 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
|
||||||
type={type}
|
type={type}
|
||||||
data-slot="input"
|
data-slot="input"
|
||||||
className={cn(
|
className={cn(
|
||||||
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
"glass-gradient file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground h-9 w-full min-w-0 rounded-lg border-2 px-3 py-1 text-base shadow-md transition-all outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||||
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
"hover:border-primary/50 hover:shadow-lg hover:scale-[1.01]",
|
||||||
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
"focus-visible:border-primary focus-visible:ring-4 focus-visible:ring-primary/20 focus-visible:shadow-xl focus-visible:scale-[1.01]",
|
||||||
|
"aria-invalid:border-destructive aria-invalid:ring-4 aria-invalid:ring-destructive/20",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
"use client"
|
||||||
|
|
||||||
|
import * as React from "react"
|
||||||
|
import * as PopoverPrimitive from "@radix-ui/react-popover"
|
||||||
|
|
||||||
|
import { cn } from "@/lib/utils"
|
||||||
|
|
||||||
|
function Popover({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof PopoverPrimitive.Root>) {
|
||||||
|
return <PopoverPrimitive.Root data-slot="popover" {...props} />
|
||||||
|
}
|
||||||
|
|
||||||
|
function PopoverTrigger({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {
|
||||||
|
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
|
||||||
|
}
|
||||||
|
|
||||||
|
function PopoverContent({
|
||||||
|
className,
|
||||||
|
align = "center",
|
||||||
|
sideOffset = 4,
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof PopoverPrimitive.Content>) {
|
||||||
|
return (
|
||||||
|
<PopoverPrimitive.Portal>
|
||||||
|
<PopoverPrimitive.Content
|
||||||
|
data-slot="popover-content"
|
||||||
|
align={align}
|
||||||
|
sideOffset={sideOffset}
|
||||||
|
className={cn(
|
||||||
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 origin-(--radix-popover-content-transform-origin) rounded-md border p-4 shadow-md outline-hidden",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</PopoverPrimitive.Portal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function PopoverAnchor({
|
||||||
|
...props
|
||||||
|
}: React.ComponentProps<typeof PopoverPrimitive.Anchor>) {
|
||||||
|
return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor }
|
||||||
|
|
@ -37,7 +37,10 @@ function SelectTrigger({
|
||||||
data-slot="select-trigger"
|
data-slot="select-trigger"
|
||||||
data-size={size}
|
data-size={size}
|
||||||
className={cn(
|
className={cn(
|
||||||
"border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 dark:hover:bg-input/50 flex w-fit items-center justify-between gap-2 rounded-md border bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
"glass-gradient data-[placeholder]:text-muted-foreground [&_svg:not([class*='text-'])]:text-muted-foreground flex w-fit items-center justify-between gap-2 rounded-lg border-2 px-3 py-2 text-sm whitespace-nowrap shadow-md transition-all outline-none disabled:cursor-not-allowed disabled:opacity-50 data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
||||||
|
"hover:border-primary/50 hover:shadow-lg hover:scale-105",
|
||||||
|
"focus-visible:border-primary focus-visible:ring-4 focus-visible:ring-primary/20 focus-visible:shadow-xl",
|
||||||
|
"aria-invalid:border-destructive aria-invalid:ring-4 aria-invalid:ring-destructive/20",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|
@ -62,7 +65,7 @@ function SelectContent({
|
||||||
<SelectPrimitive.Content
|
<SelectPrimitive.Content
|
||||||
data-slot="select-content"
|
data-slot="select-content"
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border shadow-md",
|
"glass-gradient text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-xl border-2 shadow-xl",
|
||||||
position === "popper" &&
|
position === "popper" &&
|
||||||
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
||||||
className
|
className
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
"@radix-ui/react-dialog": "^1.1.15",
|
"@radix-ui/react-dialog": "^1.1.15",
|
||||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||||
"@radix-ui/react-label": "^2.1.8",
|
"@radix-ui/react-label": "^2.1.8",
|
||||||
|
"@radix-ui/react-popover": "^1.1.15",
|
||||||
"@radix-ui/react-select": "^2.2.6",
|
"@radix-ui/react-select": "^2.2.6",
|
||||||
"@radix-ui/react-slot": "^1.2.4",
|
"@radix-ui/react-slot": "^1.2.4",
|
||||||
"@radix-ui/react-tabs": "^1.1.13",
|
"@radix-ui/react-tabs": "^1.1.13",
|
||||||
|
|
@ -25,6 +26,7 @@
|
||||||
"next": "16.0.3",
|
"next": "16.0.3",
|
||||||
"next-themes": "^0.4.6",
|
"next-themes": "^0.4.6",
|
||||||
"react": "19.2.0",
|
"react": "19.2.0",
|
||||||
|
"react-day-picker": "^9.11.3",
|
||||||
"react-dom": "19.2.0",
|
"react-dom": "19.2.0",
|
||||||
"react-hook-form": "^7.66.1",
|
"react-hook-form": "^7.66.1",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@ importers:
|
||||||
'@radix-ui/react-label':
|
'@radix-ui/react-label':
|
||||||
specifier: ^2.1.8
|
specifier: ^2.1.8
|
||||||
version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
version: 2.1.8(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
'@radix-ui/react-popover':
|
||||||
|
specifier: ^1.1.15
|
||||||
|
version: 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
'@radix-ui/react-select':
|
'@radix-ui/react-select':
|
||||||
specifier: ^2.2.6
|
specifier: ^2.2.6
|
||||||
version: 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
version: 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
|
@ -56,6 +59,9 @@ importers:
|
||||||
react:
|
react:
|
||||||
specifier: 19.2.0
|
specifier: 19.2.0
|
||||||
version: 19.2.0
|
version: 19.2.0
|
||||||
|
react-day-picker:
|
||||||
|
specifier: ^9.11.3
|
||||||
|
version: 9.11.3(react@19.2.0)
|
||||||
react-dom:
|
react-dom:
|
||||||
specifier: 19.2.0
|
specifier: 19.2.0
|
||||||
version: 19.2.0(react@19.2.0)
|
version: 19.2.0(react@19.2.0)
|
||||||
|
|
@ -185,6 +191,9 @@ packages:
|
||||||
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
|
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
|
||||||
engines: {node: '>=6.9.0'}
|
engines: {node: '>=6.9.0'}
|
||||||
|
|
||||||
|
'@date-fns/tz@1.4.1':
|
||||||
|
resolution: {integrity: sha512-P5LUNhtbj6YfI3iJjw5EL9eUAG6OitD0W3fWQcpQjDRc/QIsL0tRNuO1PcDvPccWL1fSTXXdE1ds+l95DV/OFA==}
|
||||||
|
|
||||||
'@emnapi/core@1.7.1':
|
'@emnapi/core@1.7.1':
|
||||||
resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==}
|
resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==}
|
||||||
|
|
||||||
|
|
@ -662,6 +671,19 @@ packages:
|
||||||
'@types/react-dom':
|
'@types/react-dom':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@radix-ui/react-popover@1.1.15':
|
||||||
|
resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@radix-ui/react-popper@1.2.8':
|
'@radix-ui/react-popper@1.2.8':
|
||||||
resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==}
|
resolution: {integrity: sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -1461,6 +1483,9 @@ packages:
|
||||||
resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
|
resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
date-fns-jalali@4.1.0-0:
|
||||||
|
resolution: {integrity: sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==}
|
||||||
|
|
||||||
date-fns@4.1.0:
|
date-fns@4.1.0:
|
||||||
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
|
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
|
||||||
|
|
||||||
|
|
@ -2531,6 +2556,12 @@ packages:
|
||||||
queue-microtask@1.2.3:
|
queue-microtask@1.2.3:
|
||||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||||
|
|
||||||
|
react-day-picker@9.11.3:
|
||||||
|
resolution: {integrity: sha512-7lD12UvGbkyXqgzbYIGQTbl+x29B9bAf+k0pP5Dcs1evfpKk6zv4EdH/edNc8NxcmCiTNXr2HIYPrSZ3XvmVBg==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.8.0'
|
||||||
|
|
||||||
react-dom@19.2.0:
|
react-dom@19.2.0:
|
||||||
resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==}
|
resolution: {integrity: sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
@ -3100,6 +3131,8 @@ snapshots:
|
||||||
'@babel/helper-string-parser': 7.27.1
|
'@babel/helper-string-parser': 7.27.1
|
||||||
'@babel/helper-validator-identifier': 7.28.5
|
'@babel/helper-validator-identifier': 7.28.5
|
||||||
|
|
||||||
|
'@date-fns/tz@1.4.1': {}
|
||||||
|
|
||||||
'@emnapi/core@1.7.1':
|
'@emnapi/core@1.7.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@emnapi/wasi-threads': 1.1.0
|
'@emnapi/wasi-threads': 1.1.0
|
||||||
|
|
@ -3530,6 +3563,29 @@ snapshots:
|
||||||
'@types/react': 19.2.6
|
'@types/react': 19.2.6
|
||||||
'@types/react-dom': 19.2.3(@types/react@19.2.6)
|
'@types/react-dom': 19.2.3(@types/react@19.2.6)
|
||||||
|
|
||||||
|
'@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
|
||||||
|
dependencies:
|
||||||
|
'@radix-ui/primitive': 1.1.3
|
||||||
|
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.6)(react@19.2.0)
|
||||||
|
'@radix-ui/react-context': 1.1.2(@types/react@19.2.6)(react@19.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
'@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.6)(react@19.2.0)
|
||||||
|
'@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
'@radix-ui/react-id': 1.1.1(@types/react@19.2.6)(react@19.2.0)
|
||||||
|
'@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
'@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.2.3(@types/react@19.2.6)(react@19.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.6)(react@19.2.0)
|
||||||
|
aria-hidden: 1.2.6
|
||||||
|
react: 19.2.0
|
||||||
|
react-dom: 19.2.0(react@19.2.0)
|
||||||
|
react-remove-scroll: 2.7.1(@types/react@19.2.6)(react@19.2.0)
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 19.2.6
|
||||||
|
'@types/react-dom': 19.2.3(@types/react@19.2.6)
|
||||||
|
|
||||||
'@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
|
'@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.6))(@types/react@19.2.6)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@floating-ui/react-dom': 2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
'@floating-ui/react-dom': 2.1.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
|
||||||
|
|
@ -4314,6 +4370,8 @@ snapshots:
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
is-data-view: 1.0.2
|
is-data-view: 1.0.2
|
||||||
|
|
||||||
|
date-fns-jalali@4.1.0-0: {}
|
||||||
|
|
||||||
date-fns@4.1.0: {}
|
date-fns@4.1.0: {}
|
||||||
|
|
||||||
debug@3.2.7:
|
debug@3.2.7:
|
||||||
|
|
@ -5749,6 +5807,13 @@ snapshots:
|
||||||
|
|
||||||
queue-microtask@1.2.3: {}
|
queue-microtask@1.2.3: {}
|
||||||
|
|
||||||
|
react-day-picker@9.11.3(react@19.2.0):
|
||||||
|
dependencies:
|
||||||
|
'@date-fns/tz': 1.4.1
|
||||||
|
date-fns: 4.1.0
|
||||||
|
date-fns-jalali: 4.1.0-0
|
||||||
|
react: 19.2.0
|
||||||
|
|
||||||
react-dom@19.2.0(react@19.2.0):
|
react-dom@19.2.0(react@19.2.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
react: 19.2.0
|
react: 19.2.0
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue