barsa b99799c2fe Refactor UI components and enhance styling consistency across the portal
- Updated various components to use consistent color tokens, improving visual coherence.
- Refactored layout components to utilize the new PublicShell for better structure.
- Enhanced error and status messaging styles for improved user feedback.
- Standardized button usage across forms and modals for a unified interaction experience.
- Introduced new UI design tokens and guidelines in documentation to support future development.
2025-12-16 13:54:31 +09:00

77 lines
2.3 KiB
TypeScript

"use client";
import type { ComponentType, SVGProps } from "react";
import {
DocumentTextIcon,
CheckCircleIcon,
ServerIcon,
ChatBubbleLeftRightIcon,
ExclamationTriangleIcon,
} from "@heroicons/react/24/outline";
import type { Activity } from "@customer-portal/domain/dashboard";
import {
formatActivityDate,
formatActivityDescription,
getActivityIconGradient,
} from "../utils/dashboard.utils";
interface DashboardActivityItemProps {
activity: Activity;
onClick?: () => void;
}
const ICON_COMPONENTS: Record<Activity["type"], ComponentType<SVGProps<SVGSVGElement>>> = {
invoice_created: DocumentTextIcon,
invoice_paid: CheckCircleIcon,
service_activated: ServerIcon,
case_created: ChatBubbleLeftRightIcon,
case_closed: CheckCircleIcon,
};
const FALLBACK_ICON = ExclamationTriangleIcon;
export function DashboardActivityItem({ activity, onClick }: DashboardActivityItemProps) {
const Icon = ICON_COMPONENTS[activity.type] ?? FALLBACK_ICON;
const gradient = getActivityIconGradient(activity.type);
const description = formatActivityDescription(activity);
const formattedDate = formatActivityDate(activity.date);
const content = (
<>
<div className="flex-shrink-0">
<div
className={`w-10 h-10 rounded-full bg-gradient-to-r ${gradient} flex items-center justify-center shadow-[var(--cp-shadow-1)]`}
>
<Icon className="h-5 w-5 text-white" />
</div>
</div>
<div className="flex-1 min-w-0">
<p
className={[
"text-sm font-medium",
onClick ? "text-foreground group-hover:text-primary" : "text-foreground",
].join(" ")}
>
{activity.title}
</p>
<p className="text-sm text-muted-foreground mt-1">{description}</p>
<p className="text-xs text-muted-foreground/70 mt-2">{formattedDate}</p>
</div>
</>
);
if (onClick) {
return (
<button
type="button"
className="group flex items-start space-x-4 w-full text-left p-3 -m-3 rounded-lg hover:bg-muted transition-colors duration-[var(--cp-duration-normal)] cursor-pointer"
onClick={onClick}
>
{content}
</button>
);
}
return <div className="flex items-start space-x-4 w-full text-left">{content}</div>;
}