Skip to content

Commit

Permalink
feat(GIST-97): replace patch by put
Browse files Browse the repository at this point in the history
  • Loading branch information
Courtcircuits committed Nov 13, 2024
1 parent 782ace6 commit 0572537
Show file tree
Hide file tree
Showing 7 changed files with 161 additions and 29 deletions.
27 changes: 21 additions & 6 deletions src/app/(gistLayout)/mygist/[gistId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"use client"
import React from "react"
import MyGistIdPage from "./page-ui"
import { useGist, usePatchGistContent, usePatchGistName } from "@/lib/queries/gists.queries"
import { useEditGist, useGist, usePatchGistContent, usePatchGistName } from "@/lib/queries/gists.queries"
import { useToast } from "@/components/shadcn/use-toast"
import { getRawGistURL } from "@/lib/utils"
import { useMe } from "@/lib/queries/user.queries"

interface MyGistIdFeaturePageProps {
params: {
Expand All @@ -15,6 +16,7 @@ export default function MyGistIdFeaturePage({ params }: MyGistIdFeaturePageProps
const { gistId } = params
const { data } = useGist(gistId)
const { toast } = useToast()
const { data: me } = useMe()

const { mutate: updateName } = usePatchGistName({

Check warning on line 21 in src/app/(gistLayout)/mygist/[gistId]/page.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'updateName' is assigned a value but never used
onSuccess: () => {
Expand All @@ -29,18 +31,31 @@ export default function MyGistIdFeaturePage({ params }: MyGistIdFeaturePageProps
onSuccess: () => {},
})

const { mutate: edit } = useEditGist({
onSuccess: () => {
toast({
title: "Gist Saved",
description: "Your gist has been saved successfully",
})
},
})
const onDownload = () => {
toast({
title: "Gist Downloaded",
description: "Your gist has been downloaded successfully",
})
}
const onSave = (name: string, code: string) => {
updateContent({ id: gistId, content: code })
updateName({ id: gistId, name })
toast({
title: "Gist Saved",
description: "Your gist has been saved successfully",
console.log("save")
edit({
id: gistId,
name,
content: code,
description: "",
visibility: "public",
org_id: null,
language: "plaintext",
owner_id: me?.id || "",
})
}

Expand Down
12 changes: 10 additions & 2 deletions src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use client"
import { useToast } from "@/components/shadcn/use-toast"
import GistDetails from "@/components/ui/gist-details"
import { useGist, usePatchGistContent, usePatchGistName } from "@/lib/queries/gists.queries"
import { useEditGist, useGist, usePatchGistContent, usePatchGistName } from "@/lib/queries/gists.queries"
import { useOrg } from "@/lib/queries/orgs.queries"
import { getRawGistURL } from "@/lib/utils"
import React from "react"
Expand Down Expand Up @@ -31,6 +31,15 @@ export default function MyOrgGistIdFeaturePage({ params }: MyOrgGistIdFeaturePag
onSuccess: () => {},
})

const { mutate: edit } = useEditGist({

Check warning on line 34 in src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'edit' is assigned a value but never used
onSuccess: () => {
toast({
title: "Gist Saved",
description: "Your gist has been saved successfully",
})
},
})

const onDownload = () => {
toast({
title: "Gist Downloaded",
Expand All @@ -56,7 +65,6 @@ export default function MyOrgGistIdFeaturePage({ params }: MyOrgGistIdFeaturePag
}

const onDelete = (id: string) => {

Check warning on line 67 in src/app/(gistLayout)/org/[orgId]/gist/[gistId]/page.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'id' is defined but never used
console.log(`Deleting gist with ID: ${id}`)
toast({
title: "Gist Deleted",
description: "Your gist has been deleted successfully",
Expand Down
1 change: 0 additions & 1 deletion src/components/contexts/pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ export function PaginationProvider({ children, fromUrl }: { children: ReactNode;
if (searchParams.has("page")) {
const page = parseInt(searchParams.get("page") as string)
const offset = (page - 1) * limit
console.log("offset", offset)
if (!checkOffset(offset)) return
setOffset(offset)
}
Expand Down
16 changes: 12 additions & 4 deletions src/components/ui/gist-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import {
Trash2Icon,
} from "lucide-react"
import Link from "next/link"
import { useState } from "react"
import { useEffect, useState } from "react"
import { Codearea } from "../shadcn/codearea"
import { getLanguage } from "@/lib/language"
import TooltipShortcut, { TooltipShortcutTrigger } from "./tooltip-shortcut"
import { getBackendURL, getRawGistURL } from "@/lib/utils"
import { getRawGistURL } from "@/lib/utils"
import { SidebarTrigger } from "../shadcn/sidebar"
import { Button } from "../shadcn/button"

Expand Down Expand Up @@ -46,6 +46,15 @@ export default function GistDetails({
const [gistId] = useState(gist.id)
const [gistName, setGistName] = useState(gist.name)
const [gistCode, setGistCode] = useState(gist.code)
const [needSync, setNeedSync] = useState(false)

useEffect(() => {
if (gist.name !== gistName || gist.code !== gistCode) {
setNeedSync(true)
} else {
setNeedSync(false)
}
}, [gistName, gistCode])

const gistState: Gist = {
id: gistId,
Expand All @@ -54,7 +63,6 @@ export default function GistDetails({
}

const onOpenPlainText = (gistID: string) => {
// if production go to https://raw.gists.app/{gistID}
console.log(process.env.NODE_ENV)
window.open(getRawGistURL(gistID), "_blank")
}
Expand Down Expand Up @@ -117,7 +125,7 @@ export default function GistDetails({
</TooltipShortcut>
<TooltipShortcut tooltip="Save" shortcuts={["Ctrl", "S"]}>
<TooltipShortcutTrigger>
<MenuButton onClick={() => onSave(gistName, gistCode)} variant={"menu"}>
<MenuButton onClick={() => onSave(gistName, gistCode)} variant={"menu"} disabled={!needSync}>
<span>Save</span>
</MenuButton>
</TooltipShortcutTrigger>
Expand Down
102 changes: 86 additions & 16 deletions src/lib/queries/gists.queries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
import ky from "ky"
import { getBackendURL } from "../utils"
import { Gist } from "@/types"
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
import { keepPreviousData, useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query"

Check warning on line 5 in src/lib/queries/gists.queries.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'keepPreviousData' is defined but never used
import { useEffect } from "react"
import { useGistStorage } from "../storage/gists"

Check warning on line 7 in src/lib/queries/gists.queries.tsx

View workflow job for this annotation

GitHub Actions / Test linting

'useGistStorage' is defined but never used

//types

Expand All @@ -11,6 +13,9 @@ export interface ApiGist {
name: string
content: string
owner_id: string
language: string
description: string
visibility: string
org_id: string | null
}

Expand Down Expand Up @@ -131,17 +136,35 @@ const fetchDeleteGist = async (id: string) => {
//hooks

export const useGists = ({ offset, limit }: { offset?: number; limit?: number }) => {
const { data, error, isPending } = useQuery({
queryKey: ["gists", offset?.toString(), limit?.toString()],
queryFn: () =>
fetchGists({
offset: offset || 0,
const { data, error, isFetching, fetchNextPage, fetchPreviousPage } = useInfiniteQuery({
queryKey: ["gists"],
queryFn: ({ pageParam }) => fetchGists(pageParam),
initialPageParam: {
offset: offset || 0,
limit: limit || 50,
},
getNextPageParam: (lastPage, allPages, lastPageParam, allPageParams) => {
return {
offset: offset || 0 + (limit || 50),
limit: limit || 50,
}),
staleTime: 5000,
}
},
})

return { data: data?.gists, nb_pages: data?.nb_pages, error, isPending }
const currentPage = Math.trunc((offset || 0) / (limit || 50))

useEffect(() => {
fetchNextPage() //prefetch
}, [offset, limit])

return {
data: data?.pages[currentPage]?.gists,
nb_pages: data?.pages[0].nb_pages,
error,
isPending: isFetching,
fetchNextPage,
fetchPreviousPage,
}
}

export const useGist = (gistId: string) => {
Expand All @@ -160,10 +183,14 @@ export const useCreateGist = ({ onSuccess }: { onSuccess: () => void }) => {
return fetchCreateGist(gist)
},
onSuccess: (newGist) => {
queryClient.setQueryData(["gists"], (oldData: any) => {
// Assuming oldData is an array, you might need to adjust this based on your actual data structure
return [...(oldData || []), newGist]
})
//invalidate
queryClient.invalidateQueries({ queryKey: ["gists"] })
// queryClient.setQueryData(["gists"], (oldData: any) => {
// // Assuming oldData is an array, you might need to adjust this based on your actual data structure
//
//
// return [...(oldData || []), newGist]
// })

// Call the onSuccess callback if provided
if (onSuccess) {
Expand Down Expand Up @@ -228,12 +255,55 @@ export const useDeleteGist = ({ onSuccess }: { onSuccess: (id: string) => void }
return fetchDeleteGist(id)
},
onSuccess: (gistID) => {
queryClient.setQueryData(["gists"], (oldData: any) => {
return oldData.filter((gist: Gist) => gist.id !== gistID.toString())
})
// queryClient.setQueryData(["gists"], (oldData: any) => {
// return oldData.filter((gist: Gist) => gist.id !== gistID.toString())
// })
queryClient.invalidateQueries({ queryKey: ["gists"] })
onSuccess(gistID.toString())
},
})

return { mutate, error, data, isPending }
}

const fetchUpdateGist = async (payload: ApiGist): Promise<Gist> => {
const json = await ky
.put(`${getBackendURL()}/gists/${payload.id}`, {
credentials: "include",
json: {
name: payload.name,
content: payload.content,
description: payload.description,
visibility: payload.visibility,
org_id: payload.org_id,
},
})
.json<ApiGist>()
console.log(json)
return {
id: json.id,
name: json.name,
code: json.content,
}
}

export const useEditGist = ({ onSuccess }: { onSuccess: () => void }) => {
const queryClient = useQueryClient() // Access the Query Client

const { mutate, error, data, isPending } = useMutation({
mutationFn: (payload: ApiGist) => {
return fetchUpdateGist(payload)
},
onError(error, variables, context) {
console.log(error)
},
onSuccess: (newGist) => {
queryClient.invalidateQueries({ queryKey: ["gists"] })
queryClient.invalidateQueries({ queryKey: ["gists", newGist.id] })
if (onSuccess) {
onSuccess()
}
},
})
return { mutate, error, data, isPending }
}
12 changes: 12 additions & 0 deletions src/lib/storage/gists.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Gist } from "@/types"
import DataStorage from "./storage"
import { set } from "react-hook-form"

const globalGistStorage = new DataStorage<Gist>()

export const useGistStorage = () => {
return {
set: globalGistStorage.set.bind(globalGistStorage),
getItems: globalGistStorage.getItems.bind(globalGistStorage),
}
}
20 changes: 20 additions & 0 deletions src/lib/storage/storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"use client"
interface ItemWithID {
id: string
}

class DataStorage<T extends ItemWithID> {
private data: Map<string, T> = new Map()
set(data: T) {
this.data.set(data.id, data)
}
getItems(offset?: number, limit?: number): T[] {
if (offset !== undefined && limit !== undefined) {
return Array.from(this.data.values()).slice(offset, offset + limit)
}

return Array.from(this.data.values())
}
}

export default DataStorage

0 comments on commit 0572537

Please sign in to comment.