92 lines
3.6 KiB
TypeScript
92 lines
3.6 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './ui/card';
|
|
import { Button } from './ui/button';
|
|
import { useIsLoggedIn } from '../lib/isLoggedIn';
|
|
import Loader from "./ui/loader";
|
|
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "./ui/dialog";
|
|
|
|
export interface ServiceCardProps {
|
|
title: string;
|
|
description: string;
|
|
imageUrl: string;
|
|
features: string[];
|
|
learnMoreUrl: string;
|
|
buyButtonText: string;
|
|
buyButtonUrl: string;
|
|
}
|
|
|
|
export function ServiceCard({ title, description, imageUrl, features, learnMoreUrl, buyButtonText, buyButtonUrl }: ServiceCardProps) {
|
|
const { isLoggedIn, loading, sessionData } = useIsLoggedIn();
|
|
const [showLoginModal, setShowLoginModal] = useState(false);
|
|
|
|
const handleBuyClick = () => {
|
|
if (!isLoggedIn) {
|
|
setShowLoginModal(true);
|
|
return;
|
|
}
|
|
window.location.href = buyButtonUrl;
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Card className="overflow-hidden transition-all hover:shadow-lg dark:border-neutral-700 h-full flex flex-col">
|
|
<div className="relative h-48 w-full overflow-hidden bg-neutral-100 dark:bg-neutral-800">
|
|
<img
|
|
src={imageUrl}
|
|
alt={`${title}`}
|
|
className="object-cover w-full h-full transition-transform duration-300 hover:scale-105"
|
|
/>
|
|
</div>
|
|
<CardHeader className="pb-3">
|
|
<CardTitle className="text-xl text-[#6d9e37]">{title}</CardTitle>
|
|
<CardDescription className="text-neutral-400">{description}</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="flex-grow">
|
|
<ul className="space-y-2 text-sm">
|
|
{features.map((feature, index) => (
|
|
<li key={index} className="flex items-start">
|
|
<svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5 mr-2 text-[#6d9e37] shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" /></svg>
|
|
<span className='text-zinc-600'>{feature}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</CardContent>
|
|
<CardFooter>
|
|
<div className='flex gap-4 w-full'>
|
|
{buyButtonText && buyButtonUrl && (
|
|
<Button className='w-full' variant='outline' onClick={handleBuyClick}>{buyButtonText}</Button>
|
|
)}
|
|
<a
|
|
href={learnMoreUrl}
|
|
className="inline-flex items-center justify-center rounded-md bg-[#6d9e37] px-4 py-2 text-sm font-medium text-white hover:bg-[#598035] transition-colors w-full"
|
|
>
|
|
Learn More
|
|
</a>
|
|
</div>
|
|
</CardFooter>
|
|
</Card>
|
|
|
|
{/* Login Required Modal */}
|
|
<Dialog open={showLoginModal} onOpenChange={setShowLoginModal}>
|
|
<DialogContent>
|
|
<DialogHeader>
|
|
<DialogTitle className="text-xl mb-2">Login Required</DialogTitle>
|
|
<DialogDescription>
|
|
You need to be logged in to purchase this service.
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
<div className="mt-4 flex flex-col space-y-2">
|
|
<Button onClick={() => window.location.href = '/login'} className="w-full bg-[#6d9e37] hover:bg-[#598035]">Login Now</Button>
|
|
<Button
|
|
variant="outline"
|
|
className="w-full"
|
|
onClick={() => setShowLoginModal(false)}
|
|
>
|
|
Continue Browsing
|
|
</Button>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</>
|
|
);
|
|
} |