Add Oudelaa dashboard API integration
فشلت بعض الفحوصات
Deploy To Ghaymah / deploy (push) Has been cancelled

هذا الالتزام موجود في:
boutmoun123
2026-05-25 20:36:52 +03:00
الأصل 367fce6557
التزام 8863f61d00
90 ملفات معدلة مع 16694 إضافات و1 حذوفات

عرض الملف

@@ -0,0 +1,30 @@
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const badgeVariants = cva(
"inline-flex items-center rounded-full px-2.5 py-1 text-xs font-medium",
{
variants: {
variant: {
default: "bg-primary/20 text-primary",
success: "bg-emerald-500/15 text-emerald-300",
warning: "bg-amber-500/15 text-amber-200",
danger: "bg-rose-500/15 text-rose-200",
muted: "bg-secondary text-muted-foreground",
},
},
defaultVariants: {
variant: "default",
},
},
);
export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {}
function Badge({ className, variant, ...props }: BadgeProps) {
return <div className={cn(badgeVariants({ variant }), className)} {...props} />;
}
export { Badge, badgeVariants };

عرض الملف

@@ -0,0 +1,49 @@
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 rounded-lg font-semibold transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "bg-transparent text-foreground hover:bg-secondary/60",
outline: "border border-border bg-transparent text-foreground hover:bg-secondary/60",
danger: "bg-red-900/70 text-red-100 hover:bg-red-800/80",
},
size: {
default: "h-10 px-4 py-2 text-sm",
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-11 px-5 text-sm",
icon: "h-9 w-9",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, type, ...props }, ref) => {
return (
<button
type={type ?? "button"}
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
},
);
Button.displayName = "Button";
export { Button, buttonVariants };

عرض الملف

@@ -0,0 +1,30 @@
import * as React from "react";
import { cn } from "@/lib/utils";
const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("frame-panel gold-edge", className)} {...props} />
));
Card.displayName = "Card";
const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("flex flex-col gap-1.5 p-5", className)} {...props} />
));
CardHeader.displayName = "CardHeader";
const CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(({ className, ...props }, ref) => (
<h3 ref={ref} className={cn("font-heading text-lg font-semibold tracking-tight", className)} {...props} />
));
CardTitle.displayName = "CardTitle";
const CardDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
({ className, ...props }, ref) => <p ref={ref} className={cn("text-sm text-muted-foreground", className)} {...props} />,
);
CardDescription.displayName = "CardDescription";
const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(({ className, ...props }, ref) => (
<div ref={ref} className={cn("p-5 pt-0", className)} {...props} />
));
CardContent.displayName = "CardContent";
export { Card, CardContent, CardDescription, CardHeader, CardTitle };

عرض الملف

@@ -0,0 +1,62 @@
"use client";
import * as React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { X } from "lucide-react";
import { cn } from "@/lib/utils";
const Dialog = DialogPrimitive.Root;
const DialogTrigger = DialogPrimitive.Trigger;
const DialogPortal = DialogPrimitive.Portal;
const DialogClose = DialogPrimitive.Close;
const DialogOverlay = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Overlay
ref={ref}
className={cn("fixed inset-0 z-50 bg-black/70 backdrop-blur-sm", className)}
{...props}
/>
));
DialogOverlay.displayName = "DialogOverlay";
const DialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<DialogPortal>
<DialogOverlay />
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-1/2 top-1/2 z-50 grid w-[95vw] max-w-xl -translate-x-1/2 -translate-y-1/2 gap-4 rounded-2xl border border-border bg-card p-6 shadow-glow",
className,
)}
{...props}
>
{children}
<DialogClose className="absolute left-4 top-4 rounded-md p-1 text-muted-foreground hover:text-foreground">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogClose>
</DialogPrimitive.Content>
</DialogPortal>
));
DialogContent.displayName = "DialogContent";
function DialogHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
return <div className={cn("space-y-2 text-right", className)} {...props} />;
}
function DialogTitle({ className, ...props }: React.HTMLAttributes<HTMLHeadingElement>) {
return <h2 className={cn("font-heading text-xl font-bold", className)} {...props} />;
}
function DialogDescription({ className, ...props }: React.HTMLAttributes<HTMLParagraphElement>) {
return <p className={cn("text-sm text-muted-foreground", className)} {...props} />;
}
export { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger };

عرض الملف

