Skip to content

Commit

Permalink
cleaner editor
Browse files Browse the repository at this point in the history
  • Loading branch information
tytremblay committed Dec 13, 2024
1 parent 639e3a3 commit 57d7466
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 67 deletions.
File renamed without changes.
48 changes: 23 additions & 25 deletions src/components/ConfigEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Button } from '@/components/ui/button';
import Editor, { useMonaco } from '@monaco-editor/react';
import { useEffect, useMemo, useState } from 'react';
import schema from '../../config/schema.json';
import schema from '../../public/schema.json';
import { getConfig, useQRScoutState } from '../store/store';

type ConfigEditorProps = {
Expand Down Expand Up @@ -29,30 +29,28 @@ export function ConfigEditor(props: ConfigEditorProps) {
});
}, [monaco]);
return (
<div className="h-screen w-screen bg-gray-500 bg-opacity-50 dark:bg-opacity-70 backdrop-blur p-4 ">
<div className="flex flex-col gap-2 h-full shadow-md p-2 rounded-lg bg-gray-50 bg-opacity-20">
<div className="flex-grow rounded-lg overflow-clip ">
<Editor
defaultLanguage="json"
defaultValue={JSON.stringify(config, null, 2)}
theme="vs-dark"
onValidate={markers => {
const severeErrors = markers.filter(m => m.severity > 4);
setErrorCount(severeErrors.length);
}}
onChange={value => value && setCurrentConfigText(value)}
/>
</div>
<div className="flex flex-grow-0 justify-end gap-2">
<Button
variant="destructive"
onClick={() => props.onSave && props.onSave(currentConfigText)}
disabled={currentConfigText.length === 0 || errorCount > 0}
>
Save
</Button>
<Button onClick={props.onCancel}>Cancel</Button>
</div>
<div className="flex flex-col gap-2 h-full ">
<div className="flex-grow rounded-lg overflow-clip ">
<Editor
defaultLanguage="json"
defaultValue={JSON.stringify(config, null, 2)}
theme="vs-dark"
onValidate={markers => {
const severeErrors = markers.filter(m => m.severity > 4);
setErrorCount(severeErrors.length);
}}
onChange={value => value && setCurrentConfigText(value)}
/>
</div>
<div className="flex flex-grow-0 justify-center gap-4">
<Button
variant="destructive"
onClick={() => props.onSave && props.onSave(currentConfigText)}
disabled={currentConfigText.length === 0 || errorCount > 0}
>
Save
</Button>
<Button onClick={props.onCancel}>Cancel</Button>
</div>
</div>
);
Expand Down
37 changes: 3 additions & 34 deletions src/components/Sections/ConfigSection/ConfigSection.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { ConfigEditor } from '@/components/ConfigEditor';
import { Button } from '@/components/ui/button';
import {
Dialog,
Expand All @@ -15,8 +14,6 @@ import {
DrawerTrigger,
} from '@/components/ui/drawer';
import { useMediaQuery } from '@/hooks';
import { setConfig } from '@/store/store';
import { Transition } from '@headlessui/react';
import { Cog6ToothIcon } from '@heroicons/react/20/solid';
import { useMemo, useState } from 'react';
import { Section } from '../../core/Section';
Expand All @@ -25,16 +22,8 @@ import { ThemeSelector } from './ThemeSelector';

export function ConfigSection() {
const [open, setOpen] = useState(false);
const [showEditor, setShowEditor] = useState(false);
const isDesktop = useMediaQuery('(min-width: 768px)');

const handleShowEditor = (show: boolean) => {
if (show) {
setOpen(false);
}
setShowEditor(show);
};

const dialogOrDrawer = useMemo(() => {
if (isDesktop) {
return (
Expand All @@ -49,7 +38,7 @@ export function ConfigSection() {
<DialogHeader>
<DialogTitle>Settings</DialogTitle>
</DialogHeader>
<Settings setShowEditor={handleShowEditor} />
<Settings />
</DialogContent>
</Dialog>
);
Expand All @@ -66,38 +55,18 @@ export function ConfigSection() {
<DrawerHeader>
<DrawerTitle>Settings</DrawerTitle>
</DrawerHeader>
<Settings setShowEditor={handleShowEditor} />
<Settings />
</DrawerContent>
</Drawer>
);
}, [isDesktop, open, setShowEditor]);
}, [isDesktop, open]);

return (
<Section>
<div className="flex flex-col justify-center items-center gap-4">
{dialogOrDrawer}

<ThemeSelector />
</div>

<Transition
show={showEditor}
enter="transition ease-out duration-300 transform"
enterFrom="translate-y-full"
enterTo="translate-y-0"
leave="transition ease-in duration-300 transform"
leaveFrom="translate-y-0"
leaveTo="translate-y-full"
className="z-50 fixed inset-0"
>
<ConfigEditor
onCancel={() => setShowEditor(false)}
onSave={configString => {
setConfig(configString);
setShowEditor(false);
}}
/>
</Transition>
</Section>
);
}
38 changes: 30 additions & 8 deletions src/components/Sections/ConfigSection/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { ConfigEditor } from '@/components/ConfigEditor';
import { Button } from '@/components/ui/button';
import {
Sheet,
SheetContent,
SheetHeader,
SheetTitle,
SheetTrigger,
} from '@/components/ui/sheet';
import { useState } from 'react';
import {
resetToDefaultConfig,
setConfig,
uploadConfig,
useQRScoutState,
} from '../../../store/store';
Expand Down Expand Up @@ -40,12 +50,9 @@ function downloadConfig(formData: Config) {
download('QRScout_config.json', JSON.stringify(configDownload));
}

type SettingsProps = {
setShowEditor: (showEditor: boolean) => void;
};

export function Settings({ setShowEditor }: SettingsProps) {
export function Settings() {
const formData = useQRScoutState(state => state.formData);
const [showEditor, setShowEditor] = useState(false);
return (
<div className="flex flex-col gap-4 px-6">
<Button
Expand All @@ -62,9 +69,24 @@ export function Settings({ setShowEditor }: SettingsProps) {
>
Copy Column Names
</Button>
<Button variant="secondary" onClick={() => setShowEditor(true)}>
Edit Config
</Button>
<Sheet open={showEditor} onOpenChange={setShowEditor}>
<SheetTrigger asChild>
<Button variant="secondary">Edit Config</Button>
</SheetTrigger>
<SheetContent side="bottom" className="w-full h-full">
<SheetHeader>
<SheetTitle>Edit Config</SheetTitle>
</SheetHeader>
<ConfigEditor
onCancel={() => setShowEditor(false)}
onSave={configString => {
setConfig(configString);
setShowEditor(false);
}}
/>
</SheetContent>
</Sheet>

<Button variant="secondary" onClick={() => downloadConfig(formData)}>
Download Config
</Button>
Expand Down
138 changes: 138 additions & 0 deletions src/components/ui/sheet.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import * as React from "react"
import * as SheetPrimitive from "@radix-ui/react-dialog"
import { cva, type VariantProps } from "class-variance-authority"
import { X } from "lucide-react"

import { cn } from "@/lib/utils"

const Sheet = SheetPrimitive.Root

const SheetTrigger = SheetPrimitive.Trigger

const SheetClose = SheetPrimitive.Close

const SheetPortal = SheetPrimitive.Portal

const SheetOverlay = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Overlay>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Overlay>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Overlay
className={cn(
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className
)}
{...props}
ref={ref}
/>
))
SheetOverlay.displayName = SheetPrimitive.Overlay.displayName

const sheetVariants = cva(
"fixed z-50 gap-4 bg-background p-6 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500 data-[state=open]:animate-in data-[state=closed]:animate-out",
{
variants: {
side: {
top: "inset-x-0 top-0 border-b data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top",
bottom:
"inset-x-0 bottom-0 border-t data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom",
left: "inset-y-0 left-0 h-full w-3/4 border-r data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left sm:max-w-sm",
right:
"inset-y-0 right-0 h-full w-3/4 border-l data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right sm:max-w-sm",
},
},
defaultVariants: {
side: "right",
},
}
)

interface SheetContentProps
extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>,
VariantProps<typeof sheetVariants> {}

const SheetContent = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Content>,
SheetContentProps
>(({ side = "right", className, children, ...props }, ref) => (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content
ref={ref}
className={cn(sheetVariants({ side }), className)}
{...props}
>
<SheetPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-secondary">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
{children}
</SheetPrimitive.Content>
</SheetPortal>
))
SheetContent.displayName = SheetPrimitive.Content.displayName

const SheetHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-2 text-center sm:text-left",
className
)}
{...props}
/>
)
SheetHeader.displayName = "SheetHeader"

const SheetFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className
)}
{...props}
/>
)
SheetFooter.displayName = "SheetFooter"

const SheetTitle = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Title>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Title
ref={ref}
className={cn("text-lg font-semibold text-foreground", className)}
{...props}
/>
))
SheetTitle.displayName = SheetPrimitive.Title.displayName

const SheetDescription = React.forwardRef<
React.ElementRef<typeof SheetPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof SheetPrimitive.Description>
>(({ className, ...props }, ref) => (
<SheetPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
SheetDescription.displayName = SheetPrimitive.Description.displayName

export {
Sheet,
SheetPortal,
SheetOverlay,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
}

0 comments on commit 57d7466

Please sign in to comment.