Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Caregiver Baby Book Main Pages & Update Admin Baby Book Page #144

Merged
merged 12 commits into from
Oct 3, 2024
90 changes: 78 additions & 12 deletions web/components/BabyBook/PictureArray.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import ArrowUpIcon from "@components/Icons/LeftChevronIcon copy";
import { UseMapWrapper } from "@lib/hooks/useMap";
import { monthIndexToString } from "@lib/utils/date";
import Image from "next/image";
import { useRouter } from "next/router";
import { BabyBookYear, BabyImage } from "pages/admin/book/[babyId]";
import React, { useEffect, useRef, useState } from "react";

const PictureArray = ({ babyBook, select }: Props) => {
const selectedForDownloadKey = (i: number, j: number, k: number) =>
`${i}${j}${k}`;

const PictureArray = ({ babyBook, select, selectedForDownload }: Props) => {
const router = useRouter();
const wrapper = useRef<HTMLDivElement>(null);
const [showToTop, setShowToTop] = useState(false);
Expand All @@ -14,6 +18,7 @@ const PictureArray = ({ babyBook, select }: Props) => {
year.months.map((_) => React.createRef<HTMLDivElement>())
)
);

useEffect(() => {
const onHashChange = (
url = window.location.pathname + window.location.hash
Expand Down Expand Up @@ -53,6 +58,7 @@ const PictureArray = ({ babyBook, select }: Props) => {
if (scrollTop > 0) setShowToTop(true);
else setShowToTop(false);
};

const toTop = () => {
if (!wrapper.current) return;
wrapper.current.scrollTop = 0;
Expand All @@ -69,19 +75,63 @@ const PictureArray = ({ babyBook, select }: Props) => {
<div key={year.year} className="mb-10">
<h1 className="text-3xl font-semibold mb-4">{year.year}</h1>
{year.months.map((month, j) => {
const monthSelected = month.images.every((_, k) =>
selectedForDownload.has(selectedForDownloadKey(i, j, k))
);

return (
<div key={month.month} ref={refs.current[i][j]}>
<h2 className="font-semibold mb-2">
{monthIndexToString(month.month)} {year.year}
<h2
className="group flex items-center font-semibold mb-2 cursor-pointer"
onClick={() => {
selectedForDownload.batch((map) => {
month.images.forEach((img, k) => {
const key = selectedForDownloadKey(i, j, k);
if (monthSelected) {
map.delete(key);
} else {
map.set(key, img);
}
});
});
}}
>
<input
type="checkbox"
checked={monthSelected}
className={`hidden mr-2 w-6 h-6 group-hover:block ${monthSelected ? "!block" : ""}`}
/>
<span>
{monthIndexToString(month.month)} {year.year}
</span>
</h2>
<div className="flex flex-wrap">
{month.images.map((image, k) => (
<BabyBookImage
image={image}
onClick={() => select(i, j, k)}
key={k}
/>
))}
{month.images.map((image, k) => {
const imageSelected = selectedForDownload.has(
selectedForDownloadKey(i, j, k)
);

return (
<BabyBookImage
image={image}
onClick={() => select(i, j, k)}
selected={imageSelected}
onCheckboxClick={() => {
if (imageSelected) {
selectedForDownload.delete(
selectedForDownloadKey(i, j, k)
);
} else {
selectedForDownload.set(
selectedForDownloadKey(i, j, k),
image
);
}
}}
key={k}
/>
);
})}
</div>
</div>
);
Expand All @@ -104,28 +154,44 @@ const PictureArray = ({ babyBook, select }: Props) => {
const BabyBookImage = ({
image,
onClick,
onCheckboxClick,
selected,
}: {
image: BabyImage;
onClick: () => void;
selected: boolean;
onCheckboxClick: () => void;
}) => {
const borderClasses = `border hover:border-mbb-pink ${selected ? "!border-mbb-pink" : ""}`;

return (
<div
className="w-[200px] h-[300px] overflow-hidden relative shadow-lg rounded mx-3 my-3 cursor-pointer"
className={`group w-[200px] h-[300px] overflow-hidden relative shadow-lg rounded mx-3 my-3 cursor-pointer ${borderClasses}`}
onClick={onClick}
>
<Image src={image.imageUrl} layout={"fill"} objectFit={"cover"} />
{image.caption && (
<p className="absolute bottom-0 line-clamp-3 text-ellipsis bg-white w-full min-h-[4rem] p-2">
<p className="absolute bottom-0 left-0 right-0 line-clamp-3 text-ellipsis bg-white min-h-[4rem] p-3">
{image.caption}
</p>
)}
<input
type="checkbox"
checked={selected}
className={`absolute hidden top-2 left-2 w-6 h-6 group-hover:block ${selected ? "!block" : ""}`}
onClick={(e) => {
e.stopPropagation();
onCheckboxClick();
}}
/>
</div>
);
};

interface Props {
babyBook: BabyBookYear[];
select: (arg0: number, arg1: number, arg2: number) => void;
selectedForDownload: UseMapWrapper<string, BabyImage>;
}

export default PictureArray;
16 changes: 8 additions & 8 deletions web/components/BabyBook/PictureModal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Button from "@components/atoms/Button";
import DownloadIcon from "@components/Icons/DownloadIcon";
import LeftChevronIcon from "@components/Icons/LeftChevronIcon";
import RightChevronIcon from "@components/Icons/RightChevronIcon";
Expand Down Expand Up @@ -37,13 +38,13 @@ const PictureModal = ({
).toDate();
return (
<div className="absolute flex flex-col align-center w-full h-full bg-white">
<div className="flex mt-8 ml-8 text-highlight font-semibold">
<div className="flex mt-8 ml-8 text-mbb-pink font-semibold">
<div
className="flex cursor-pointer items-center"
onClick={() => deselect()}
>
<LeftChevronIcon />
<p className="ml-2">Download</p>
<p className="ml-2">Back to album</p>
</div>
</div>
<div className="flex w-full justify-between flex-grow p-4">
Expand Down Expand Up @@ -90,13 +91,12 @@ const PictureModal = ({
<p className="my-4">
{image.caption === "" ? "No Caption" : image.caption}
</p>
<button
<Button
onClick={downloadImage}
className="rounded px-4 py-2 border border-highlight flex items-center text-highlight"
>
<DownloadIcon />
<p className="ml-2">Download</p>
</button>
text="Download"
icon={<DownloadIcon />}
width="auto"
/>
</div>
</div>
</div>
Expand Down
12 changes: 6 additions & 6 deletions web/components/BabyBook/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const SideBar = ({ babyBook }: Props) => {

return (
<div className="overflow-auto shrink-0">
<div className="w-[164px] flex flex-col items-end pt-8 text-dark-400 overflow-hidden">
<div className="w-[164px] flex flex-col items-stretch pt-8 text-dark-400 overflow-hidden">
{babyBook.map((year) => (
<YearSection
key={year.year}
Expand Down Expand Up @@ -104,27 +104,27 @@ const YearSection = ({
};

return (
<div className="w-full flex flex-col items-end">
<div className="w-full flex flex-col items-stretch">
<p
onClick={() => setIsExpanded(!isExpanded)}
className={`font-semibold text-lg border-r px-4 cursor-pointer ${
className={`font-semibold text-lg border-r px-4 cursor-pointer text-end ${
year === currentYear ? "text-black" : ""
}`}
>
{year}
</p>
<div
className={`flex flex-col text-right w-full ${
className={`flex flex-col items-stretch text-right w-full ${
isExpanded ? "" : "hidden"
}`}
>
{months.map((month) => (
<p
key={month.month}
onClick={() => pushHash(`${year}.${month.month}`)}
className={`p-1 px-8 w-full border-r cursor-pointer ${
className={`p-1 px-8 border-r cursor-pointer ${
month.month === currentMonth
? "bg-alt border-r-[3px] border-highlight text-black"
? "bg-mbb-pink/10 border-r-[3px] border-mbb-pink text-black"
: ""
}`}
>
Expand Down
84 changes: 43 additions & 41 deletions web/components/BabyBook/Topbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,22 @@ import DownloadIcon from "@components/Icons/DownloadIcon";
import ImageIcon from "@components/Icons/ImageIcon";
import LinkIcon from "@components/Icons/LinkIcon";
import PersonIcon from "@components/Icons/PersonIcon";
import { GetServerSideProps } from "next";
import Image from "next/image";
import { stringify } from "querystring";
import { useState } from "react";
import admin_portal_gradient from "../../public/admin_portal_gradient.png";
import left_heart from "../../public/left_heart.png";
import right_heart from "../../public/right_heart.png";
import Button from "@components/atoms/Button";

const TopBar = ({ number, motherName, name, content, iv }: Props) => {
const TopBar = ({
number,
motherName,
name,
content,
iv,
isPictureSelected,
}: Props) => {
const [copiedConfirmation, setCopiedConfirmation] = useState(false);

const downloadAlbum = async () => {
const downloadAlbum = () => {
const a = document.createElement("a");
a.href = `/api/download-album?content=${content}&iv=${iv}`;
console.log(a.href);
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
Expand All @@ -35,22 +36,24 @@ const TopBar = ({ number, motherName, name, content, iv }: Props) => {
return (
<div className="flex justify-between w-full shadow-lg">
<div className="flex items-center">
<div className="w-[164px] h-[81px] overflow-hidden">
<div className="relative right-12">
<Image
className="relative"
layout="fixed"
src={admin_portal_gradient}
<div className="flex items-center justify-center min-w-[164px] h-[81px] overflow-hidden bg-admin-baby-book-background">
<svg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the logo SVG from /public/MBBLogo.svg or create a new SVG in public or file in Icons if it's too different to keep the code clear and the logo consistent!

xmlns="http://www.w3.org/2000/svg"
width="41"
height="40"
viewBox="0 0 41 40"
fill="none"
>
<path
d="M20.6927 6.12111L15.3754 1H5.92491M5.92491 1L1 6.24913V18.6678M5.92491 1L12.4471 13.1626M1 18.6678L20.0341 38M1 18.6678L12.4471 13.1626M20.0341 38L40 17.8997V16.1073M20.0341 38L16.2406 25.5813M20.0341 38L31.6143 19.451M12.4471 13.1626L16.2406 25.5813M12.4471 13.1626L25.7577 1.79569M12.4471 13.1626L28.4303 14.5709M16.2406 25.5813L29.6177 20.2472M40 16.1073V6.63322L38.2696 4.96886M40 16.1073L31.6143 19.451M31.6143 19.451L29.6177 20.2472M29.6177 20.2472L28.8856 16.7474M25.7577 1.79569L26.6894 1H34.1433L38.2696 4.96886M25.7577 1.79569L28.4303 14.5709M28.8856 16.7474L38.2696 4.96886M28.8856 16.7474L28.4303 14.5709"
stroke="white"
strokeWidth="1.8"
/>
</div>
</svg>
</div>
<span className="absolute top-[26px] left-[67px]">
<Image className="static px-10" src={left_heart} />
</span>
<span className="absolute top-[26px] left-[83px]">
<Image className="static px-10" src={right_heart} />
</span>
<p className="font-bold text-2xl text-center mx-4">{name}'s album</p>
<p className="font-bold text-2xl text-center mx-4">
{name}&apos;s album
</p>
<div className="flex items-center mx-3">
<ImageIcon />
<p className="text-dark-400 ml-1">{number} photos</p>
Expand All @@ -60,24 +63,22 @@ const TopBar = ({ number, motherName, name, content, iv }: Props) => {
<p className="text-dark-400 ml-1">Mother - {motherName}</p>
</div>
</div>
<div className="flex items-center font-semibold text-highlight">
<button
className="rounded px-4 py-2 border border-highlight mx-2 flex items-center cursor-pointer"
onClick={downloadAlbum}
>
<DownloadIcon />
<p className="ml-2">Download album</p>
</button>
<button
className="rounded px-4 py-2 border border-highlight mx-2 flex items-center cursor-pointer"
onClick={copyLink}
>
<LinkIcon />
<p className="ml-2">
{copiedConfirmation ? "Copied!" : "Copy album link"}
</p>
</button>
</div>
{!isPictureSelected && (
<div className="flex items-center gap-[18px] mr-6">
<Button
onClick={downloadAlbum}
text="Download album"
icon={<DownloadIcon />}
width="auto"
/>
<Button
onClick={copyLink}
text="Copy link"
icon={<LinkIcon />}
width="auto"
/>
</div>
)}
</div>
);
};
Expand All @@ -88,6 +89,7 @@ interface Props {
name: string;
content: string;
iv: string;
isPictureSelected: boolean;
}

export default TopBar;
3 changes: 1 addition & 2 deletions web/components/Icons/DownloadIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ const DownloadIcon = () => {
width="10"
height="14"
viewBox="0 0 10 14"
fill="none"
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M4.46967 9.7803C4.76256 10.0732 5.23744 10.0732 5.53033 9.7803L9.2803 6.03033C9.5732 5.73744 9.5732 5.26256 9.2803 4.96967C8.9874 4.67678 8.5126 4.67678 8.2197 4.96967L5.75 7.43934V0.75C5.75 0.33579 5.41421 0 5 0C4.58579 0 4.25 0.33579 4.25 0.75V7.43934L1.78033 4.96967C1.48744 4.67678 1.01256 4.67678 0.71967 4.96967C0.42678 5.26256 0.42678 5.73744 0.71967 6.03033L4.46967 9.7803ZM0.75 12.0001C0.33579 12.0001 0 12.3359 0 12.7501C0 13.1643 0.33579 13.5001 0.75 13.5001H9.25C9.6642 13.5001 10 13.1643 10 12.7501C10 12.3359 9.6642 12.0001 9.25 12.0001H0.75Z"
fill="#304CD1"
/>
</svg>
);
Expand Down
3 changes: 1 addition & 2 deletions web/components/Icons/LinkIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@ const LinkIcon = () => {
width="14"
height="14"
viewBox="0 0 14 14"
fill="none"
className="fill-current"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M6.77518 2.27518C6.6427 2.41735 6.57057 2.6054 6.574 2.7997C6.57743 2.994 6.65614 3.17938 6.79355 3.3168C6.93097 3.45421 7.11635 3.53292 7.31065 3.53635C7.50495 3.53978 7.693 3.46766 7.83518 3.33518L9.08518 2.08518C9.27098 1.89936 9.49158 1.75195 9.73438 1.65139C9.97718 1.55082 10.2374 1.49906 10.5002 1.49906C10.763 1.49906 11.0232 1.55082 11.266 1.65139C11.5088 1.75195 11.7294 1.89936 11.9152 2.08518C12.101 2.271 12.2484 2.4916 12.349 2.73438C12.4495 2.97717 12.5013 3.23739 12.5013 3.50018C12.5013 3.76297 12.4495 4.02318 12.349 4.26597C12.2484 4.50875 12.101 4.72935 11.9152 4.91518L9.41518 7.41518C9.22938 7.60113 9.00888 7.74865 8.76606 7.84929C8.52326 7.94994 8.26301 8.00175 8.00018 8.00175C7.73734 8.00175 7.47709 7.94994 7.23429 7.84929C6.9915 7.74865 6.77092 7.60113 6.58518 7.41518C6.443 7.2827 6.25495 7.21057 6.06065 7.214C5.86635 7.21743 5.68097 7.29614 5.54355 7.43355C5.40614 7.57097 5.32743 7.75635 5.324 7.95065C5.32057 8.14495 5.3927 8.333 5.52518 8.47518C5.85019 8.80022 6.23604 9.05808 6.6607 9.23398C7.08536 9.40988 7.54052 9.50038 8.00018 9.50038C8.45983 9.50038 8.91499 9.40988 9.33968 9.23398C9.76428 9.05808 10.1502 8.80022 10.4752 8.47518L12.9752 5.97518C13.6316 5.31876 14.0004 4.42848 14.0004 3.50018C14.0004 2.57187 13.6316 1.68159 12.9752 1.02518C12.3188 0.368763 11.4285 0 10.5002 0C9.57188 0 8.68159 0.368763 8.02517 1.02518L6.77518 2.27518ZM2.08518 11.9152C1.89922 11.7294 1.7517 11.5089 1.65106 11.2661C1.55041 11.0233 1.4986 10.763 1.4986 10.5002C1.4986 10.2374 1.55041 9.97708 1.65106 9.73428C1.7517 9.49148 1.89922 9.27088 2.08518 9.08518L4.58518 6.58518C4.77092 6.39922 4.9915 6.2517 5.23429 6.15106C5.47709 6.05041 5.73734 5.9986 6.00018 5.9986C6.26301 5.9986 6.52326 6.05041 6.76606 6.15106C7.00885 6.2517 7.22943 6.39922 7.41518 6.58518C7.55735 6.71766 7.7454 6.78978 7.9397 6.78635C8.134 6.78292 8.31938 6.70421 8.4568 6.5668C8.59421 6.42938 8.67292 6.244 8.67635 6.0497C8.67978 5.8554 8.60766 5.66735 8.47518 5.52518C8.15017 5.20013 7.76431 4.94229 7.33965 4.76638C6.91499 4.59047 6.45983 4.49992 6.00018 4.49992C5.54052 4.49992 5.08536 4.59047 4.6607 4.76638C4.23604 4.94229 3.85019 5.20013 3.52518 5.52518L1.02518 8.02517C0.368763 8.68159 0 9.57188 0 10.5002C0 11.4285 0.368763 12.3188 1.02518 12.9752C1.68159 13.6316 2.57187 14.0004 3.50018 14.0004C4.42848 14.0004 5.31876 13.6316 5.97518 12.9752L7.22518 11.7252C7.35766 11.583 7.42978 11.395 7.42635 11.2007C7.42292 11.0064 7.34421 10.821 7.2068 10.6836C7.06938 10.5462 6.884 10.4674 6.6897 10.464C6.4954 10.4606 6.30735 10.5327 6.16518 10.6652L4.91518 11.9152C4.72943 12.1011 4.50885 12.2487 4.26606 12.3493C4.02326 12.45 3.76301 12.5018 3.50018 12.5018C3.23734 12.5018 2.97709 12.45 2.73429 12.3493C2.4915 12.2487 2.27092 12.1011 2.08518 11.9152Z"
fill="#304CD1"
/>
</svg>
);
Expand Down
Loading