Settings redesign

This commit is contained in:
Ategon Dev 2024-07-15 18:29:36 +00:00 committed by Grant
parent c012664613
commit 8f2b29abb5
7 changed files with 128 additions and 119 deletions

View File

@ -1,29 +0,0 @@
import { Button } from "@nextui-org/react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faXmark } from "@fortawesome/free-solid-svg-icons";
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons";
export type InfoHeaderProps = {
setInfoSidebar: (value: boolean) => void
}
export const InfoHeader = ({ setInfoSidebar }: InfoHeaderProps) => {
return (
<header className="flex p-2 justify-between items-center">
<div>
<div className="flex items-center gap-2">
<FontAwesomeIcon icon={faInfoCircle} size="lg" />
<div>
<h1 className="text-xl">Info</h1>
<p className="text-xs text-default-600">Information about the event</p>
</div>
</div>
</div>
<Button size="sm" isIconOnly onClick={() => setInfoSidebar(false)}>
<FontAwesomeIcon icon={faXmark} />
</Button>
</header>
);
};

View File

@ -1,9 +1,8 @@
import { Divider } from "@nextui-org/react";
import { useAppContext } from "../../contexts/AppContext"; import { useAppContext } from "../../contexts/AppContext";
import { InfoHeader } from "./InfoHeader";
import { InfoText } from "./InfoText"; import { InfoText } from "./InfoText";
import { InfoButtons } from "./InfoButtons"; import { InfoButtons } from "./InfoButtons";
import { motion } from "framer-motion" import { SidebarBase } from "../SidebarBase";
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons";
/** /**
* Information sidebar * Information sidebar
@ -16,39 +15,18 @@ export const InfoSidebar = () => {
const { infoSidebar, setInfoSidebar } = useAppContext(); const { infoSidebar, setInfoSidebar } = useAppContext();
return ( return (
<SidebarBase shown={infoSidebar} setSidebarShown={setInfoSidebar} icon={faInfoCircle} title="Info" description="Information about the event" side="Left">
<div className="flex flex-col h-full justify-between">
<div> <div>
<motion.div
className="absolute w-screen h-screen z-50 left-0 top-0 bg-black"
initial={{ opacity: 0, visibility: 'hidden' }}
animate={{ opacity: infoSidebar ? 0.25 : 0, visibility: infoSidebar ? 'visible' : 'hidden' }}
transition={{ type: 'spring', stiffness: 50 }}
/>
<motion.div
className="min-w-[20rem] max-w-[75vw] md:max-w-[30vw] bg-white dark:bg-black flex flex-col justify-between fixed left-0 h-full shadow-xl overflow-y-auto z-50 top-0"
initial={{ x: '-150%' }}
animate={{ x: infoSidebar ? '-50%' : '-150%' }}
transition={{ type: 'spring', stiffness: 50 }}
/>
<motion.div
className="min-w-[20rem] max-w-[75vw] md:max-w-[30vw] bg-white dark:bg-black text-black dark:text-white flex flex-col justify-between fixed left-0 h-full shadow-xl overflow-y-auto z-50 top-0"
initial={{ x: '-100%' }}
animate={{ x: infoSidebar ? 0 : '-100%' }}
transition={{ type: 'spring', stiffness: 50 }}
>
<div>
<InfoHeader setInfoSidebar={setInfoSidebar} />
<Divider />
<InfoButtons /> <InfoButtons />
<InfoText /> <InfoText />
</div> </div>
<div className="p-2"> <div className="p-2">
<p className="text-xs text-default-600">Build {__COMMIT_HASH__}</p> <p className="text-xs text-default-600">Build {__COMMIT_HASH__}</p>
<div id="grecaptcha-badge"></div> <div id="grecaptcha-badge"></div>
</div> </div>
</motion.div>
</div> </div>
);
</SidebarBase>
)
}; };

View File

@ -6,11 +6,12 @@ export const OverlaySettings = () => {
useAppContext(); useAppContext();
return ( return (
<> <div className="flex flex-col gap-4 p-2">
<header> <header className="flex flex-col gap-2">
<h2>Overlays</h2> <h2 className="text-xl">Overlays</h2>
<p className="text-xs text-default-600">Overlays to display additional info over the canvas</p>
</header> </header>
<section> <section className="flex flex-col gap-2">
<Switch <Switch
isSelected={blankOverlay.enabled} isSelected={blankOverlay.enabled}
onValueChange={(v) => onValueChange={(v) =>
@ -56,6 +57,6 @@ export const OverlaySettings = () => {
/> />
)} )}
</section> </section>
</> </div>
); );
}; };

View File

@ -8,18 +8,25 @@ export const ChatSettings = () => {
const { loadChat, setLoadChat } = useAppContext(); const { loadChat, setLoadChat } = useAppContext();
return ( return (
<> <div className="flex flex-col p-2">
<header> <header className="flex flex-col gap-2">
<div className="flex items-center">
<Switch <Switch
size="sm" size="sm"
isSelected={loadChat || false} isSelected={loadChat || false}
onValueChange={setLoadChat} onValueChange={setLoadChat}
/> />
<h2>Chat</h2> <h2 className="text-xl">Chat</h2>
</div>
<p className="text-default-600 text-xs">Chatting with other canvas users</p>
</header> </header>
<section> <section>
<React.Suspense>{loadChat && <InnerChatSettings />}</React.Suspense> <React.Suspense>{loadChat &&
<div className="mt-4">
<InnerChatSettings />
</div>
}</React.Suspense>
</section> </section>
</> </div>
); );
}; };

View File

@ -1,29 +1,24 @@
import { Button } from "@nextui-org/react"; import { faGear } from "@fortawesome/free-solid-svg-icons";
import { useAppContext } from "../../contexts/AppContext"; import { useAppContext } from "../../contexts/AppContext";
import { SidebarBase } from "../SidebarBase";
import { Button, Divider } from "@nextui-org/react";
import { TemplateSettings } from "./TemplateSettings"; import { TemplateSettings } from "./TemplateSettings";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faXmark } from "@fortawesome/free-solid-svg-icons/faXmark";
import { ChatSettings } from "./ChatSettings"; import { ChatSettings } from "./ChatSettings";
import { OverlaySettings } from "../Overlay/OverlaySettings"; import { OverlaySettings } from "../Overlay/OverlaySettings";
export const SettingsSidebar = () => { export const SettingsSidebar = () => {
const { settingsSidebar, setSettingsSidebar, setShowKeybinds } = const { settingsSidebar, setSettingsSidebar, setShowKeybinds } = useAppContext();
useAppContext();
return ( return (
<div <SidebarBase shown={settingsSidebar} setSidebarShown={setSettingsSidebar} icon={faGear} title="Settings" description="Configuration options for customizing your experience" side="Right">
className="sidebar sidebar-right bg-white text-black dark:bg-black dark:text-white" <div className="p-4 flex flex-col gap-4">
style={{ ...(settingsSidebar ? {} : { display: "none" }) }} <TemplateSettings />
> <Divider />
<header> <ChatSettings />
<h1>Settings</h1> <Divider />
<div className="flex-grow" /> <OverlaySettings />
<Button size="sm" isIconOnly onClick={() => setSettingsSidebar(false)}> <Divider />
<FontAwesomeIcon icon={faXmark} />
</Button>
</header>
<section> <section>
abc
<Button <Button
onPress={() => { onPress={() => {
setShowKeybinds(true); setShowKeybinds(true);
@ -33,9 +28,7 @@ export const SettingsSidebar = () => {
Keybinds Keybinds
</Button> </Button>
</section> </section>
<TemplateSettings />
<ChatSettings />
<OverlaySettings />
</div> </div>
); </SidebarBase>
)
}; };

View File

@ -22,16 +22,19 @@ export const TemplateSettings = () => {
} = useTemplateContext(); } = useTemplateContext();
return ( return (
<> <div className="flex flex-col p-2">
<header> <header className="flex flex-col gap-2">
<div className="flex items-center">
<Switch <Switch
size="sm" size="sm"
isSelected={enable || false} isSelected={enable || false}
onValueChange={setEnable} onValueChange={setEnable}
/> />
<h2>Template</h2> <h2 className="text-xl">Template</h2>
</div>
<p className="text-default-600 text-xs">Displaying an image over the canvas to help guide placing</p>
</header> </header>
<section> {enable && <section className="flex flex-col gap-2 mt-4">
<Input <Input
label="Template URL" label="Template URL"
size="sm" size="sm"
@ -102,7 +105,7 @@ export const TemplateSettings = () => {
> >
Show Mobile Tools Show Mobile Tools
</Switch> </Switch>
</section> </section>}
</> </div>
); );
}; };

View File

@ -0,0 +1,56 @@
import { motion } from "framer-motion"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { IconProp } from "@fortawesome/fontawesome-svg-core";
import { Button, Divider } from "@nextui-org/react";
import { faXmark } from "@fortawesome/free-solid-svg-icons";
/**
* Information sidebar
*
* TODO: add customization for this post-event (#46)
*
* @returns
*/
export const SidebarBase = ({children, shown, icon, setSidebarShown, title, description, side}: { children: string | JSX.Element | JSX.Element[], icon: IconProp, shown: boolean, setSidebarShown: (value: boolean) => void, title: string, description: string, side: "Left" | "Right" }) => {
return (
<div>
<motion.div
className={`absolute w-screen h-screen z-50 left-0 top-0 bg-black`}
initial={{ opacity: 0, visibility: 'hidden' }}
animate={{ opacity: shown ? 0.25 : 0, visibility: shown ? 'visible' : 'hidden' }}
transition={{ type: 'spring', stiffness: 50 }}
/>
<motion.div
className={`min-w-[20rem] max-w-[75vw] md:max-w-[30vw] bg-white dark:bg-black flex flex-col justify-between fixed ${side == "Left" ? "left-0" : "right-0"} h-full shadow-xl overflow-y-auto z-50 top-0`}
initial={{ x: side == "Left" ? '-150%' : '150%' }}
animate={{ x: shown ? side == "Left" ? '-50%' : '50%' : side == "Left" ? '-150%' : '150%' }}
transition={{ type: 'spring', stiffness: 50 }}
/>
<motion.div
className={`min-w-[20rem] max-w-[75vw] md:max-w-[30vw] bg-white dark:bg-black text-black dark:text-white flex flex-col fixed ${side == "Left" ? "left-0" : "right-0"} h-full shadow-xl overflow-y-auto z-50 top-0`}
initial={{ x: side == "Left" ? '-100%' : '100%' }}
animate={{ x: shown ? 0 : side == "Left" ? '-100%' : '100%' }}
transition={{ type: 'spring', stiffness: 50 }}
>
<header className="flex p-4 justify-between items-center">
<div>
<div className="flex items-center gap-2">
<FontAwesomeIcon icon={icon} size="lg" />
<div>
<h1 className="text-xl">{title}</h1>
<p className="text-xs text-default-600">{description}</p>
</div>
</div>
</div>
<Button size="sm" isIconOnly onClick={() => setSidebarShown(false)} variant="solid" className="ml-4">
<FontAwesomeIcon icon={faXmark} />
</Button>
</header>
<Divider />
{children}
</motion.div>
</div>
);
};