mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-23 23:05:46 +00:00
feat(FE-92-94): Slicing UI detail chickin & refactor number input chickin form
This commit is contained in:
@@ -0,0 +1,178 @@
|
||||
"use client";
|
||||
|
||||
import { HTMLAttributes, ReactNode } from "react";
|
||||
|
||||
import { cn } from "@/lib/helper";
|
||||
import Image from "next/image";
|
||||
|
||||
export interface CardProps
|
||||
extends Omit<HTMLAttributes<HTMLDivElement>, "className"> {
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
image?: string;
|
||||
imageAlt?: string;
|
||||
imageWidth?: number;
|
||||
imageHeight?: number;
|
||||
actions?: ReactNode;
|
||||
footer?: ReactNode;
|
||||
className?: {
|
||||
wrapper?: string;
|
||||
image?: string;
|
||||
body?: string;
|
||||
title?: string;
|
||||
subtitle?: string;
|
||||
actions?: string;
|
||||
footer?: string;
|
||||
};
|
||||
variant?: "default" | "compact" | "bordered" | "shadow" | "image-full";
|
||||
size?: "sm" | "md" | "lg";
|
||||
}
|
||||
|
||||
const Card = ({
|
||||
title,
|
||||
subtitle,
|
||||
image,
|
||||
imageAlt,
|
||||
imageWidth,
|
||||
imageHeight,
|
||||
actions,
|
||||
footer,
|
||||
className,
|
||||
variant = "default",
|
||||
size = "md",
|
||||
children,
|
||||
...props
|
||||
}: CardProps) => {
|
||||
const getCardClasses = () => {
|
||||
const baseClasses = "card bg-base-100";
|
||||
|
||||
const variantClasses = {
|
||||
default: "",
|
||||
compact: "card-compact",
|
||||
bordered: "border border-base-300",
|
||||
shadow: "shadow-xl",
|
||||
"image-full": "card-side card-compact shadow-xl",
|
||||
};
|
||||
|
||||
const sizeClasses = {
|
||||
sm: "w-64",
|
||||
md: "w-96",
|
||||
lg: "w-[28rem]",
|
||||
};
|
||||
|
||||
return cn(
|
||||
baseClasses,
|
||||
variantClasses[variant],
|
||||
variant !== "image-full" ? sizeClasses[size] : "",
|
||||
className?.wrapper,
|
||||
);
|
||||
};
|
||||
|
||||
const getImageDimensions = () => {
|
||||
if (variant === "image-full") {
|
||||
return {
|
||||
width: imageWidth || 128,
|
||||
height: imageHeight || 128,
|
||||
};
|
||||
}
|
||||
|
||||
const cardWidths = {
|
||||
sm: 256, // w-64
|
||||
md: 384, // w-96
|
||||
lg: 448, // w-[28rem]
|
||||
};
|
||||
|
||||
return {
|
||||
width: imageWidth || cardWidths[size],
|
||||
height: imageHeight || 192,
|
||||
};
|
||||
};
|
||||
|
||||
const getImageClasses = () => {
|
||||
if (variant === "image-full") {
|
||||
return cn("object-cover", className?.image);
|
||||
}
|
||||
return cn("w-full object-cover", className?.image);
|
||||
};
|
||||
|
||||
const getBodyClasses = () => {
|
||||
const baseClasses = "card-body";
|
||||
|
||||
if (variant === "compact" || variant === "image-full") {
|
||||
return cn(baseClasses, "p-4", className?.body);
|
||||
}
|
||||
|
||||
return cn(baseClasses, "p-6", className?.body);
|
||||
};
|
||||
|
||||
const getTitleClasses = () => {
|
||||
const sizeClasses = {
|
||||
sm: "text-lg",
|
||||
md: "text-xl",
|
||||
lg: "text-2xl",
|
||||
};
|
||||
|
||||
return cn("card-title font-bold", sizeClasses[size], className?.title);
|
||||
};
|
||||
|
||||
const getSubtitleClasses = () => {
|
||||
return cn("text-base-content/70 text-sm mt-1", className?.subtitle);
|
||||
};
|
||||
|
||||
const getActionsClasses = () => {
|
||||
return cn("card-actions justify-end mt-4", className?.actions);
|
||||
};
|
||||
|
||||
const getFooterClasses = () => {
|
||||
return cn("border-t border-base-300 mt-4 pt-4", className?.footer);
|
||||
};
|
||||
|
||||
if (variant === "image-full" && image) {
|
||||
const imageDimensions = getImageDimensions();
|
||||
return (
|
||||
<div className={getCardClasses()} {...props}>
|
||||
<figure>
|
||||
<Image
|
||||
src={image}
|
||||
alt={imageAlt || title || "Card image"}
|
||||
width={imageDimensions.width}
|
||||
height={imageDimensions.height}
|
||||
className={getImageClasses()}
|
||||
/>
|
||||
</figure>
|
||||
<div className={getBodyClasses()}>
|
||||
{title && <h2 className={getTitleClasses()}>{title}</h2>}
|
||||
{subtitle && <p className={getSubtitleClasses()}>{subtitle}</p>}
|
||||
{children}
|
||||
{actions && <div className={getActionsClasses()}>{actions}</div>}
|
||||
</div>
|
||||
{footer && <div className={getFooterClasses()}>{footer}</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={getCardClasses()} {...props}>
|
||||
{image && (
|
||||
<figure>
|
||||
<Image
|
||||
src={image}
|
||||
alt={imageAlt || title || "Card image"}
|
||||
width={getImageDimensions().width}
|
||||
height={getImageDimensions().height}
|
||||
className={getImageClasses()}
|
||||
/>
|
||||
</figure>
|
||||
)}
|
||||
<div className={getBodyClasses()}>
|
||||
{title && <h2 className={getTitleClasses()}>{title}</h2>}
|
||||
{subtitle && <p className={getSubtitleClasses()}>{subtitle}</p>}
|
||||
{children}
|
||||
{actions && <div className={getActionsClasses()}>{actions}</div>}
|
||||
</div>
|
||||
{footer && <div className={getFooterClasses()}>{footer}</div>}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Card;
|
||||
Reference in New Issue
Block a user