|
| 1 | +'use client' |
| 2 | + |
| 3 | +import { useCallback, useRef, useState } from 'react' |
| 4 | +import { ArrowUp } from 'lucide-react' |
| 5 | +import Link from 'next/link' |
| 6 | +import { useLandingSubmit } from '@/app/(home)/components/landing-preview/components/landing-preview-panel/landing-preview-panel' |
| 7 | +import { useAnimatedPlaceholder } from '@/app/workspace/[workspaceId]/home/hooks/use-animated-placeholder' |
| 8 | + |
| 9 | +const MAX_HEIGHT = 120 |
| 10 | + |
| 11 | +const CTA_BUTTON = |
| 12 | + 'inline-flex items-center h-[32px] rounded-[5px] border px-[10px] font-[430] font-season text-[14px]' |
| 13 | + |
| 14 | +export function FooterCTA() { |
| 15 | + const landingSubmit = useLandingSubmit() |
| 16 | + const [inputValue, setInputValue] = useState('') |
| 17 | + const textareaRef = useRef<HTMLTextAreaElement>(null) |
| 18 | + const animatedPlaceholder = useAnimatedPlaceholder() |
| 19 | + |
| 20 | + const isEmpty = inputValue.trim().length === 0 |
| 21 | + |
| 22 | + const handleSubmit = useCallback(() => { |
| 23 | + if (isEmpty) return |
| 24 | + landingSubmit(inputValue) |
| 25 | + }, [isEmpty, inputValue, landingSubmit]) |
| 26 | + |
| 27 | + const handleKeyDown = useCallback( |
| 28 | + (e: React.KeyboardEvent<HTMLTextAreaElement>) => { |
| 29 | + if (e.key === 'Enter' && !e.shiftKey) { |
| 30 | + e.preventDefault() |
| 31 | + handleSubmit() |
| 32 | + } |
| 33 | + }, |
| 34 | + [handleSubmit] |
| 35 | + ) |
| 36 | + |
| 37 | + const handleInput = useCallback((e: React.FormEvent<HTMLTextAreaElement>) => { |
| 38 | + const target = e.target as HTMLTextAreaElement |
| 39 | + target.style.height = 'auto' |
| 40 | + target.style.height = `${Math.min(target.scrollHeight, MAX_HEIGHT)}px` |
| 41 | + }, []) |
| 42 | + |
| 43 | + return ( |
| 44 | + <div className='flex flex-col items-center px-4 pt-[120px] pb-[100px] sm:px-8 md:px-[80px]'> |
| 45 | + <h2 className='text-center font-[430] font-season text-[#1C1C1C] text-[28px] leading-[100%] tracking-[-0.02em] sm:text-[32px] md:text-[36px]'> |
| 46 | + What should we get done? |
| 47 | + </h2> |
| 48 | + |
| 49 | + <div className='mt-8 w-full max-w-[42rem]'> |
| 50 | + <div |
| 51 | + className='cursor-text rounded-[20px] border border-[#E5E5E5] bg-white px-[10px] py-[8px] shadow-sm' |
| 52 | + onClick={() => textareaRef.current?.focus()} |
| 53 | + > |
| 54 | + <textarea |
| 55 | + ref={textareaRef} |
| 56 | + value={inputValue} |
| 57 | + onChange={(e) => setInputValue(e.target.value)} |
| 58 | + onKeyDown={handleKeyDown} |
| 59 | + onInput={handleInput} |
| 60 | + placeholder={animatedPlaceholder} |
| 61 | + rows={2} |
| 62 | + className='m-0 box-border min-h-[48px] w-full resize-none border-0 bg-transparent px-[4px] py-[4px] font-body text-[#1C1C1C] text-[15px] leading-[24px] tracking-[-0.015em] outline-none placeholder:font-[380] placeholder:text-[#999] focus-visible:ring-0' |
| 63 | + style={{ caretColor: '#1C1C1C', maxHeight: `${MAX_HEIGHT}px` }} |
| 64 | + /> |
| 65 | + <div className='flex items-center justify-end'> |
| 66 | + <button |
| 67 | + type='button' |
| 68 | + onClick={handleSubmit} |
| 69 | + disabled={isEmpty} |
| 70 | + className='flex h-[28px] w-[28px] items-center justify-center rounded-full border-0 p-0 transition-colors' |
| 71 | + style={{ |
| 72 | + background: isEmpty ? '#C0C0C0' : '#1C1C1C', |
| 73 | + cursor: isEmpty ? 'not-allowed' : 'pointer', |
| 74 | + }} |
| 75 | + > |
| 76 | + <ArrowUp size={16} strokeWidth={2.25} color='#FFFFFF' /> |
| 77 | + </button> |
| 78 | + </div> |
| 79 | + </div> |
| 80 | + </div> |
| 81 | + |
| 82 | + <div className='mt-8 flex gap-[8px]'> |
| 83 | + <a |
| 84 | + href='https://docs.sim.ai' |
| 85 | + target='_blank' |
| 86 | + rel='noopener noreferrer' |
| 87 | + className={`${CTA_BUTTON} border-[#D4D4D4] text-[#1C1C1C] transition-colors hover:bg-[#E8E8E8]`} |
| 88 | + > |
| 89 | + Docs |
| 90 | + </a> |
| 91 | + <Link |
| 92 | + href='/signup' |
| 93 | + className={`${CTA_BUTTON} gap-[8px] border-[#1C1C1C] bg-[#1C1C1C] text-white transition-colors hover:border-[#333] hover:bg-[#333]`} |
| 94 | + > |
| 95 | + Get started |
| 96 | + </Link> |
| 97 | + </div> |
| 98 | + </div> |
| 99 | + ) |
| 100 | +} |
0 commit comments