1
+ 'use client'
2
+
1
3
import { Dispatch , SetStateAction , useMemo , useState } from 'react'
2
4
import Link from 'next/link'
3
5
import { useRouter } from 'next/navigation'
@@ -26,13 +28,19 @@ import * as ReplFS from '@/lib/repl-fs'
26
28
import { fork , getPageUrl , remove } from '@/lib/repl-stored-state/adapter-supabase'
27
29
import { ReplStoredState } from '@/types'
28
30
29
- export default function ReplCard ( {
30
- repl,
31
- customTimestamp,
32
- } : {
33
- repl : ReplStoredState
34
- customTimestamp ?: React . ReactNode
35
- } ) {
31
+ type Props =
32
+ | {
33
+ repl : ReplStoredState
34
+ mode ?: undefined
35
+ }
36
+ | {
37
+ repl : ReplStoredState & {
38
+ viewed_at : string
39
+ }
40
+ mode : 'recently-viewed'
41
+ }
42
+
43
+ export default function ReplCard ( { repl, mode } : Props ) {
36
44
const user = useUser ( )
37
45
const supabase = useSupabaseClient ( )
38
46
const queryClient = useQueryClient ( )
@@ -46,6 +54,7 @@ export default function ReplCard({
46
54
const url = useMemo ( ( ) => getPageUrl ( repl ) , [ repl ] )
47
55
48
56
const filePath = repl . activeModel
57
+ const datetime = mode === 'recently-viewed' ? repl . viewed_at : repl . updated_at
49
58
50
59
const code = useMemo ( ( ) => {
51
60
const file = filePath ? ReplFS . getFile ( repl . fs , filePath ) : null
@@ -102,10 +111,7 @@ export default function ReplCard({
102
111
} ,
103
112
} )
104
113
105
- const queryKey = [ 'user-repls' , user ?. id ]
106
- queryClient . setQueryData < ReplStoredState [ ] > ( queryKey , ( prev ) => {
107
- return prev ? [ forkedRepl , ...prev ] : prev
108
- } )
114
+ queryClient . invalidateQueries ( { queryKey : [ 'user-repls' , user ?. id ] } )
109
115
} catch ( error ) {
110
116
console . error ( error )
111
117
toast . error ( 'Failed to fork.' )
@@ -151,7 +157,11 @@ export default function ReplCard({
151
157
< h2 className = "font-medium" > { repl . title || 'Untitled' } </ h2 >
152
158
< p className = "text-muted-foreground line-clamp-3 text-sm" > { repl . description } </ p >
153
159
< div className = "mt-auto flex flex-wrap items-center justify-between gap-2 pt-2" >
154
- { customTimestamp ?? < Timestamp repl = { repl } /> }
160
+ { datetime && (
161
+ < span className = "text-muted-foreground text-nowrap text-xs" >
162
+ < RelativeTime date = { new Date ( datetime ) } />
163
+ </ span >
164
+ ) }
155
165
{ repl . user && (
156
166
< div className = "text-muted-foreground flex min-w-0 items-center gap-1 text-xs" >
157
167
< UserAvatar user = { repl . user } size = { 18 } />
@@ -166,18 +176,6 @@ export default function ReplCard({
166
176
)
167
177
}
168
178
169
- function Timestamp ( { repl } : { repl : ReplStoredState } ) {
170
- return (
171
- < >
172
- { repl . updated_at && (
173
- < span className = "text-muted-foreground text-nowrap text-xs" >
174
- < RelativeTime date = { new Date ( repl . updated_at ) } />
175
- </ span >
176
- ) }
177
- </ >
178
- )
179
- }
180
-
181
179
function RemoveButton ( {
182
180
repl,
183
181
isBusy,
@@ -203,13 +201,8 @@ function RemoveButton({
203
201
await remove ( repl . id , { supabase } )
204
202
toast ( 'Deleted.' )
205
203
206
- queryClient . setQueryData < ReplStoredState [ ] > ( [ 'user-repls' , user ?. id ] , ( prev ) => {
207
- return prev ? prev . filter ( ( x ) => x . id !== repl . id ) : prev
208
- } )
209
-
210
- queryClient . setQueryData < ReplStoredState [ ] > ( [ 'recently-viewed-repls' , user ?. id ] , ( prev ) => {
211
- return prev ? prev . filter ( ( x ) => x . id !== repl . id ) : prev
212
- } )
204
+ queryClient . invalidateQueries ( { queryKey : [ 'user-repls' , user ?. id ] } )
205
+ queryClient . invalidateQueries ( { queryKey : [ 'recently-viewed-repls' , user ?. id ] } )
213
206
} catch ( error ) {
214
207
console . error ( error )
215
208
toast . error ( 'Failed to delete.' )
0 commit comments