From ca1a2bf1cad04c62e9cf88eeccc604d9b901865a Mon Sep 17 00:00:00 2001 From: Yura Dupyn <2153100+omedusyo@users.noreply.github.com> Date: Fri, 15 May 2026 00:36:08 +0200 Subject: [PATCH] Ditch old css. Use Material UI. Add Modal. Make it work on mobile. --- src/App.tsx | 147 ++++++++++++++++++++++++++++++++++++++++++++------ src/index.css | 41 -------------- src/main.tsx | 2 +- src/style.css | 3 ++ 4 files changed, 134 insertions(+), 59 deletions(-) delete mode 100644 src/index.css create mode 100644 src/style.css diff --git a/src/App.tsx b/src/App.tsx index 2722b3d..5904588 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,14 @@ import { z } from "zod" import { useReducer, useRef, useEffect, createContext, useContext } from "react" +import { + CssBaseline, + Box, + Button, + Typography, + Skeleton, + Dialog, + DialogContent, +} from "@mui/material" // TODO: Use Material UI later. // TODO: Improve error-handling. Introduce some proper server response. @@ -26,8 +35,8 @@ type Dimension = { height: number } const Dimension = { - medium: { width: 200, height: 200 } as Dimension, - big: { width: 300, height: 500 } as Dimension, + medium: { width: 180, height: 180 } as Dimension, + big: { width: 720, height: 720 } as Dimension, } // === Page === @@ -62,6 +71,9 @@ const Page = { key(page: Page): PageKey { return `${page.page}:${page.limit}` }, + isFirst(page: Page): boolean { + return page.page === FIRST_PAGE + }, } // === api === @@ -230,7 +242,7 @@ function useDispatch() { function RemoteImages({ images }: { images: Remote }) { switch (images.tag) { case "loading": - return
Loading...
+ return case "error": return
Error: TODO
case "loaded": @@ -238,21 +250,82 @@ function RemoteImages({ images }: { images: Remote }) { } } +function imageGridStyle(dimension: Dimension) { + return { + display: "grid", + gridTemplateColumns: { + xs: `repeat(2, ${dimension.width}px)`, + md: `repeat(5, ${dimension.width}px)`, + }, + gridAutoRows: `${dimension.height}px`, + gap: 2, + } +} + +// 2x5 on mobile, 5x2 on desktop (assuming 10 images per page) +function ImagesSkeleton() { + const images = Array.from({ length: 10 }) + return ( + + {images.map((_, index) => ( + + ))} + + ) +} + function Images({ images }: { images: ImageId[] }) { const dispatch = useDispatch() - // TODO: Is there some basic `Col/Row` component? return ( -
+ {images.map((imageId) => ( - dispatch({ tag: "imageClicked", imageId })} + sx={{ + width: Dimension.medium.width, + height: Dimension.medium.height, + objectFit: "cover", + cursor: "pointer", + }} + key={imageId} alt="" /> ))} -
+ + ) +} + +function ImageModal({ selectedImage }: { selectedImage: ImageId | undefined }) { + const dispatch = useDispatch() + return ( + dispatch({ tag: "modalCloseButtonClicked" })} + maxWidth={false} + > + + {selectedImage !== undefined && ( + + )} + + ) } @@ -260,13 +333,53 @@ export default function App() { const [state, dispatch] = useApp() return ( - -
-

Picturarium

- - - -
-
+ <> + + + + Picturarium + + + + + + + {state.page.page} + + + + + + + + ) } diff --git a/src/index.css b/src/index.css deleted file mode 100644 index bd1da64..0000000 --- a/src/index.css +++ /dev/null @@ -1,41 +0,0 @@ -/* === Reset === */ -*, -*::before, -*::after { - box-sizing: border-box; -} - -html { - line-height: 1.45; -} - -body { - margin: 0; -} - -h1, -h2, -h3, -h4, -h5, -h6 { - margin: 0; -} - -p { - margin: 0; -} - -ul { - list-style: none; - padding: 0; - margin: 0; -} - -button { - border: none; - padding: 0; - cursor: pointer; -} - -/* === main === */ diff --git a/src/main.tsx b/src/main.tsx index 57d77e4..5a7820c 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,7 +1,7 @@ import { StrictMode } from "react" import { createRoot } from "react-dom/client" import App from "./App" -import "./index.css" +import "./style.css" const rootElement = document.getElementById("root") diff --git a/src/style.css b/src/style.css new file mode 100644 index 0000000..5467feb --- /dev/null +++ b/src/style.css @@ -0,0 +1,3 @@ +:root { + --base-hue: 260; +}