LogoPicker.tsx124 lines · main
1import { useBreakpoint } from 'common'
2import { ChevronLeft } from 'lucide-react'
3import { useEffect, useState } from 'react'
4import {
5 Button,
6 Dialog,
7 DialogContent,
8 DialogHeader,
9 DialogTitle,
10 Sheet,
11 SheetContent,
12 SheetHeader,
13 SheetTitle,
14} from 'ui'
15
16import { BucketFilePickerExplorer } from '../../Storage/BucketFilePickerDialog/BucketFilePickerExplorer'
17import { BucketFilePickerStateContextProvider } from '../../Storage/BucketFilePickerDialog/BucketFilePickerState'
18import { BucketsPicker } from '../../Storage/BucketsPickerDialog/BucketsPicker'
19import type { Bucket } from '@/data/storage/buckets-query'
20
21export type StorageFilePickerProps = {
22 open: boolean
23 onOpenChange: (open: boolean) => void
24 onSelect: (value: string) => void
25}
26
27export function LogoPicker({ open, onOpenChange, onSelect }: StorageFilePickerProps) {
28 const [selectedBucket, setSelectedBucket] = useState<Bucket | null>(null)
29
30 const isMobileLayout = useBreakpoint('lg')
31
32 useEffect(() => {
33 if (!open) {
34 setSelectedBucket(null)
35 }
36 }, [open])
37
38 const handleSelect = (value: string) => {
39 onSelect(value)
40 onOpenChange(false)
41 }
42
43 return (
44 <>
45 {isMobileLayout ? (
46 <Sheet open={open} onOpenChange={onOpenChange}>
47 <SheetContent side="bottom" className="flex h-[85vh] flex-col gap-0 p-0">
48 {selectedBucket ? (
49 <SheetHeader className="flex flex-row items-center gap-2 border-b border-overlay px-6 py-4">
50 <Button
51 type="text"
52 size="tiny"
53 icon={<ChevronLeft size={16} />}
54 className="shrink-0"
55 onClick={() => setSelectedBucket(null)}
56 >
57 Buckets
58 </Button>
59 <SheetTitle className="min-w-0 flex-1">Choose a file</SheetTitle>
60 </SheetHeader>
61 ) : (
62 <SheetHeader className="flex flex-row items-center gap-2 border-b border-overlay px-6 py-4">
63 <SheetTitle className="min-w-0 flex-1">Select a bucket</SheetTitle>
64 </SheetHeader>
65 )}
66 <div className="flex h-full min-h-0 min-w-0 flex-1 flex-col px-2 pb-3 pt-2">
67 {selectedBucket ? (
68 <BucketFilePickerStateContextProvider
69 bucket={selectedBucket}
70 maxFiles={1}
71 acceptedFileExtensions={['.png', '.jpg', '.jpeg', '.svg']}
72 >
73 <BucketFilePickerExplorer onSelect={handleSelect} />
74 </BucketFilePickerStateContextProvider>
75 ) : (
76 <BucketsPicker onSelectBucket={setSelectedBucket} allowedBucketType="public" />
77 )}
78 </div>
79 </SheetContent>
80 </Sheet>
81 ) : (
82 <Dialog open={open} onOpenChange={onOpenChange}>
83 <DialogContent
84 size="xxlarge"
85 className="flex h-[85vh] max-h-[500px] max-w-5xl flex-col gap-0 overflow-hidden p-0"
86 >
87 {selectedBucket ? (
88 <DialogHeader className="flex flex-row items-center gap-2 border-b border-overlay px-6 py-4 h-[60px]">
89 <Button
90 type="text"
91 size="tiny"
92 icon={<ChevronLeft size={16} />}
93 className="shrink-0"
94 onClick={() => setSelectedBucket(null)}
95 >
96 Buckets
97 </Button>
98 <DialogTitle className="min-w-0 flex-1">Choose a file</DialogTitle>
99 </DialogHeader>
100 ) : (
101 <DialogHeader className="flex flex-row items-center gap-2 border-b border-overlay px-6 py-4 h-[60px]">
102 <DialogTitle className="min-w-0 flex-1">Select a bucket</DialogTitle>
103 </DialogHeader>
104 )}
105
106 <div className="flex h-full min-h-0 min-w-0 flex-1 flex-col overflow-hidden p-3">
107 {selectedBucket ? (
108 <BucketFilePickerStateContextProvider
109 bucket={selectedBucket}
110 maxFiles={1}
111 acceptedFileExtensions={['.png', '.jpg', '.jpeg', '.svg']}
112 >
113 <BucketFilePickerExplorer onSelect={handleSelect} />
114 </BucketFilePickerStateContextProvider>
115 ) : (
116 <BucketsPicker onSelectBucket={setSelectedBucket} allowedBucketType="public" />
117 )}
118 </div>
119 </DialogContent>
120 </Dialog>
121 )}
122 </>
123 )
124}