@@ -0,0 +1,58 @@
"use client";
import type { ReactNode } from "react";
import { X } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
type DrawerProps = {
open: boolean;
onClose: () => void;
title: string;
description?: string;
children: ReactNode;
side?: "left" | "right";
widthClassName?: string;
};
export function Drawer({
open,
onClose,
title,
description,
children,
side = "left",
widthClassName,
}: DrawerProps) {
return (
<>
<div
className={cn(
"fixed inset-0 z-40 bg-black/50 backdrop-blur-sm transition",
open ? "opacity-100" : "pointer-events-none opacity-0",
)}
onClick={onClose}
/>
<aside
className={cn(
"fixed bottom-0 top-0 z-50 w-[96vw] max-w-md border border-border bg-card p-5 shadow-glow transition",
widthClassName,
side === "left" ? "left-0" : "right-0",
open ? "translate-x-0" : side === "left" ? "-translate-x-full" : "translate-x-full",
)}
>
<div className="mb-5 flex items-start justify-between">
<div className="space-y-1">
<h3 className="font-heading text-lg font-bold">{title}</h3>
{description ? <p className="text-sm text-muted-foreground">{description}</p> : null}
</div>
<Button variant="ghost" size="icon" onClick={onClose}>
<X className="h-4 w-4" />
</Button>
</div>
<div className="h-[calc(100%-72px)] overflow-y-auto">{children}</div>
</aside>
</>
);
}

عرض الملف

@@ -0,0 +1,21 @@
import { Music2 } from "lucide-react";
import { cn } from "@/lib/utils";
type EmptyStateProps = {
title: string;
description: string;
className?: string;
};
export function EmptyState({ title, description, className }: EmptyStateProps) {
return (
<div className={cn("ornament-grid shimmer-empty rounded-xl border border-dashed border-border p-8 text-center", className)}>
<div className="mx-auto mb-3 flex h-12 w-12 items-center justify-center rounded-full bg-secondary text-primary">
<Music2 className="h-5 w-5" />
</div>
<h3 className="font-heading text-lg font-semibold">{title}</h3>
<p className="mx-auto mt-1 max-w-md text-sm text-muted-foreground">{description}</p>
</div>
);
}

عرض الملف

@@ -0,0 +1,20 @@
import * as React from "react";
import { cn } from "@/lib/utils";
const Input = React.forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(({ className, ...props }, ref) => {
return (
<input
ref={ref}
className={cn(
"flex h-10 w-full rounded-lg border border-input bg-background/60 px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
className,
)}
{...props}
/>
);
});
Input.displayName = "Input";
export { Input };

عرض الملف

