ClientLibraryInfo.tsx129 lines · main
1// End of third-party imports
2
3import { CLIENT_LIBRARIES } from 'common/constants'
4import { ExternalLink } from 'lucide-react'
5import Link from 'next/link'
6import type { UseFormReturn } from 'react-hook-form'
7import {
8 Button,
9 cn,
10 FormControl,
11 FormField,
12 Select,
13 SelectContent,
14 SelectGroup,
15 SelectItem,
16 SelectTrigger,
17 SelectValue,
18} from 'ui'
19import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
20
21import type { ExtendedSupportCategories } from './Support.constants'
22import type { SupportFormValues } from './SupportForm.schema'
23import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
24
25interface ClientLibraryInfoProps {
26 form: UseFormReturn<SupportFormValues>
27 category: ExtendedSupportCategories
28 library: string | undefined
29}
30
31export function ClientLibraryInfo({ form, category, library }: ClientLibraryInfoProps) {
32 const showClientLibraries = useIsFeatureEnabled('support:show_client_libraries')
33
34 if (!showClientLibraries) return null
35 if (category !== 'Problem') return null
36
37 return (
38 <div className="flex flex-col gap-y-1">
39 <FormField
40 name="library"
41 control={form.control}
42 render={({ field }) => (
43 <FormItemLayout layout="vertical" label="Which library are you having issues with">
44 <FormControl>
45 <Select {...field} defaultValue={field.value} onValueChange={field.onChange}>
46 <SelectTrigger className="w-full" aria-label="Select a library">
47 <SelectValue placeholder="Select a library" />
48 </SelectTrigger>
49 <SelectContent>
50 <SelectGroup>
51 {CLIENT_LIBRARIES.map((option) => (
52 <SelectItem key={option.language} value={option.language}>
53 {option.language}
54 </SelectItem>
55 ))}
56 </SelectGroup>
57 </SelectContent>
58 </Select>
59 </FormControl>
60 </FormItemLayout>
61 )}
62 />
63 {library && library.length > 0 && <LibrarySuggestions library={library} />}
64 </div>
65 )
66}
67
68interface LibrarySuggestionsProps {
69 library: string
70}
71
72const LibrarySuggestions = ({ library }: LibrarySuggestionsProps) => {
73 const selectedLibrary = CLIENT_LIBRARIES.find((lib) => lib.language === library)
74 const selectedClientLibraries = selectedLibrary?.libraries.filter((library) =>
75 library.name.includes('briven-')
76 )
77 return (
78 <div className="flex flex-col gap-y-4">
79 <div className="space-y-2">
80 <p className="text-sm text-foreground-light">
81 Found an issue or a bug? Try searching our GitHub issues or submit a new one.
82 </p>
83 </div>
84 <div className="flex items-center space-x-4 overflow-x-auto">
85 {selectedClientLibraries?.map((lib) => {
86 const libraryLanguage = library === 'Dart (Flutter)' ? lib.name.split('-')[1] : library
87 return (
88 <div
89 key={lib.name}
90 className="w-[230px] min-w-[230px] min-h-[128px] rounded-sm border border-control bg-surface-100 space-y-3 px-4 py-3"
91 >
92 <div className="space-y-1">
93 <p className="text-sm">{lib.name}</p>
94 <p className="text-sm text-foreground-light">
95 For issues regarding the {libraryLanguage} client library
96 </p>
97 </div>
98 <div>
99 <Button asChild type="default" icon={<ExternalLink size={14} strokeWidth={1.5} />}>
100 <Link href={lib.url} target="_blank" rel="noreferrer">
101 View GitHub issues
102 </Link>
103 </Button>
104 </div>
105 </div>
106 )
107 })}
108 <div
109 className={cn(
110 'px-4 py-3 rounded-sm border border-control bg-surface-100',
111 'w-[230px] min-w-[230px] min-h-[128px] flex flex-col justify-between space-y-3'
112 )}
113 >
114 <div className="space-y-1">
115 <p className="text-sm">briven</p>
116 <p className="text-sm text-foreground-light">For any issues about our API</p>
117 </div>
118 <div>
119 <Button asChild type="default" icon={<ExternalLink size={14} strokeWidth={1.5} />}>
120 <Link href="https://github.com/briven/briven" target="_blank" rel="noreferrer">
121 View GitHub issues
122 </Link>
123 </Button>
124 </div>
125 </div>
126 </div>
127 </div>
128 )
129}