mirror of
https://github.com/BrenBroZAYT/gameyfin.git
synced 2026-06-15 16:20:03 +00:00
Finish theming implementation (finally...)
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import {useField} from "formik";
|
||||
import {XCircle} from "@phosphor-icons/react";
|
||||
import {Input as ShadcnInput} from "Frontend/@/components/ui/input";
|
||||
import {Label} from "Frontend/@/components/ui/label";
|
||||
import {Input as NextUiInput} from "@nextui-org/react";
|
||||
|
||||
// @ts-ignore
|
||||
const Input = ({label, ...props}) => {
|
||||
@@ -10,19 +9,17 @@ const Input = ({label, ...props}) => {
|
||||
|
||||
return (
|
||||
<div className="grid w-full max-w-sm items-center gap-1.5">
|
||||
<Label htmlFor={label}>{label}</Label>
|
||||
<ShadcnInput
|
||||
<NextUiInput
|
||||
{...props}
|
||||
{...field}
|
||||
id={label}
|
||||
placeholder={label}
|
||||
isInvalid={meta.touched && !!meta.error}
|
||||
errorMessage={
|
||||
<small className="flex flex-row items-center gap-1 text-danger">
|
||||
<XCircle weight="fill" size={14}/> {meta.error}
|
||||
</small>}
|
||||
/>
|
||||
{(meta.touched && !!meta.error) ?
|
||||
<small
|
||||
className="flex flex-row items-center gap-1 text-red-500"
|
||||
>
|
||||
<XCircle weight="fill" size={14}/> {meta.error}
|
||||
</small> : <></>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
import {useState} from "react";
|
||||
import {useAuth} from "Frontend/util/auth";
|
||||
import {useNavigate} from "react-router-dom";
|
||||
import {GearFine, Question, SignOut, User} from "@phosphor-icons/react";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger
|
||||
} from "Frontend/@/components/ui/dropdown-menu";
|
||||
import {Avatar, AvatarFallback} from "Frontend/@/components/ui/avatar";
|
||||
import {Avatar, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger} from "@nextui-org/react";
|
||||
|
||||
export default function ProfileMenu() {
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
const {state, logout} = useAuth();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -36,28 +28,33 @@ export default function ProfileMenu() {
|
||||
label: "Sign Out",
|
||||
icon: <SignOut/>,
|
||||
onClick: () => logout(),
|
||||
color: "red-500"
|
||||
color: "danger"
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<DropdownMenu open={isMenuOpen}>
|
||||
<DropdownMenuTrigger>
|
||||
<Avatar>
|
||||
<AvatarFallback>{state.user?.name?.substring(0, 2).toUpperCase()}</AvatarFallback>
|
||||
</Avatar>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<Dropdown placement="bottom-end">
|
||||
<DropdownTrigger>
|
||||
<Avatar showFallback radius="full" as="button" className="transition-transform"/>
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu>
|
||||
{/* @ts-ignore */}
|
||||
{profileMenuItems.map(({label, icon, onClick, showIf, color}) => {
|
||||
return (
|
||||
(showIf === undefined || showIf === true) ?
|
||||
<DropdownMenuItem key={label} onClick={onClick}>
|
||||
{icon}
|
||||
<p color={color ? color : ""}>{label}</p>
|
||||
</DropdownMenuItem> : null
|
||||
<DropdownItem
|
||||
key={label}
|
||||
onClick={onClick}
|
||||
startContent={<div color={color}>{icon}</div>}
|
||||
/* @ts-ignore */
|
||||
color={color ? color : ""}
|
||||
className={`text-${color}`}
|
||||
>
|
||||
{label}
|
||||
</DropdownItem> : null
|
||||
);
|
||||
})}
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</DropdownMenu>
|
||||
</Dropdown>
|
||||
);
|
||||
}
|
||||
@@ -1,26 +1,16 @@
|
||||
import {hsl} from "Frontend/@/lib/utils";
|
||||
|
||||
export default function GameyfinLogo({primary, secondary, className}: {
|
||||
primary: string,
|
||||
secondary: string,
|
||||
export default function GameyfinLogo({className}: {
|
||||
className?: string
|
||||
}) {
|
||||
const primaryColor = hsl(primary)
|
||||
const secondaryColor = (secondary === null || secondary === undefined) ? primaryColor : hsl(secondary);
|
||||
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 365.58 336.34" className={className}>
|
||||
<polygon points="190.1 49.13 190.1 69.24 207.98 44.13 190.1 49.13" fill={secondaryColor}/>
|
||||
<polygon points="365.58 0 263.22 28.66 205.64 95.97 365.58 51.18 365.58 0" fill={secondaryColor}/>
|
||||
<polygon points="190.1 49.13 190.1 69.24 207.98 44.13 190.1 49.13"/>
|
||||
<polygon points="365.58 0 263.22 28.66 205.64 95.97 365.58 51.18 365.58 0"/>
|
||||
<polygon
|
||||
points="190.1 283.11 248.6 266.73 248.6 149.74 365.58 116.99 365.58 73.12 190.1 122.25 190.1 283.11"
|
||||
fill={secondaryColor}/>
|
||||
points="190.1 283.11 248.6 266.73 248.6 149.74 365.58 116.99 365.58 73.12 190.1 122.25 190.1 283.11"/>
|
||||
<polygon
|
||||
points="58.49 144.48 155.98 117.18 175.48 89.79 175.48 53.23 0 102.36 0 336.34 58.49 254.15 58.49 144.48"
|
||||
fill={primaryColor}/>
|
||||
points="58.49 144.48 155.98 117.18 175.48 89.79 175.48 53.23 0 102.36 0 336.34 58.49 254.15 58.49 144.48"/>
|
||||
<polygon
|
||||
points="116.99 199.59 116.99 245.09 65.81 259.42 0 336.34 175.48 287.2 175.48 170.22 131.61 182.5 116.99 199.59"
|
||||
fill={primaryColor}/>
|
||||
points="116.99 199.59 116.99 245.09 65.81 259.42 0 336.34 175.48 287.2 175.48 170.22 131.61 182.5 116.99 199.59"/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -1,41 +1,25 @@
|
||||
import {Theme} from "Frontend/@/registry/themes";
|
||||
import {Card} from "Frontend/@/components/ui/card";
|
||||
import {Tooltip, TooltipContent, TooltipTrigger} from "Frontend/@/components/ui/tooltip";
|
||||
import {useTheme} from "next-themes";
|
||||
import {Theme} from "Frontend/theming/theme";
|
||||
import {Card, Tooltip} from "@nextui-org/react";
|
||||
import GameyfinLogo from "Frontend/components/theming/GameyfinLogo";
|
||||
import {hsl} from "Frontend/@/lib/utils";
|
||||
|
||||
export default function ThemePreview({theme}: { theme: Theme }) {
|
||||
//@ts-ignore
|
||||
let resolvedTheme: "light" | "dark" = useTheme().resolvedTheme ?? "light";
|
||||
const {setTheme} = useTheme();
|
||||
|
||||
function toggleMode() {
|
||||
resolvedTheme = resolvedTheme === "light" ? "dark" : "light";
|
||||
setTheme(resolvedTheme);
|
||||
}
|
||||
|
||||
export default function ThemePreview({theme, mode, isSelected}: {
|
||||
theme: Theme,
|
||||
mode: "light" | "dark",
|
||||
isSelected?: boolean
|
||||
}) {
|
||||
return (
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Card
|
||||
className="overflow-hidden flex place-self-center justify-center p-6"
|
||||
style={{background: hsl(theme.cssVars[resolvedTheme].background)}}>
|
||||
<GameyfinLogo primary={theme.cssVars[resolvedTheme].primary}
|
||||
secondary={theme.cssVars[resolvedTheme].secondary}
|
||||
className="w-1/2"
|
||||
/>
|
||||
</Card>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent side="bottom">
|
||||
<p className="capitalize">{theme.name}</p>
|
||||
</TooltipContent>
|
||||
<Tooltip content={<p className="capitalize">{theme.name?.replace("-", " ")}</p>} placement="bottom">
|
||||
<Card
|
||||
shadow="none"
|
||||
className={`${theme.name}-${mode} flex-row justify-center p-6 border-2 ${isSelected ? "border-focus" : "border-foreground-200 hover:border-focus"}`}
|
||||
>
|
||||
<GameyfinLogo className="w-1/2 fill-primary"/>
|
||||
</Card>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
<svg width="228" height="120" viewBox="0 0 228 120" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="background" d="M0 0H228V120H0V0Z" fill={theme.cssVars[resolvedTheme].background}/>
|
||||
<rect id="background-secondary" x="29" y="54" width="144" height="53" rx="2" fill="#30363D"/>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, {ReactNode, useState} from "react";
|
||||
import {Form, Formik, FormikBag, FormikHelpers} from "formik";
|
||||
import {ArrowLeft, ArrowRight, Check, SpinnerGap} from "@phosphor-icons/react";
|
||||
import {Button} from "Frontend/@/components/ui/button";
|
||||
import {ArrowLeft, ArrowRight, Check} from "@phosphor-icons/react";
|
||||
import {Button} from "@nextui-org/react";
|
||||
import {Step, Stepper} from "@material-tailwind/react";
|
||||
|
||||
const Wizard = ({children, initialValues, onSubmit}: {
|
||||
children: ReactNode,
|
||||
@@ -51,31 +52,34 @@ const Wizard = ({children, initialValues, onSubmit}: {
|
||||
{formik => (
|
||||
<Form className="flex flex-col h-full">
|
||||
<div className="w-full mb-8">
|
||||
<p>Step {stepNumber + 1} of {steps.length}</p>
|
||||
{/*<Stepper activeStep={stepNumber}>
|
||||
{/*<p>Step {stepNumber + 1} of {steps.length}</p>*/}
|
||||
<Stepper activeStep={stepNumber} activeLineClassName="bg-primary"
|
||||
lineClassName="bg-foreground">
|
||||
{steps.map((child, index) => (
|
||||
<Step key={index}>
|
||||
<Step key={index}
|
||||
className="bg-foreground text-background"
|
||||
activeClassName="bg-primary"
|
||||
completedClassName="bg-primary">
|
||||
{/*@ts-ignore*/}
|
||||
{child.props.icon}
|
||||
</Step>
|
||||
))}
|
||||
</Stepper>*/}
|
||||
</Stepper>
|
||||
</div>
|
||||
<div className="flex grow">
|
||||
{step}
|
||||
</div>
|
||||
<div className="bottom-0 w-full">
|
||||
<div className="flex justify-between">
|
||||
<Button onClick={() => previous(formik.values)} disabled={isFirstStep}
|
||||
className="rounded-full">
|
||||
<Button color="primary" onClick={() => previous(formik.values)} disabled={isFirstStep}>
|
||||
<ArrowLeft/>
|
||||
</Button>
|
||||
<Button disabled={formik.isSubmitting}
|
||||
className="rounded-full"
|
||||
type="submit"
|
||||
<Button
|
||||
color="primary"
|
||||
isLoading={formik.isSubmitting}
|
||||
type="submit"
|
||||
>
|
||||
{formik.isSubmitting ?
|
||||
<SpinnerGap className="animate-spin"/> : isLastStep ? <Check/> : <ArrowRight/>
|
||||
}
|
||||
{formik.isSubmitting ? "" : isLastStep ? <Check/> : <ArrowRight/>}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user