From 49b80a2f4c3b8ace81064501da3db68d67c342f9 Mon Sep 17 00:00:00 2001 From: Khairul Hidayat Date: Sat, 24 Feb 2024 00:27:52 +0000 Subject: [PATCH] feat: initial editor files, add toast --- components/ui/sonner.tsx | 27 +++++++++++++++++++ lib/utils.ts | 13 +++++++++ package.json | 1 + pages/project/@slug/+data.ts | 8 ++++-- .../@slug/components/console-logger.tsx | 2 +- pages/project/@slug/components/editor.tsx | 18 ++++++------- .../project/@slug/components/file-listing.tsx | 10 +++++-- .../project/@slug/components/file-viewer.tsx | 4 +-- pages/project/@slug/components/status-bar.tsx | 14 +++++++--- pnpm-lock.yaml | 13 +++++++++ renderer/providers.tsx | 20 ++++++++++++-- 11 files changed, 108 insertions(+), 22 deletions(-) create mode 100644 components/ui/sonner.tsx diff --git a/components/ui/sonner.tsx b/components/ui/sonner.tsx new file mode 100644 index 0000000..3da8b8d --- /dev/null +++ b/components/ui/sonner.tsx @@ -0,0 +1,27 @@ +import { Toaster as Sonner } from "sonner"; + +type ToasterProps = React.ComponentProps; + +const Toaster = ({ ...props }: ToasterProps) => { + return ( + + ); +}; + +export { Toaster }; diff --git a/lib/utils.ts b/lib/utils.ts index 06fd997..87eacc9 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,5 +1,7 @@ import { type ClassValue, clsx } from "clsx"; import { twMerge } from "tailwind-merge"; +import copyToClipboard from "copy-to-clipboard"; +import { toast } from "sonner"; import { BASE_URL } from "./consts"; import type { ProjectSchema } from "~/server/db/schema/project"; import type { FileSchema } from "~/server/db/schema/file"; @@ -33,3 +35,14 @@ export const ucfirst = (str: string) => { export const ucwords = (str: string) => { return str.split(" ").map(ucfirst).join(" "); }; + +export const copy = (text: string) => { + copyToClipboard(text, { + onCopy: (data) => { + toast.success("Copied to clipboard!"); + return data; + }, + }); +}; + +export { toast }; diff --git a/package.json b/package.json index 049b010..30d41ea 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "react-hook-form": "^7.50.1", "react-icons": "^5.0.1", "react-resizable-panels": "^2.0.9", + "sonner": "^1.4.1", "tailwind-merge": "^2.2.1", "tailwindcss-animate": "^1.0.7", "usehooks-ts": "^2.14.0", diff --git a/pages/project/@slug/+data.ts b/pages/project/@slug/+data.ts index 2af5e0a..1a5b058 100644 --- a/pages/project/@slug/+data.ts +++ b/pages/project/@slug/+data.ts @@ -4,6 +4,8 @@ import trpcServer from "~/server/api/trpc/trpc"; export const data = async (ctx: PageContext) => { const trpc = await trpcServer(ctx); + const searchParams = ctx.urlParsed.search; + const filesParam = searchParams.files ? searchParams.files.split(",") : null; const project = await trpc.project.getById(ctx.routeParams?.slug!); if (!project) { @@ -11,14 +13,16 @@ export const data = async (ctx: PageContext) => { } const files = await trpc.file.getAll({ projectId: project.id }); - const pinnedFiles = files.filter((i) => i.isPinned); + const initialFiles = files.filter((i) => + filesParam != null ? filesParam.includes(i.path) : i.isPinned + ); return { title: project.title, description: `Check ${project.title} on CodeShare!`, project, files, - pinnedFiles, + initialFiles, }; }; diff --git a/pages/project/@slug/components/console-logger.tsx b/pages/project/@slug/components/console-logger.tsx index e342571..9879ace 100644 --- a/pages/project/@slug/components/console-logger.tsx +++ b/pages/project/@slug/components/console-logger.tsx @@ -6,7 +6,7 @@ const ConsoleLogger = () => { const logs = useConsoleLogs(); return ( -
+

Console

diff --git a/pages/project/@slug/components/editor.tsx b/pages/project/@slug/components/editor.tsx index 399de08..b9c3102 100644 --- a/pages/project/@slug/components/editor.tsx +++ b/pages/project/@slug/components/editor.tsx @@ -20,21 +20,21 @@ import StatusBar from "./status-bar"; import { FiTerminal } from "react-icons/fi"; const Editor = () => { - const { project, pinnedFiles } = useData(); + const { project, initialFiles } = useData(); const trpcUtils = trpc.useUtils(); const projectCtx = useProjectContext(); const [breakpoint] = useBreakpoint(); const [curTabIdx, setCurTabIdx] = useState(0); const [curOpenFiles, setOpenFiles] = useState( - pinnedFiles.map((i) => i.id) + initialFiles.map((i) => i.id) ); const openedFilesData = trpc.file.getAll.useQuery( { projectId: project.id, id: curOpenFiles }, - { enabled: curOpenFiles.length > 0, initialData: pinnedFiles } + { enabled: curOpenFiles.length > 0, initialData: initialFiles } ); - const [openedFiles, setOpenedFiles] = useState(pinnedFiles); + const [openedFiles, setOpenedFiles] = useState(initialFiles); const deleteFile = trpc.file.delete.useMutation({ onSuccess: (file) => { @@ -49,11 +49,11 @@ const Editor = () => { }); useEffect(() => { - if (!pinnedFiles?.length || curOpenFiles.length > 0) { + if (!initialFiles?.length || curOpenFiles.length > 0) { return; } - pinnedFiles.forEach((file) => { + initialFiles.forEach((file) => { onOpenFile(file.id, false); }); @@ -61,7 +61,7 @@ const Editor = () => { setOpenFiles([]); }; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [pinnedFiles]); + }, [initialFiles]); useEffect(() => { if (openedFilesData.data) { @@ -170,7 +170,7 @@ const Editor = () => { collapsedSize={0} /> - + @@ -185,7 +185,7 @@ const Editor = () => { {breakpoint >= 2 ? ( <> - + { Open in new tab + + copy(getUrl(project.slug + `?files=${file.path}`)) + } + > + Share + { return updateFile.mutate({ diff --git a/pages/project/@slug/components/file-viewer.tsx b/pages/project/@slug/components/file-viewer.tsx index 0deb112..86009b9 100644 --- a/pages/project/@slug/components/file-viewer.tsx +++ b/pages/project/@slug/components/file-viewer.tsx @@ -11,8 +11,8 @@ type Props = { }; const FileViewer = ({ id }: Props) => { - const { pinnedFiles } = useData(); - const initialData = pinnedFiles.find((i) => i.id === id); + const { initialFiles } = useData(); + const initialData = initialFiles.find((i) => i.id === id); const { data, isLoading, refetch } = trpc.file.getById.useQuery(id, { initialData, diff --git a/pages/project/@slug/components/status-bar.tsx b/pages/project/@slug/components/status-bar.tsx index cda7e44..7e9a6eb 100644 --- a/pages/project/@slug/components/status-bar.tsx +++ b/pages/project/@slug/components/status-bar.tsx @@ -1,5 +1,5 @@ import React from "react"; -import { FiSidebar, FiSmartphone, FiUser } from "react-icons/fi"; +import { FiArrowLeft, FiSidebar, FiSmartphone, FiUser } from "react-icons/fi"; import { useStore } from "zustand"; import { Button } from "~/components/ui/button"; import { cn } from "~/lib/utils"; @@ -22,24 +22,30 @@ const StatusBar = ({ className }: React.ComponentProps<"div">) => { return (
sidebarStore.getState().toggle()} /> previewStore.getState().toggle()} />
+