Files
eventspace/frontend/src/components/info-card.tsx
Felipe Cardoso 03cb95b4b3
Some checks failed
Build and Push Docker Images / changes (push) Successful in 5s
Build and Push Docker Images / build-backend (push) Has been skipped
Build and Push Docker Images / build-frontend (push) Failing after 57s
Refactor gift registry UI to use InfoCard component
Simplified the gift registry section by replacing custom JSX with the reusable InfoCard component. This improves code maintainability and consistency in the UI while retaining the existing styles and functionality. Updated InfoCard styling to ensure compatibility with the new use case.
2025-03-14 15:27:13 +01:00

144 lines
3.6 KiB
TypeScript

import React from "react";
import Image from "next/image";
import Link from "next/link";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
interface CardButton {
text: string;
href: string;
backgroundColor?: string;
textColor?: string;
}
interface InfoCardProps {
imageSrc?: string | null;
imageAlt?: string;
imagePosition?: "left" | "right";
borderColor?: string;
backgroundColor?: string;
boxShadow?: string;
headingText: string;
headingStyle?: React.CSSProperties;
bodyText?: string;
bodyTextColor?: string;
buttonProps?: CardButtonProps;
}
interface CardButtonProps {
text: string;
href: string;
backgroundColor?: string;
textColor?: string;
}
const InfoCard: React.FC<InfoCardProps> = ({
imageSrc,
imageAlt = "Image",
imagePosition = "left",
borderColor = "#ccc",
backgroundColor = "rgba(240,233,214,0.7)",
boxShadow = "0 2px 4px rgba(0, 0, 0, 0.05)",
headingText,
headingStyle = {},
bodyText,
bodyTextColor = "#555",
buttonProps,
}) => {
const imageElement = (
<div className="mb-4 hidden md:mb-0 md:block">
<div
className="flex h-28 w-28 items-center justify-center rounded-full border-2 md:h-32 md:w-32"
style={{ borderColor }}
>
{imageSrc ? (
<div className="relative h-24 w-24 md:h-28 md:w-28">
<Image
src={imageSrc}
alt={imageAlt ?? "Image"}
fill
className="object-contain"
/>
</div>
) : (
<p className="text-center text-sm">{imageAlt ?? "Image"}</p>
)}
</div>
</div>
);
return (
<div
className={cn(
"mb-10 flex flex-col items-center md:items-start md:space-x-6",
imagePosition === "right"
? "md:flex-row-reverse md:space-x-reverse"
: "md:flex-row",
"w-full",
)}
>
{imageElement}
<Card
className="flex-1 relative overflow-hidden p-6 w-full"
style={{ backgroundColor, borderColor, boxShadow }}
>
{imageSrc && (
<div
className={cn(
"absolute bottom-0 h-32 w-32 opacity-20 md:hidden",
imagePosition === "right" ? "left-0" : "right-0",
)}
style={{
backgroundImage: `url(${imageSrc})`,
backgroundSize: "contain",
backgroundRepeat: "no-repeat",
backgroundPosition:
imagePosition === "right" ? "bottom left" : "bottom right",
}}
/>
)}
<h3
className="mb-2 text-center text-2xl font-bold md:text-left"
style={headingStyle}
>
{headingText}
</h3>
{bodyText && (
<p
className="text-center md:text-left"
style={{ color: bodyTextColor }}
>
{bodyText}
</p>
)}
{buttonProps && (
<div className="mt-4 text-center md:text-left">
<Link
href={buttonProps.href}
target="_blank"
rel="noopener noreferrer"
>
<Button
className="rounded-full"
style={{
backgroundColor: buttonProps.backgroundColor,
color: buttonProps.textColor ?? "white",
}}
>
{buttonProps.text}
</Button>
</Link>
</div>
)}
</Card>
</div>
);
};
export default InfoCard;