feat: add AdjustAIButton, EditPlanButton, and AsignaturaPreviewCard components

- Implemented AdjustAIButton for AI-driven plan adjustments with a confetti effect on success.
- Created EditPlanButton to allow editing of plan details with form validation and optimistic updates.
- Added AsignaturaPreviewCard to display course previews with relevant statistics and details.
- Introduced Field component for consistent form field labeling.
- Developed GradientMesh for dynamic background effects based on color input.
- Added Pulse component for skeleton loading states.
- Created SmallStat and StatCard components for displaying statistical information in a card format.
- Implemented utility functions in planHelpers for color manipulation and formatting.
- Established planQueries for fetching plan and course data from the database.
- Updated the plan detail route to utilize new components and queries for improved user experience.
This commit is contained in:
2025-08-29 11:14:34 -06:00
parent 3bc4498e4f
commit a487a8c293
13 changed files with 609 additions and 214 deletions

View File

@@ -0,0 +1,25 @@
export function Pulse({ className = '' }: { className?: string }) {
return <div className={`animate-pulse bg-neutral-200 rounded-xl ${className}`} />
}
export function PageSkeleton() {
return (
<div className="p-6 space-y-6">
<div className="border rounded-2xl p-6">
<div className="flex items-center gap-3">
<Pulse className="w-10 h-10" />
<div className="flex-1 space-y-2">
<Pulse className="h-5 w-64" />
<Pulse className="h-3 w-48" />
</div>
</div>
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4 mt-4">
{Array.from({ length: 5 }).map((_, i) => <Pulse key={i} className="h-14" />)}
</div>
</div>
<div className="grid gap-6 lg:grid-cols-2">
{Array.from({ length: 6 }).map((_, i) => <Pulse key={i} className="h-40" />)}
</div>
</div>
)
}