Added template for uploading csv modal

This commit is contained in:
Khalim Conn-Kowlessar 2023-07-12 18:33:53 +01:00
parent c1f4f3ca60
commit 0e9509ae42
4 changed files with 174 additions and 4 deletions

View file

@ -41,15 +41,19 @@ ListItem.displayName = "ListItem";
export default function AddNewDropDown({
portfolioId,
isUploadCsvOpen,
setIsUploadCsvOpen,
}: {
portfolioId: number;
isUploadCsvOpen: boolean;
setIsUploadCsvOpen: React.Dispatch<React.SetStateAction<boolean>>;
}) {
function handleCickAddUnit() {
console.log("Add unit");
}
function handleClickUploadCSV() {
console.log("Upload csv");
setIsUploadCsvOpen(!isUploadCsvOpen);
}
return (

View file

@ -8,6 +8,8 @@ import {
} from "@/app/shadcn_components/ui/navigation-menu";
import AddNewDropDown from "./AddNew";
import { cva } from "class-variance-authority";
import UploadCsvModal from "./UploadCsvModal";
import { useState } from "react";
interface ToolbarProps {
portfolioId: number;
@ -21,6 +23,9 @@ export function Toolbar({ portfolioId }: ToolbarProps) {
function handleClickSettings() {
console.log("Settings were clicked, implement me");
}
const [modalIsOpen, setModalIsOpen] = useState(false);
return (
<NavigationMenu>
<NavigationMenuList>
@ -31,8 +36,13 @@ export function Toolbar({ portfolioId }: ToolbarProps) {
<Cog6ToothIcon className="h-4 w-4 mr-2" />
Settings
</NavigationMenuItem>
<AddNewDropDown portfolioId={portfolioId} />
<AddNewDropDown
portfolioId={portfolioId}
isUploadCsvOpen={modalIsOpen}
setIsUploadCsvOpen={setModalIsOpen}
/>
</NavigationMenuList>
<UploadCsvModal isOpen={modalIsOpen} setIsOpen={setModalIsOpen} />
</NavigationMenu>
);
}

View file

@ -0,0 +1,156 @@
import { Dialog, Transition } from "@headlessui/react";
import { Fragment, useState } from "react";
import ModalSubmit from "@/app/components/home/ModalSubmit";
import { PortfolioGoal } from "@/app/db/schema/portfolio";
// Mock Icon component
interface IconProps {
name: string;
selected: boolean;
onSelect: (name: string) => void;
className?: string;
}
const hiddenInputArrows =
"[-moz-appearance:_textfield] [&::-webkit-inner-spin-button]:m-0 [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-outer-spin-button]:appearance-none";
export default function UploadCsvModal({
isOpen = false,
setIsOpen,
}: {
isOpen?: boolean;
setIsOpen: (isOpen: boolean) => void;
}) {
const [portfolioName, setPortfolioName] = useState("");
const [budget, setBudget] = useState<undefined | number>(undefined);
const [selectedOutcome, setSelectedOutcome] =
useState<string>("Nothing Specific");
const [buttonDisabled, setButtonDisabled] = useState(true);
function closeModal() {
setIsOpen(false);
}
function handlePortfolioNameChange(e: React.ChangeEvent<HTMLInputElement>) {
if (e.target.value.length > 0) {
setButtonDisabled(false);
} else {
setButtonDisabled(true);
}
setPortfolioName(e.target.value);
}
return (
<>
<Transition appear show={isOpen} as={Fragment}>
<Dialog as="div" className="relative z-10" onClose={closeModal}>
<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"
>
<div className="fixed inset-0 bg-black bg-opacity-25" />
</Transition.Child>
<div className="fixed inset-0 overflow-y-auto">
<div className="flex min-h-full items-center justify-center p-4 text-center">
<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"
>
<Dialog.Panel className="w-full max-w-screen-md transform overflow-hidden rounded-2xl bg-white p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-brandblue mb-3"
>
Upload a CSV of properties
</Dialog.Title>
<form className="space-y-4">
<div className="flex flex-col">
<label
htmlFor="portfolio-name"
className="text-sm font-semibold text-gray-600 mb-1 relative"
>
Portfolio Name:
<span className="text-red-500">*</span>
</label>
<input
id="portfolio-name"
type="text"
placeholder="My new portfolio"
required
value={portfolioName}
onChange={(e) => handlePortfolioNameChange(e)}
className="p-2 border border-gray-200 rounded-md focus:outline-none bg-gray-100"
/>
</div>
<div className="flex flex-col">
<label
htmlFor="budget"
className="text-sm font-semibold text-gray-600 mb-1"
>
Budget (£){" "}
<span className="text-gray-400 text-xs">optional</span>{" "}
:
</label>
<div className="flex items-center border border-gray-200 rounded-md text-gray-900 bg-brandblue">
<span className="px-2 text-sm text-white">£</span>
<input
id="budget"
type="number"
placeholder="1000"
value={budget}
onChange={(e) => setBudget(Number(e.target.value))}
onKeyDown={(e) =>
(e.key === "e" || e.key === "E") &&
e.preventDefault()
}
className={[
"flex-1 p-2 bg-gray-100 focus:outline-none",
hiddenInputArrows,
].join(" ")}
/>
</div>
</div>
<div className="flex flex-col space-y-2">
<span className="text-sm font-semibold text-gray-600">
Select Outcome:
</span>
<div className="flex space-x-2">"Fill me in"</div>
</div>
</form>
<div className="mt-4 flex justify-end gap-2">
<button
type="button"
className="inline-flex justify-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-900 hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
onClick={closeModal}
>
Cancel
</button>
<ModalSubmit
buttonDisabled={buttonDisabled}
portfolioName={portfolioName}
budget={budget}
objective={selectedOutcome}
/>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition>
</>
);
}

View file

@ -27,7 +27,7 @@ function EmptyPropertyState() {
<div className="flex justify-center h-1/2">
<div className="bg-white rounded-lg w-full">
<p className="text-center text-gray-400 pt-6">
Click on Add new to start adding properties to your Portfolio
Hover over "Add new" to start adding properties to your Portfolio
<HomeIcon className="h-20 w-20 mx-auto mt-4 text-gray-200" />
</p>
</div>
@ -156,7 +156,7 @@ function SummaryBox({
const energySavingsFormatted = formatKwh(energySavings);
return (
<div className="p-6 bg-white rounded-lg shadow ">
<div className="p-6 bg-white rounded-lg shadow leading-relaxed">
<h2 className="text-2xl font-bold mb-4 text-gray-700 text-center">
Portfolio Summary
</h2>