@@ -0,0 +1,71 @@
"use client";
import * as React from "react";
import * as SelectPrimitive from "@radix-ui/react-select";
import { Check, ChevronDown } from "lucide-react";
import { cn } from "@/lib/utils";
const Select = SelectPrimitive.Root;
const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex h-10 w-full items-center justify-between rounded-lg border border-input bg-background/60 px-3 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-ring",
className,
)}
{...props}
>
{children}
<SelectPrimitive.Icon asChild>
<ChevronDown className="h-4 w-4 text-muted-foreground" />
</SelectPrimitive.Icon>
</SelectPrimitive.Trigger>
));
SelectTrigger.displayName = "SelectTrigger";
const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn("z-50 min-w-[8rem] overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground", className)}
{...props}
>
<SelectPrimitive.Viewport className="p-1">{children}</SelectPrimitive.Viewport>
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
));
SelectContent.displayName = "SelectContent";
const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
>(({ className, children, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default select-none items-center rounded-md py-2 pl-8 pr-3 text-sm outline-none hover:bg-secondary",
className,
)}
{...props}
>
<span className="absolute left-2 flex h-3.5 w-3.5 items-center justify-center">
<SelectPrimitive.ItemIndicator>
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
</span>
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
SelectItem.displayName = "SelectItem";
const SelectValue = SelectPrimitive.Value;
export { Select, SelectContent, SelectItem, SelectTrigger, SelectValue };

عرض الملف

@@ -0,0 +1,9 @@
import * as React from "react";
import { cn } from "@/lib/utils";
function Separator({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {
return <div role="separator" className={cn("h-px w-full bg-border", className)} {...props} />;
}
export { Separator };

عرض الملف

@@ -0,0 +1,32 @@
"use client";
import { cn } from "@/lib/utils";
type SwitchProps = {
checked: boolean;
onCheckedChange: (value: boolean) => void;
className?: string;
};
export function Switch({ checked, onCheckedChange, className }: SwitchProps) {
return (
<button
type="button"
role="switch"
aria-checked={checked}
onClick={() => onCheckedChange(!checked)}
className={cn(
"relative h-6 w-11 rounded-full border border-border transition",
checked ? "bg-primary" : "bg-secondary",
className,
)}
>
<span
className={cn(
"absolute top-0.5 h-[18px] w-[18px] rounded-full bg-background transition",
checked ? "right-0.5" : "right-[22px]",
)}
/>
</button>
);
}

عرض الملف

@@ -0,0 +1,37 @@
import * as React from "react";
import { cn } from "@/lib/utils";
const Table = React.forwardRef<HTMLTableElement, React.HTMLAttributes<HTMLTableElement>>(({ className, ...props }, ref) => (
<div className="w-full overflow-auto">
<table ref={ref} className={cn("w-full caption-bottom text-sm", className)} {...props} />
</div>
));
Table.displayName = "Table";
const TableHeader = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(({ className, ...props }, ref) => (
<thead ref={ref} className={cn("[&_tr]:border-b [&_tr]:border-border", className)} {...props} />
));
TableHeader.displayName = "TableHeader";
const TableBody = React.forwardRef<HTMLTableSectionElement, React.HTMLAttributes<HTMLTableSectionElement>>(({ className, ...props }, ref) => (
<tbody ref={ref} className={cn("[&_tr:last-child]:border-0", className)} {...props} />
));
TableBody.displayName = "TableBody";
const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTMLTableRowElement>>(({ className, ...props }, ref) => (
<tr ref={ref} className={cn("border-b border-border/70 transition hover:bg-secondary/40", className)} {...props} />
));
TableRow.displayName = "TableRow";
const TableHead = React.forwardRef<HTMLTableCellElement, React.ThHTMLAttributes<HTMLTableCellElement>>(({ className, ...props }, ref) => (
<th ref={ref} className={cn("h-11 px-4 text-right align-middle font-medium text-muted-foreground", className)} {...props} />
));
TableHead.displayName = "TableHead";
const TableCell = React.forwardRef<HTMLTableCellElement, React.TdHTMLAttributes<HTMLTableCellElement>>(({ className, ...props }, ref) => (
<td ref={ref} className={cn("p-4 align-middle", className)} {...props} />
));
TableCell.displayName = "TableCell";
export { Table, TableBody, TableCell, TableHead, TableHeader, TableRow };

عرض الملف

@@ -0,0 +1,22 @@
import * as React from "react";
import { cn } from "@/lib/utils";
const Textarea = React.forwardRef<HTMLTextAreaElement, React.TextareaHTMLAttributes<HTMLTextAreaElement>>(
({ className, ...props }, ref) => {
return (
<textarea
ref={ref}
className={cn(
"min-h-[90px] w-full rounded-lg border border-input bg-background/60 px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
className,
)}
{...props}
/>
);
},
);
Textarea.displayName = "Textarea";
export { Textarea };

عرض الملف

@@ -0,0 +1,80 @@
"use client";
import * as React from "react";
import { X } from "lucide-react";
import { cn } from "@/lib/utils";
type ToastVariant = "default" | "success" | "warning" | "danger";
type ToastItem = {
id: string;
title: string;
description?: string;
variant?: ToastVariant;
};
type ToastContextValue = {
toast: (item: Omit<ToastItem, "id">) => void;
};
const ToastContext = React.createContext<ToastContextValue | null>(null);
function getToastId() {
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
return crypto.randomUUID();
}
return `toast_${Date.now()}_${Math.random().toString(16).slice(2)}`;
}
const variantStyles: Record<ToastVariant, string> = {
default: "border-border bg-card text-foreground",
success: "border-emerald-500/40 bg-emerald-500/10 text-emerald-100",
warning: "border-amber-500/40 bg-amber-500/10 text-amber-100",
danger: "border-rose-500/40 bg-rose-500/10 text-rose-100",
};
export function ToastProvider({ children }: { children: React.ReactNode }) {
const [toasts, setToasts] = React.useState<ToastItem[]>([]);
const toast = React.useCallback((item: Omit<ToastItem, "id">) => {
const id = getToastId();
setToasts((prev) => [...prev, { id, ...item }]);
window.setTimeout(() => {
setToasts((prev) => prev.filter((toastItem) => toastItem.id !== id));
}, 3200);
}, []);
const remove = React.useCallback((id: string) => {
setToasts((prev) => prev.filter((toastItem) => toastItem.id !== id));
}, []);
return (
<ToastContext.Provider value={{ toast }}>
{children}
<div className="fixed bottom-6 left-6 z-50 flex w-[90vw] max-w-sm flex-col gap-3">
{toasts.map((item) => (
<div key={item.id} className={cn("frame-panel border px-4 py-3 shadow-glow", variantStyles[item.variant ?? "default"])}>
<div className="flex items-start justify-between gap-3">
<div>
<p className="text-sm font-semibold">{item.title}</p>
{item.description ? <p className="mt-1 text-xs text-muted-foreground">{item.description}</p> : null}
</div>
<button className="rounded-md p-1 text-muted-foreground hover:text-foreground" onClick={() => remove(item.id)}>
<X className="h-4 w-4" />
</button>
</div>
</div>
))}
</div>
</ToastContext.Provider>
);
}
export function useToast() {
const context = React.useContext(ToastContext);
if (!context) {
throw new Error("useToast must be used within ToastProvider");
}
return context;
}