Skip to content

Commit

Permalink
♻️ refactor: add print page
Browse files Browse the repository at this point in the history
  • Loading branch information
andrehadianto committed Sep 26, 2024
1 parent 7efa0fb commit 2770270
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 12 deletions.
48 changes: 36 additions & 12 deletions pages/sticker-map.tsx → pages/sticker-map/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/* eslint-disable @next/next/no-img-element */
import { type FilePondFile } from "filepond";
import { useRouter } from "next/router";
import { PropsWithChildren, useState } from "react";
import { FilePond } from "react-filepond";

import { Button } from "@/common/components/Button";
import { Icon } from "@/common/components/CustomIcon";
import { Footer } from "@/common/components/Footer";
import { Input } from "@/common/components/Input";
Expand All @@ -11,16 +13,29 @@ import { cn } from "@/common/functions";
import "filepond/dist/filepond.min.css";

export const StickerMap = () => {
const router = useRouter();
const [files, setFiles] = useState<Blob[]>([]);

const [imageSize, setImageSize] = useState(46);
const [imageSize, setImageSize] = useState(51);
const [blackBorderSize, setBlackBorderSize] = useState(1);
const [whiteBorderSize, setWhiteBorderSize] = useState(2);

const handleFilePondChange = (items: FilePondFile[]) => {
setFiles(items.map((item) => item.file));
};

const handleNavigateToPrint = () => {
router.push({
pathname: "/sticker-map/print",
query: {
imageSize,
blackBorderSize,
whiteBorderSize,
files: files.map((file) => URL.createObjectURL(file)),
},
});
};

return (
<main className="mx-auto flex max-w-screen-xl flex-col items-center gap-10 px-2 pb-24 pt-10 sm:pb-40">
<div className="mx-auto flex flex-col gap-10 border-b border-b-border-base pb-10 md:flex-row">
Expand All @@ -38,6 +53,7 @@ export const StickerMap = () => {
}}
id="image-size"
label="Image Size"
min={0}
placeholder="in mm"
rightContent={<span className="text-text-em-mid">mm</span>}
type="number"
Expand All @@ -51,6 +67,7 @@ export const StickerMap = () => {
}}
id="black-border-size"
label="Black Border Size"
min={0}
placeholder="in mm"
rightContent={<span className="text-text-em-mid">x2 mm</span>}
type="number"
Expand All @@ -64,6 +81,7 @@ export const StickerMap = () => {
}}
id="white-border-size"
label="White Border Size"
min={0}
placeholder="in mm"
rightContent={<span className="text-text-em-mid">x2 mm</span>}
type="number"
Expand All @@ -72,7 +90,7 @@ export const StickerMap = () => {
onChange={(e) => setWhiteBorderSize(e.target.valueAsNumber)}
/>
<div className="flex items-end justify-between pl-1 pt-2">
<span className="font-mono font-medium text-text-em-high">{`LENGTH ${imageSize + blackBorderSize * 2 + whiteBorderSize * 2}mm (${Math.round(((imageSize + blackBorderSize * 2 + whiteBorderSize * 2) / 25.4) * 100) / 100}inch)`}</span>
<span className="font-mono font-medium text-text-em-high">{`LENGTH ${imageSize}mm (${Math.round((imageSize / 25.4) * 100) / 100}inch)`}</span>
<span className="font-mono text-xs text-text-em-mid">
25.4mm/inch
</span>
Expand All @@ -82,19 +100,21 @@ export const StickerMap = () => {
<div className="flex flex-wrap items-center justify-center gap-10 rounded-md bg-white/10 p-10">
{files.length > 0 ? (
files.map((file, index) => (
<div key={index}>
<div
key={index}
className="border-white"
style={{
boxSizing: "border-box",
height: `${imageSize}mm`,
width: `${imageSize}mm`,
borderWidth: `${whiteBorderSize}mm`,
}}
>
<img
alt={`sticker-${index}`}
className={cn(
"border-black object-cover outline outline-white",
)}
className={cn("box-border border-black object-cover")}
src={URL.createObjectURL(file)}
style={{
borderWidth: `${blackBorderSize}mm`,
outlineWidth: `${whiteBorderSize}mm`,
height: `${imageSize}mm`,
width: `${imageSize}mm`,
}}
style={{ borderWidth: `${blackBorderSize}mm` }}
/>
</div>
))
Expand All @@ -110,6 +130,10 @@ export const StickerMap = () => {
</div>
)}
</div>
<div className="flex-grow" />
<div>
<Button onClick={handleNavigateToPrint}>Go to print page</Button>
</div>
</main>
);
};
Expand Down
105 changes: 105 additions & 0 deletions pages/sticker-map/print.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/* eslint-disable @next/next/no-img-element */
import { useRouter } from "next/router";
import { PropsWithChildren, useState } from "react";

import { Button } from "@/common/components/Button";
import { cn } from "@/common/functions";

export const PrintPage = () => {
const [extraImage, setExtraImage] = useState<string[]>([]);

const { query } = useRouter();
const { imageSize, blackBorderSize, whiteBorderSize, files } = query as {
imageSize: string;
blackBorderSize: string;
whiteBorderSize: string;
files: string[];
};

if (!files || !imageSize || !blackBorderSize || !whiteBorderSize) {
return (
<span className="font-mono text-sm text-text-em-high">
missing something. go back!
</span>
);
}

const parentWidth = 210;
const parentHeight = 297;
const childSize = imageSize || "1";

const columns = Math.floor(parentWidth / Number(childSize));
const rows = Math.floor(parentHeight / Number(childSize));

const imageCount = columns * rows;

const countPerImage = imageCount / files.length;

const renderImage = (file: string) => (
<div className="h-fit w-fit border border-black">
<div
className="border-white"
style={{
boxSizing: "border-box",
height: `${imageSize}mm`,
width: `${imageSize}mm`,
borderWidth: `${whiteBorderSize}mm`,
}}
>
<img
alt="sticker"
className={cn("box-border border-black object-cover")}
src={file}
style={{ borderWidth: `${blackBorderSize}mm` }}
/>
</div>
</div>
);

return (
<main className="flex flex-col gap-4">
<section className="h-[297mm] w-[210mm] bg-white">
<div
className="relative grid h-full w-full place-content-start gap-0.5"
style={{
gridTemplateColumns: `repeat(auto-fit, minmax(${childSize}mm, 1fr))`,
gridAutoRows: `${childSize}mm`,
}}
>
{files.length > 0 &&
files.map((file) =>
Array.from({ length: countPerImage }).map((_, index) =>
renderImage(file),
),
)}
{extraImage.length > 0 && extraImage.map((file) => renderImage(file))}
</div>
</section>
<div className="flex w-[210mm] flex-col gap-2">
<div className="flex gap-2">
<Button
fullWidth
onClick={() => setExtraImage([...extraImage, files[0]])}
>
Add Extra Image
</Button>
<Button
fullWidth
onClick={() => setExtraImage(extraImage.slice(0, -1))}
>
Delete Last Extra Image
</Button>
</div>
<span className="font-mono text-sm text-text-em-high">
The white space above is the A4 paper.
</span>
</div>
</main>
);
};

PrintPage.layout = ({ children }: PropsWithChildren) => (
<div className="relative">{children}</div>
);

export default PrintPage;

0 comments on commit 2770270

Please sign in to comment.