This commit is contained in:
Brandon Egger 2023-06-05 00:07:45 -05:00
parent d4cd046c4b
commit 3d89632047
3 changed files with 96 additions and 58 deletions

View File

@ -13,7 +13,7 @@ const AdminBarLayout = ({
return ( return (
<div className="relative"> <div className="relative">
{data?.user.role === Role.ADMIN ? ( {data?.user.role === Role.ADMIN ? (
<div className="sticky left-0 right-0 top-[71px] z-10 mx-auto mb-3 mt-[15px] flex max-w-4xl flex-row justify-between rounded-xl border border-neutral-600 bg-red-300 drop-shadow-xl sm:mb-6"> <div className="sticky left-0 right-0 top-2 z-10 mx-auto mb-3 mt-4 flex max-w-4xl flex-row justify-between rounded-xl border border-neutral-600 bg-red-300 drop-shadow-xl sm:mb-6">
<h1 className="rounded-lg px-4 py-2 font-semibold text-black"> <h1 className="rounded-lg px-4 py-2 font-semibold text-black">
Admin Mode Admin Mode
</h1> </h1>

View File

@ -1,12 +1,17 @@
import { PaymentType, type AuditoryResource, SkillLevel } from "@prisma/client"; import {
PaymentType,
type AuditoryResource,
SkillLevel,
Skill,
} from "@prisma/client";
import Image from "next/image"; import Image from "next/image";
import { PencilSquareIcon } from "@heroicons/react/24/solid"; import { PencilSquareIcon } from "@heroicons/react/24/solid";
import { import {
MultiSelector, MultiSelector,
MultiSelectorMany, MultiSelectorMany,
MultiSelectorOption, MultiSelectorOption,
SelectedManyContext,
SelectedUniqueContext, SelectedUniqueContext,
SimpleSelectorManyOption,
} from "../../forms/selectors"; } from "../../forms/selectors";
import { InfoInputLine } from "~/components/forms/textInput"; import { InfoInputLine } from "~/components/forms/textInput";
import { PriceIcon } from "~/prices/Icons"; import { PriceIcon } from "~/prices/Icons";
@ -51,8 +56,8 @@ const SelectImageInput = ({ file }: { file?: string }) => {
const ResourceLinkSubForm = ({}) => { const ResourceLinkSubForm = ({}) => {
return ( return (
<div className="mx-4"> <div className="mx-4">
<h1 className="mb-2 border-b border-neutral-400">Links</h1> <h1 className="mb-2 border-b border-neutral-400 text-xl">Links</h1>
<div className="flex mx-auto w-48 flex-col space-y-2"> <div className="mx-auto flex w-48 flex-col space-y-2">
{/** Insert existing links here */} {/** Insert existing links here */}
<button type="button"> <button type="button">
<div className="flex h-14 flex-row space-x-2 rounded-lg border-2 border-neutral-900 bg-amber-300 px-2 align-middle hover:bg-amber-200"> <div className="flex h-14 flex-row space-x-2 rounded-lg border-2 border-neutral-900 bg-amber-300 px-2 align-middle hover:bg-amber-200">
@ -99,42 +104,6 @@ const PaymentTypeOption = ({
); );
}; };
const SkillLevelOption = ({
type,
label,
}: {
type: SkillLevel;
label: string;
}) => {
return (
<MultiSelectorOption value={type}>
<SelectedManyContext.Consumer>
{(selected) => (
<div
className={
(selected.includes(type.toString())
? "bg-stone-800"
: "bg-white") +
" flex flex-row space-x-2 whitespace-nowrap rounded-xl border border-neutral-400 px-2 py-1"
}
>
<span
className={
(selected.includes(type.toString())
? "text-white"
: "text black") +
" my-auto inline-block whitespace-nowrap text-sm"
}
>
{label}
</span>
</div>
)}
</SelectedManyContext.Consumer>
</MultiSelectorOption>
);
};
/** /**
* Resource summary inputs - ie description, manufacturer, etc. * Resource summary inputs - ie description, manufacturer, etc.
*/ */
@ -145,11 +114,14 @@ const ResourceSummarySubForm = ({
}) => { }) => {
return ( return (
<div className="space-y-4 px-4"> <div className="space-y-4 px-4">
<div className="flex flex-row space-x-4 pt-4"> <div className="flex flex-row space-x-4 sm:mt-4">
<div className="flex w-20 flex-col justify-center space-y-2 sm:w-28"> <div className="flex w-20 flex-col justify-center space-y-2 sm:w-28">
<SelectImageInput file={resource?.icon} /> <SelectImageInput file={resource?.icon} />
</div> </div>
<div className="w-full overflow-hidden rounded-xl border border-neutral-400 bg-white drop-shadow-lg"> <div className="flex flex-col justify-center overflow-hidden rounded-xl border border-neutral-400 bg-white drop-shadow-lg sm:w-[300px] md:w-[400px]">
<h2 className="border-b border-neutral-300 px-2 text-center font-semibold">
Resource Details
</h2>
<span className="text-md"> <span className="text-md">
<InfoInputLine <InfoInputLine
placeholder="manufacturer" placeholder="manufacturer"
@ -188,9 +160,30 @@ const ResourceSummarySubForm = ({
label="Skill Level" label="Skill Level"
defaultValues={resource?.skill_levels ?? []} defaultValues={resource?.skill_levels ?? []}
> >
<SkillLevelOption type={SkillLevel.BEGINNER} label="beginner" /> {Object.values(SkillLevel).map((skillLevel, index) => {
<SkillLevelOption type={SkillLevel.INTERMEDIATE} label="intermediate" /> return (
<SkillLevelOption type={SkillLevel.ADVANCED} label="advanced" /> <SimpleSelectorManyOption
key={index}
type={skillLevel}
label={skillLevel.toLowerCase()}
/>
);
})}
</MultiSelectorMany>
<MultiSelectorMany
label="Skills Covered"
defaultValues={resource?.skills ?? []}
>
{Object.values(Skill).map((skill, index) => {
return (
<SimpleSelectorManyOption
key={index}
type={skill}
label={skill.toLowerCase()}
/>
);
})}
</MultiSelectorMany> </MultiSelectorMany>
</div> </div>
); );
@ -207,12 +200,17 @@ const ResourceSummarySubForm = ({
const ResourceForm = ({ resource }: { resource?: AuditoryResource }) => { const ResourceForm = ({ resource }: { resource?: AuditoryResource }) => {
return ( return (
<div className="flex mx-auto max-w-2xl flex-col flex-col-reverse py-1 sm:flex-row sm:divide-x sm:py-4"> <div className="mx-auto flex max-w-2xl flex-col flex-col-reverse py-1 sm:flex-row sm:divide-x sm:py-4">
<div className="flex my-5 mr-4 flex-col justify-end text-lg font-bold"> <div className="my-5 mr-4 flex flex-col justify-end text-lg font-bold">
<ResourceLinkSubForm /> {/** //resource={resource} /> */} <ResourceLinkSubForm /> {/** //resource={resource} /> */}
</div> </div>
<div className="justify-left flex mx-auto max-w-lg flex-col pb-5"> <div>
<ResourceSummarySubForm resource={resource} /> <h1 className="mx-4 mb-2 border-b border-neutral-400 text-xl font-bold sm:hidden">
General
</h1>
<div className="justify-left mx-auto flex max-w-lg flex-col pb-5">
<ResourceSummarySubForm resource={resource} />
</div>
</div> </div>
</div> </div>
); );

View File

@ -1,5 +1,10 @@
import { createContext, useContext, useState } from "react"; import { createContext, useContext, useState } from "react";
// generics
interface ToStringable {
toString: () => string;
}
// Define contexts // Define contexts
const SelectorContext = createContext<{ const SelectorContext = createContext<{
type: "one" | "many"; type: "one" | "many";
@ -13,7 +18,7 @@ const SelectorContext = createContext<{
const SelectedUniqueContext = createContext<string>(""); const SelectedUniqueContext = createContext<string>("");
const SelectedManyContext = createContext<string[]>([]); const SelectedManyContext = createContext<string[]>([]);
function MultiSelectorMany<T extends { toString: () => string }>({ function MultiSelectorMany<T extends ToStringable>({
label, label,
defaultValues, defaultValues,
children, children,
@ -55,7 +60,7 @@ function MultiSelectorMany<T extends { toString: () => string }>({
className="hidden" className="hidden"
value={selected ?? ""} value={selected ?? ""}
/> />
<div className="flex mt-2 flex-row space-x-2 overflow-x-auto"> <div className="mt-2 space-x-2 space-y-2 overflow-x-auto">
{children} {children}
</div> </div>
</div> </div>
@ -64,7 +69,7 @@ function MultiSelectorMany<T extends { toString: () => string }>({
); );
} }
function MultiSelector<T extends { toString: () => string }>({ function MultiSelector<T extends ToStringable>({
label, label,
defaultValue, defaultValue,
children, children,
@ -77,7 +82,7 @@ function MultiSelector<T extends { toString: () => string }>({
return ( return (
<SelectorContext.Provider <SelectorContext.Provider
value={{ type: "many", updateCallback: setSelected }} value={{ type: "one", updateCallback: setSelected }}
> >
<SelectedUniqueContext.Provider value={selected}> <SelectedUniqueContext.Provider value={selected}>
<div className="flex flex-col"> <div className="flex flex-col">
@ -91,16 +96,14 @@ function MultiSelector<T extends { toString: () => string }>({
className="hidden" className="hidden"
value={selected ?? ""} value={selected ?? ""}
/> />
<div className="flex mt-2 flex-row space-x-2 overflow-x-auto"> <div className="space-x-2 space-y-2 overflow-x-auto">{children}</div>
{children}
</div>
</div> </div>
</SelectedUniqueContext.Provider> </SelectedUniqueContext.Provider>
</SelectorContext.Provider> </SelectorContext.Provider>
); );
} }
function MultiSelectorOption<T extends { toString: () => string }>({ function MultiSelectorOption<T extends ToStringable>({
value, value,
children, children,
}: { }: {
@ -121,6 +124,42 @@ function MultiSelectorOption<T extends { toString: () => string }>({
); );
} }
function SimpleSelectorManyOption<T extends ToStringable>({
type,
label,
}: {
type: T;
label: string;
}) {
return (
<MultiSelectorOption value={type}>
<SelectedManyContext.Consumer>
{(selected) => (
<div
className={
(selected.includes(type.toString())
? "bg-stone-800"
: "bg-white") +
" flex flex-row space-x-2 whitespace-nowrap rounded-xl border border-neutral-400 px-2 py-1"
}
>
<span
className={
(selected.includes(type.toString())
? "text-white"
: "text black") +
" my-auto inline-block whitespace-nowrap text-sm"
}
>
{label}
</span>
</div>
)}
</SelectedManyContext.Consumer>
</MultiSelectorOption>
);
}
export { export {
SelectedUniqueContext, SelectedUniqueContext,
SelectorContext, SelectorContext,
@ -128,4 +167,5 @@ export {
MultiSelectorMany, MultiSelectorMany,
MultiSelector, MultiSelector,
MultiSelectorOption, MultiSelectorOption,
SimpleSelectorManyOption,
}; };