forked from cerc-io/snowballtools-base
commit ea08482596e10f27536af2d32040b476a18085e0 Author: icld <ian@icld.io> Date: Tue Feb 25 07:06:03 2025 -0800 refactor: update WalletContext import and enhance layout components
106 lines
2.8 KiB
TypeScript
106 lines
2.8 KiB
TypeScript
import { Tag } from '@/components/shared/Tag';
|
|
import { useToast } from '@/components/shared/Toast';
|
|
import { Card } from '@/components/ui/card';
|
|
import { cn } from '@/utils/classnames';
|
|
import { GitBranch } from 'lucide-react';
|
|
import React, { ComponentPropsWithoutRef, useCallback } from 'react';
|
|
import { useNavigate, useParams } from 'react-router-dom';
|
|
|
|
export interface TemplateDetail {
|
|
id: string;
|
|
name: string;
|
|
icon: string;
|
|
repoFullName?: string;
|
|
isComingSoon?: boolean;
|
|
}
|
|
|
|
export interface TemplateCardProps extends ComponentPropsWithoutRef<'div'> {
|
|
template: TemplateDetail;
|
|
isGitAuth: boolean;
|
|
}
|
|
|
|
export const TemplateCard: React.FC<TemplateCardProps> = ({
|
|
template,
|
|
isGitAuth,
|
|
className,
|
|
...props
|
|
}: TemplateCardProps) => {
|
|
const { toast, dismiss } = useToast();
|
|
const navigate = useNavigate();
|
|
const { orgSlug } = useParams();
|
|
|
|
const handleClick = useCallback(() => {
|
|
if (template?.isComingSoon) {
|
|
return toast({
|
|
id: 'coming-soon',
|
|
title: 'This template is coming soon',
|
|
variant: 'info',
|
|
onDismiss: dismiss,
|
|
});
|
|
}
|
|
|
|
if (isGitAuth) {
|
|
return navigate(
|
|
`/${orgSlug}/projects/create/template?templateId=${template.id}`,
|
|
);
|
|
}
|
|
|
|
return toast({
|
|
id: 'connect-git-account',
|
|
title: 'Connect Git account to start with a template',
|
|
variant: 'error',
|
|
onDismiss: dismiss,
|
|
});
|
|
}, [orgSlug, dismiss, isGitAuth, navigate, template, toast]);
|
|
|
|
// Extract short name for icon (e.g., "PWA" from "Progressive Web App")
|
|
const shortName = template.name
|
|
.split(' ')
|
|
.map((word) => word[0])
|
|
.join('')
|
|
.slice(0, 3);
|
|
|
|
return (
|
|
<Card
|
|
className={cn(
|
|
'flex flex-col gap-2 p-4 bg-[#121212] hover:bg-[#1a1a1a] rounded-xl cursor-pointer transition-all',
|
|
template?.isComingSoon && 'cursor-default opacity-70',
|
|
className,
|
|
)}
|
|
onClick={handleClick}
|
|
{...props}
|
|
>
|
|
<div className="flex items-start gap-3">
|
|
{/* Icon */}
|
|
<div className="flex-shrink-0 w-10 h-10 flex items-center justify-center rounded-md bg-[#1E1E1E] text-white font-medium text-xs">
|
|
{shortName}
|
|
</div>
|
|
|
|
<div className="flex flex-col gap-1">
|
|
{/* Name */}
|
|
<p className="text-sm font-medium text-white">{template.name}</p>
|
|
|
|
{/* Repo name */}
|
|
{template.repoFullName && (
|
|
<div className="flex items-center gap-1 text-[#8A8A8E] text-xs">
|
|
<GitBranch size={12} />
|
|
<span>{template.repoFullName}</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{template?.isComingSoon && (
|
|
<Tag
|
|
size="xs"
|
|
type="neutral"
|
|
leftIcon={<GitBranch size={12} />}
|
|
className="self-start mt-1"
|
|
>
|
|
Soon
|
|
</Tag>
|
|
)}
|
|
</Card>
|
|
);
|
|
};
|