content.tsx52 lines · main
| 1 | import { Copy } from 'lucide-react' |
| 2 | import { useMemo, useState } from 'react' |
| 3 | import { Button, copyToClipboard } from 'ui' |
| 4 | |
| 5 | import type { StepContentProps } from '@/components/interfaces/ConnectSheet/Connect.types' |
| 6 | |
| 7 | function getShadcnCommand(state: StepContentProps['state']): string | null { |
| 8 | if (state.framework === 'nextjs') { |
| 9 | return 'npx shadcn@latest add @supabase/supabase-client-nextjs' |
| 10 | } |
| 11 | |
| 12 | if (state.framework === 'react') { |
| 13 | return 'npx shadcn@latest add @supabase/supabase-client-react-router' |
| 14 | } |
| 15 | |
| 16 | return null |
| 17 | } |
| 18 | |
| 19 | function ShadcnCommandContent({ state }: StepContentProps) { |
| 20 | const command = useMemo(() => getShadcnCommand(state), [state]) |
| 21 | const [copyLabel, setCopyLabel] = useState('Copy') |
| 22 | |
| 23 | if (!command) return null |
| 24 | |
| 25 | const handleCopy = () => { |
| 26 | copyToClipboard(command, () => { |
| 27 | setCopyLabel('Copied') |
| 28 | setTimeout(() => setCopyLabel('Copy'), 2000) |
| 29 | }) |
| 30 | } |
| 31 | |
| 32 | return ( |
| 33 | <div className="relative group"> |
| 34 | <div className="bg-surface-75 border rounded-lg p-3 pr-20 font-mono text-sm text-foreground-light overflow-x-auto"> |
| 35 | <code>{command}</code> |
| 36 | </div> |
| 37 | <div className="absolute right-2 top-1/2 -translate-y-1/2"> |
| 38 | <Button |
| 39 | type="default" |
| 40 | size="tiny" |
| 41 | icon={<Copy size={14} />} |
| 42 | onClick={handleCopy} |
| 43 | className="opacity-0 group-hover:opacity-100 transition-opacity" |
| 44 | > |
| 45 | {copyLabel} |
| 46 | </Button> |
| 47 | </div> |
| 48 | </div> |
| 49 | ) |
| 50 | } |
| 51 | |
| 52 | export default ShadcnCommandContent |