riffusion-app/components/Settings.tsx

445 lines
16 KiB
TypeScript

import { RadioGroup, Listbox, Dialog, Transition } from "@headlessui/react";
import { Fragment, useState } from "react";
import { FiSettings, FiChevronsDown, FiCheck } from "react-icons/fi";
import styled, { css } from "styled-components";
const ModalContainer = styled.div`
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
`;
const plans = [
{
name: 'Startup',
ram: '12GB',
cpus: '6 CPUs',
disk: '160 GB SSD disk',
},
{
name: 'Business',
ram: '16GB',
cpus: '8 CPUs',
disk: '512 GB SSD disk',
},
{
name: 'Enterprise',
ram: '32GB',
cpus: '12 CPUs',
disk: '1024 GB SSD disk',
},
]
export default function Settings() {
const [open, setOpen] = useState(false);
var classNameCondition = ""
if (open) {
classNameCondition = "fixed z-20 top-64 mt-4 right-4 md:top-68 md:right-8 bg-sky-400 w-14 h-14 rounded-full drop-shadow-lg flex justify-center items-center text-white text-2xl hover:bg-sky-500 hover:drop-shadow-2xl"
} else {
classNameCondition = "fixed z-20 top-64 mt-4 right-4 md:top-68 md:right-8 bg-slate-100 w-14 h-14 rounded-full drop-shadow-lg flex justify-center items-center text-sky-900 text-2xl hover:text-white hover:bg-sky-600 hover:drop-shadow-2xl"
}
return (
<>
<button
title="Settings"
className={classNameCondition}
onClick={() => setOpen(true)}
>
<FiSettings />
</button>
<Transition appear show={open} as={Fragment}>
<Dialog
as="div"
className="fixed inset-0 z-10 overflow-y-auto"
onClose={() => setOpen(false)}
>
<div className="min-h-screen px-4 text-center">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="fixed inset-0" />
</Transition.Child>
<span
className="inline-block h-screen align-middle"
aria-hidden="true"
>
&#8203;
</span>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 scale-95"
enterTo="opacity-100 scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
<ModalContainer>
<div className="my-8 inline-block w-full max-w-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h1"
className="text-3xl font-medium leading-6 text-gray-900 pb-2"
>
Settings
</Dialog.Title>
<div className="mt-4">
<p className="text-sm text-gray-500">
{Denoising()}
{Drop()}
{/* choose options */}
{/* {Example()} */}
<br></br>
{/* {Radio()} */}
</p>
</div>
<div className="mt-6">
<button
className="relative inline-flex items-center justify-center p-0.5 mb-2 mr-2 overflow-hidden text-sm font-medium text-gray-900 rounded-lg group bg-sky-500 group-hover:from-sky-600 group-hover:to-sky-500 hover:text-white"
onClick={() => {
window.open("/about", "_blank");
setOpen(false);
}}
>
<span className="relative px-5 py-2 transition-all ease-in duration-75 bg-white rounded-md group-hover:bg-opacity-0">
Cancel
</span>
</button>
<button
type="button"
className="text-white bg-gradient-to-br from-purple-600 to-sky-500 hover:bg-gradient-to-bl font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2"
onClick={() => setOpen(false)}
>
Let&apos;s Riff 🎸
</button>
</div>
</div>
</ModalContainer>
</Transition.Child>
</div>
</Dialog>
</Transition>
</>
);
};
export function Denoising() {
return (
<div>
<label htmlFor="price" className="block text-sm font-medium text-gray-700">
Denoising
</label>
<div className="relative mt-1 rounded-md shadow-sm">
<input
type="text"
name="denoising"
className="block w-full rounded-md border-gray-300 pl-7 pr-12 focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
placeholder="0.75"
/>
</div>
</div>
)
}
export function Example() {
const [selected, setSelected] = useState(people[0])
return (
<div className="fixed top-16 w-72">
<Listbox value={selected} onChange={setSelected}>
<div className="relative mt-1">
<Listbox.Button className="relative w-full cursor-default rounded-lg bg-white py-2 pl-3 pr-10 text-left shadow-md focus:outline-none focus-visible:border-indigo-500 focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-orange-300 sm:text-sm">
<span className="block truncate">{selected.name}</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<FiChevronsDown
className="h-5 w-5 text-gray-400"
aria-hidden="true"
/>
</span>
</Listbox.Button>
<Transition
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="absolute mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{people.map((person, personIdx) => (
<Listbox.Option
key={personIdx}
className={({ active }) =>
`relative cursor-default select-none py-2 pl-10 pr-4 ${active ? 'bg-amber-100 text-amber-900' : 'text-gray-900'
}`
}
value={person}
>
{({ selected }) => (
<>
<span
className={`block truncate ${selected ? 'font-medium' : 'font-normal'
}`}
>
{person.name}
</span>
{selected ? (
<span className="absolute inset-y-0 left-0 flex items-center pl-3 text-amber-600">
<FiCheck className="h-5 w-5" aria-hidden="true" />
</span>
) : null}
</>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Transition>
</div>
</Listbox>
</div>
)
}
export function Radio() {
const [selected, setSelected] = useState(plans[0])
return (
<div className="w-full px-4 py-16">
<div className="mx-auto w-full max-w-md">
<RadioGroup value={selected} onChange={setSelected}>
<RadioGroup.Label className="sr-only">Server size</RadioGroup.Label>
<div className="space-y-2">
{plans.map((plan) => (
<RadioGroup.Option
key={plan.name}
value={plan}
className={({ active, checked }) =>
`${active
? 'ring-2 ring-white ring-opacity-60 ring-offset-2 ring-offset-sky-300'
: ''
}
${checked ? 'bg-sky-900 bg-opacity-75 text-white' : 'bg-white'
}
relative flex cursor-pointer rounded-lg px-5 py-4 shadow-md focus:outline-none`
}
>
{({ active, checked }) => (
<>
<div className="flex w-full items-center justify-between">
<div className="flex items-center">
<div className="text-sm">
<RadioGroup.Label
as="p"
className={`font-medium ${checked ? 'text-white' : 'text-gray-900'
}`}
>
{plan.name}
</RadioGroup.Label>
<RadioGroup.Description
as="span"
className={`inline ${checked ? 'text-sky-100' : 'text-gray-500'
}`}
>
<span>
{plan.ram}/{plan.cpus}
</span>{' '}
<span aria-hidden="true">&middot;</span>{' '}
<span>{plan.disk}</span>
</RadioGroup.Description>
</div>
</div>
{checked && (
<div className="shrink-0 text-white">
<CheckIcon className="h-6 w-6" />
</div>
)}
</div>
</>
)}
</RadioGroup.Option>
))}
</div>
</RadioGroup>
</div>
</div>
)
}
function CheckIcon(props) {
return (
<svg viewBox="0 0 24 24" fill="none" {...props}>
<circle cx={12} cy={12} r={12} fill="#fff" opacity="0.2" />
<path
d="M7 13l3 3 7-7"
stroke="#fff"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
)
}
const people = [
{
id: 1,
name: 'Wade Cooper',
avatar:
'https://images.unsplash.com/photo-1491528323818-fdd1faba62cc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
{
id: 2,
name: 'Arlene Mccoy',
avatar:
'https://images.unsplash.com/photo-1550525811-e5869dd03032?ixlib=rb-1.2.1&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
{
id: 3,
name: 'Devon Webb',
avatar:
'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.25&w=256&h=256&q=80',
},
{
id: 4,
name: 'Tom Cook',
avatar:
'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
{
id: 5,
name: 'Tanya Fox',
avatar:
'https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
{
id: 6,
name: 'Hellen Schmidt',
avatar:
'https://images.unsplash.com/photo-1487412720507-e7ab37603c6f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
{
id: 7,
name: 'Caroline Schultz',
avatar:
'https://images.unsplash.com/photo-1568409938619-12e139227838?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
{
id: 8,
name: 'Mason Heaney',
avatar:
'https://images.unsplash.com/photo-1531427186611-ecfd6d936c79?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
{
id: 9,
name: 'Claudie Smitham',
avatar:
'https://images.unsplash.com/photo-1584486520270-19eca1efcce5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
{
id: 10,
name: 'Emil Schaefer',
avatar:
'https://images.unsplash.com/photo-1561505457-3bcad021f8ee?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80',
},
]
function classNames(...classes) {
return classes.filter(Boolean).join(' ')
}
export function Drop() {
const [selected, setSelected] = useState(people[3])
return (
<Listbox value={selected} onChange={setSelected}>
{({ open }) => (
<>
<Listbox.Label className="block text-sm font-medium text-gray-700">Assigned to</Listbox.Label>
<div className="relative mt-1">
<Listbox.Button className="relative w-full cursor-default rounded-md border border-gray-300 bg-white py-2 pl-3 pr-10 text-left shadow-sm focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 sm:text-sm">
<span className="flex items-center">
<img src={selected.avatar} alt="" className="h-6 w-6 flex-shrink-0 rounded-full" />
<span className="ml-3 block truncate">{selected.name}</span>
</span>
<span className="pointer-events-none absolute inset-y-0 right-0 ml-3 flex items-center pr-2">
<FiChevronsDown className="h-5 w-5 text-gray-400" aria-hidden="true" />
</span>
</Listbox.Button>
<Transition
show={open}
as={Fragment}
leave="transition ease-in duration-100"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Listbox.Options className="absolute z-10 mt-1 max-h-56 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
{people.map((person) => (
<Listbox.Option
key={person.id}
className={({ active }) =>
classNames(
active ? 'text-white bg-indigo-600' : 'text-gray-900',
'relative cursor-default select-none py-2 pl-3 pr-9'
)
}
value={person}
>
{({ selected, active }) => (
<>
<div className="flex items-center">
<img src={person.avatar} alt="" className="h-6 w-6 flex-shrink-0 rounded-full" />
<span
className={classNames(selected ? 'font-semibold' : 'font-normal', 'ml-3 block truncate')}
>
{person.name}
</span>
</div>
{selected ? (
<span
className={classNames(
active ? 'text-white' : 'text-indigo-600',
'absolute inset-y-0 right-0 flex items-center pr-4'
)}
>
<CheckIcon className="h-5 w-5" aria-hidden="true" />
</span>
) : null}
</>
)}
</Listbox.Option>
))}
</Listbox.Options>
</Transition>
</div>
</>
)}
</Listbox>
)
}