Started the New Proposal button dialog

This commit is contained in:
2023-03-24 03:15:48 -05:00
parent 0e064dd9b7
commit 19c73ac33e
2 changed files with 153 additions and 1 deletions

View File

@@ -0,0 +1,93 @@
import { typo } from "@styles/typography";
import { cva } from "class-variance-authority";
import type { ChangeEvent } from "react";
import { useEffect, useRef, useState } from "react";
import Image from "next/image";
const input = cva([
typo({ tag: "p" }),
"w-full rounded border-[6px] py-2 px-3 md:py-3 md:px-4 leading-tight border-fg placeholder-fg/50 bg-fg/20",
"focus:outline-none",
]);
interface ImageInputProps {
label: string;
placeholderImage?: string;
onChange?: (file: File) => void;
currentImage?: string;
aspectRatio?: number;
}
export const ImageInput: React.FC<ImageInputProps> = ({
label,
placeholderImage,
onChange,
currentImage,
aspectRatio,
}) => {
const [preview, setPreview] = useState<string | undefined>(currentImage);
const fileInputRef = useRef<HTMLInputElement | null>(null);
useEffect(() => {
if (currentImage) {
setPreview(currentImage);
} else {
setPreview(undefined);
}
}, [currentImage]);
const handleFileInputChange = (e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (file) {
setPreview(URL.createObjectURL(file));
if (onChange) onChange(file);
}
};
const handleImageClick = () => {
fileInputRef.current?.click();
};
return (
<div className="flex flex-col">
<label
className={typo({ size: "base", className: "mb-1 block text-fg" })}
>
{label}
</label>
<div className="relative h-32 w-full overflow-clip rounded border-[6px] border-fg bg-fg/20">
{preview ? (
<div className={"h-full w-full"}>
<img src={preview} alt="Selected image" className="object-cover" />
</div>
) : (
<div
className={"flex h-full w-full items-center justify-center"}
onClick={handleImageClick}
>
{placeholderImage ? (
<Image
src={placeholderImage}
alt="Placeholder image"
className="object-cover"
width={300}
height={225}
/>
) : (
<span className={typo({ tag: "p", className: "text-fg/50" })}>
Click to add image
</span>
)}
</div>
)}
<input
type="file"
accept="image/*"
className="absolute inset-0 h-full w-full cursor-pointer opacity-0"
onChange={handleFileInputChange}
ref={fileInputRef}
/>
</div>
</div>
);
};

View File

@@ -14,6 +14,11 @@ import {
import type { IconType } from "react-icons/lib";
import { Button } from "@components/Button";
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import * as Dialog from "@radix-ui/react-dialog";
import { cx } from "class-variance-authority";
import { TextInput } from "@components/TextInput";
import { Divider } from "@components/Divider";
import { ImageInput } from "@components/ImageInput";
export const MainLayout: React.FC<Children> = ({ children }) => {
return (
@@ -72,7 +77,7 @@ export const SidePanel: React.FC = () => {
</Link>
))}
</nav>
<Button variant={{ size: "small" }}>New Proposal</Button>
<NewProposalButton />
</div>
<MoreMenu />
</header>
@@ -80,6 +85,60 @@ export const SidePanel: React.FC = () => {
);
};
const NewProposalButton: React.FC = () => {
const container =
typeof window !== "undefined" ? document.getElementById("root") : null;
const FullDivider = () => (
<div className="my-4 -mx-10">
<Divider />
</div>
);
return (
<Dialog.Root>
<Dialog.Trigger asChild>
<Button variant={{ size: "small" }}>New Proposal</Button>
</Dialog.Trigger>
<Dialog.Portal container={container}>
<Dialog.Overlay className="fixed inset-0 bg-black/40 data-[state=open]:animate-overlayShow" />
<Dialog.Content
className={cx(
"fixed top-[50%] left-[50%] max-h-[85vh] w-[90vw] max-w-[750px] translate-x-[-50%] translate-y-[-50%]",
"rounded-3xl bg-bg p-10",
"focus:outline-none data-[state=open]:animate-contentShow"
)}
>
<Dialog.Title>
<h1 className={typo({ tag: "h5", className: "text-primary" })}>
Create new proposal
</h1>
</Dialog.Title>
<Dialog.Description>
Let others know a little about your project idea.
</Dialog.Description>
<FullDivider />
<div className="mb-8 flex flex-col gap-y-4">
<TextInput label="Title" />
<TextInput
label="Description"
placeholder="Describe your project"
/>
<ImageInput label="Image" />
</div>
<Dialog.Close asChild>
<div className="flex flex-row justify-end">
<Button variant={{ size: "small" }}>Create</Button>
</div>
</Dialog.Close>
</Dialog.Content>
</Dialog.Portal>
</Dialog.Root>
);
};
const MoreMenu: React.FC = () => {
const container =
typeof window !== "undefined" ? document.getElementById("root") : null;