@@ -57,15 +57,37 @@ function onFileSelect (e) {
57
57
const files = [... (target .files || [])]
58
58
if (files .length ) {
59
59
newFileValue .value = files[0 ]
60
- if (! newFileKey .value .trim ()) {
61
- newFileKey .value = files[0 ].name
62
- }
60
+ newFileKey .value = files[0 ].name
63
61
}
64
62
65
63
// Clear the input value so that the same file can be uploaded again
66
- // target.value = ''
64
+ target .value = ' '
67
65
}
68
66
67
+ async function deleteFile (key ) {
68
+ try {
69
+ await useFetch (` /api/storage/${ key} ` , { method: ' DELETE' })
70
+ storage .value = storage .value .filter (t => t .key !== key)
71
+ toast .add ({ title: ` File "${ key} " deleted.` })
72
+ } catch (err) {
73
+ if (err .data ? .data ? .issues ) {
74
+ const title = err .data .data .issues .map (issue => issue .message ).join (' \n ' )
75
+ toast .add ({ title, color: ' red' })
76
+ }
77
+ }
78
+ }
79
+
80
+ onMounted (async () => {
81
+ // FIXME
82
+ // storage.value = await Promise.all(storage.value.map(async (file) => {
83
+ // const { data: { body } } = await useFetch(`/api/storage/${file.key}`, { params: { populate: true } })
84
+ // return {
85
+ // ...file,
86
+ // body
87
+ // }
88
+ // }))
89
+ })
90
+
69
91
const items = [[{
70
92
label: ' Logout' ,
71
93
icon: ' i-heroicons-arrow-left-on-rectangle' ,
@@ -102,28 +124,58 @@ const items = [[{
102
124
autofocus
103
125
: ui= " { wrapper: 'flex-1' }"
104
126
/ >
127
+ < UInput
128
+ : model- value= " newFileValue?.name"
129
+ name= " fileValue"
130
+ disabled
131
+ class = " flex-1"
132
+ autocomplete= " off"
133
+ : ui= " { wrapper: 'flex-1' }"
134
+ / >
105
135
< input
106
136
ref= " uploadRef"
107
137
tabindex= " -1"
108
138
accept= " jpeg, png"
109
139
type= " file"
110
140
name= " file"
111
- class = " flex-1 "
141
+ class = " hidden "
112
142
@change= " onFileSelect"
113
143
>
114
144
145
+ < UButton
146
+ label= " Select file"
147
+ @click= " uploadRef.click()"
148
+ / >
149
+
115
150
< UButton type= " submit" icon= " i-heroicons-plus-20-solid" : loading= " loading" : disabled= " false" / >
116
151
< / div>
117
152
118
- < ul class = " divide-y divide-gray-200 dark:divide-gray-800" >
119
- < li
120
- v- for = " (file, index) of storage"
121
- : key= " index"
122
- class = " flex items-center gap-4 py-2"
153
+ < div class = " grid grid-cols-1 md:grid-cols-3 gap-2" >
154
+ < UCard
155
+ v- for = " file of storage"
156
+ : key= " file.key"
157
+ : ui= " {
158
+ body: {
159
+ base: 'space-y-0',
160
+ padding: ''
161
+ }
162
+ }"
163
+ class = " overflow-hidden relative"
123
164
>
124
- < span class = " flex-1 font-medium" > {{ file .key }}< / span>
125
- < span class = " flex-1 font-medium" > {{ file .httpMetadata ? .contentType || ' -' }}< / span>
126
- < / li>
127
- < / ul>
165
+ < img v- if = " file.httpMetadata?.contentType?.startsWith('image/') && file.body" : src= " `data:${file.httpMetadata.contentType};base64,${(file.body)}`" class = " h-36 w-full object-cover" >
166
+ < div v- else class = " h-36 w-full flex items-center justify-center" >
167
+ {{ file .key }}
168
+ < / div>
169
+ < div class = " flex flex-col gap-1 p-2 border-t border-gray-200 dark:border-gray-800" >
170
+ < span class = " text-sm font-medium" > {{ file .key }}< / span>
171
+ < div class = " flex items-center justify-between" >
172
+ < span class = " text-xs" > {{ file .httpMetadata ? .contentType || ' -' }}< / span>
173
+ < span class = " text-xs" > {{ file .size ? ` ${ Math .round (file .size / Math .pow (1024 , 2 ) * 100 ) / 100 } MB` : ' -' }}< / span>
174
+ < / div>
175
+ < / div>
176
+
177
+ < UButton icon= " i-heroicons-x-mark" variant= " link" color= " primary" class = " absolute top-0 right-0" @click= " deleteFile(file.key)" / >
178
+ < / UCard>
179
+ < / div>
128
180
< / UCard>
129
181
< / template>
0 commit comments