first commit

This commit is contained in:
Your NamebaishaliHolocron
2026-06-15 12:57:03 +05:30
commit b9ac5ae0b2
398 changed files with 49583 additions and 0 deletions

View File

@@ -0,0 +1,134 @@
"use client";
import React from "react";
import { Building2 } from "lucide-react";
import { Card, Badge, Button } from "../../";
import { HeaderProps } from "./type";
function Avatar({
avatar,
initials,
icon,
}: Pick<HeaderProps, "avatar" | "initials" | "icon">) {
if (avatar) return <>{avatar}</>;
if (initials) {
return (
<div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-xl bg-accent text-lg font-bold uppercase text-accent-foreground">
{initials}
</div>
);
}
return (
<div className="flex h-14 w-14 shrink-0 items-center justify-center rounded-xl bg-accent">
{icon ?? <Building2 className="h-7 w-7" />}
</div>
);
}
export default function HeaderDetails({
title,
subtitle,
subtitleIcon,
avatar,
initials,
icon,
badges,
actions,
actionsSlot,
meta,
accent = true,
className = "",
}: HeaderProps) {
const hasActions = actionsSlot || (actions && actions.length > 0);
const hasMeta = meta && meta.length > 0;
return (
<Card className={`relative overflow-hidden p-0 ${className}`}>
{accent && (
<div className="h-1 w-full bg-accent" />
)}
<div className="p-5 sm:p-6">
{/* Top row: identity + actions */}
<div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
<div className="flex items-center gap-4">
<Avatar avatar={avatar} initials={initials} icon={icon} />
<div className="flex flex-col gap-1">
<div className="flex flex-wrap items-center gap-2.5">
<h1 className="text-xl sm:text-2xl font-bold leading-tight">
{title}
</h1>
{/* {badges?.map((badge, i) => (
<Badge
key={i}
variant={badge.variant ?? "default"}
className={`rounded-full text-xs font-medium ${badge.className ?? ""}`}
>
{badge.icon && (
<span className="mr-1.5 flex items-center">
{badge.icon}
</span>
)}
{badge.label}
</Badge>
))} */}
</div>
{subtitle && (
<p className="flex items-center gap-1.5 text-sm text-muted-foreground">
<span className="flex items-center">
{subtitleIcon ?? <Building2 className="h-4 w-4" />}
</span>
{subtitle}
</p>
)}
</div>
</div>
{hasActions && (
<div className="flex items-center justify-end gap-2 shrink-0">
{actionsSlot}
{actions?.map((action, i) => (
<Button
key={i}
variant={action.variant ?? "default"}
onClick={action.onClick}
disabled={action.disabled}
>
{action.icon && (
<span className="flex items-center">{action.icon}</span>
)}
{action.label}
</Button>
))}
</div>
)}
</div>
{/* Lower meta section: Owner / Industry / Deal Value / Created, etc. */}
{hasMeta && (
<div className="mt-5 border-t pt-4">
<div className="flex flex-wrap gap-x-12 gap-y-4">
{meta!.map((item, i) => (
<div key={i} className="flex items-center gap-3">
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground">
{item.icon}
</div>
<div className="flex flex-col">
<span className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
{item.label}
</span>
<span className="text-sm font-semibold">{item.value}</span>
</div>
</div>
))}
</div>
</div>
)}
</div>
</Card>
);
}

View File

@@ -0,0 +1,62 @@
import { Badge, Button } from "../../";
type BadgeVariant = React.ComponentProps<typeof Badge>["variant"];
export interface HeaderBadge {
/** Text/content shown inside the badge */
label: React.ReactNode;
/** Optional leading icon */
icon?: React.ReactNode;
variant?: BadgeVariant;
className?: string;
}
export interface HeaderMetaItem {
/** Small muted label, e.g. "Owner" / "Sales Manager" */
label: string;
/** The value shown under the label */
value: React.ReactNode;
/** Icon rendered inside the boxed container on the left */
icon?: React.ReactNode;
}
export interface HeaderAction {
label: React.ReactNode;
onClick?: () => void;
icon?: React.ReactNode;
variant?: React.ComponentProps<typeof Button>["variant"];
disabled?: boolean;
}
export interface HeaderProps {
title: React.ReactNode;
subtitle?: React.ReactNode;
/** Small icon shown before the subtitle (defaults to a building icon) */
subtitleIcon?: React.ReactNode;
/**
* Leading visual. Priority: `avatar` node → `initials` gradient box →
* `icon` → default building icon.
*/
avatar?: React.ReactNode;
/** Initials rendered inside a gradient avatar box, e.g. "FM" */
initials?: string;
icon?: React.ReactNode;
/** Status / tag badges rendered inline next to the title */
badges?: HeaderBadge[];
/**
* Right-side actions. Pass an array for convenience buttons, or a custom
* node via `actionsSlot` for full control.
*/
actions?: HeaderAction[];
actionsSlot?: React.ReactNode;
/** Lower meta section, e.g. Owner / Industry / Deal Value / Created */
meta?: HeaderMetaItem[];
/** Show the gradient accent bar at the top (default true) */
accent?: boolean;
className?: string;
}