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 { InfoHeader } from "./InfoHeader";
import { InfoText } from "./InfoText";
import { InfoButtons } from "./InfoButtons";
import { motion } from "framer-motion"
import { SidebarBase } from "../SidebarBase";
import { faInfoCircle } from "@fortawesome/free-solid-svg-icons";
/**
* Information sidebar
@ -16,39 +15,18 @@ export const InfoSidebar = () => {
const { infoSidebar, setInfoSidebar } = useAppContext();
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: 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 }}
>
<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>
<InfoHeader setInfoSidebar={setInfoSidebar} />
<Divider />
<InfoButtons />
<InfoText />
</div>
<div className="p-2">
<p className="text-xs text-default-600">Build {__COMMIT_HASH__}</p>
<div id="grecaptcha-badge"></div>
</div>
</motion.div>
</div>
);
};
</div>
</SidebarBase>
)
};

View File

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

View File

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

View File

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

View File

@ -22,16 +22,19 @@ export const TemplateSettings = () => {
} = useTemplateContext();
return (
<>
<header>
<Switch
size="sm"
isSelected={enable || false}
onValueChange={setEnable}
/>
<h2>Template</h2>
<div className="flex flex-col p-2">
<header className="flex flex-col gap-2">
<div className="flex items-center">
<Switch
size="sm"
isSelected={enable || false}
onValueChange={setEnable}
/>
<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>
<section>
{enable && <section className="flex flex-col gap-2 mt-4">
<Input
label="Template URL"
size="sm"
@ -102,7 +105,7 @@ export const TemplateSettings = () => {
>
Show Mobile Tools
</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>
);
};