- 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.
26 lines
891 B
TypeScript
26 lines
891 B
TypeScript
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>
|
|
)
|
|
}
|