- )
+ );
}
diff --git a/src/components/CombinedFeaturePanel/components/FeatureGallery.tsx b/src/components/CombinedFeaturePanel/components/FeatureGallery.tsx
index d23e1d11a..56fa04173 100644
--- a/src/components/CombinedFeaturePanel/components/FeatureGallery.tsx
+++ b/src/components/CombinedFeaturePanel/components/FeatureGallery.tsx
@@ -1,35 +1,9 @@
-import { CameraIcon } from "@radix-ui/react-icons";
-import {
- AspectRatio,
- Box,
- Button,
- Callout,
- Card,
- Dialog,
- Flex,
- Grid,
- Inset,
- VisuallyHidden,
-} from "@radix-ui/themes";
-import { useRouter } from "next/router";
-import {
- type FC,
- createContext,
- useCallback,
- useContext,
- useEffect,
- useMemo,
- useState,
-} from "react";
-/* eslint-disable jsx-a11y/alt-text */
-/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
-/* eslint-disable @next/next/no-img-element */
+import { type FC, useMemo } from "react";
import useSWR from "swr";
import useAccessibilityCloudAPI from "~/lib/fetchers/ac/useAccessibilityCloudAPI";
import type { AccessibilityCloudImage } from "~/lib/model/ac/Feature";
import type { AnyFeature } from "~/lib/model/geo/AnyFeature";
import { Gallery } from "./Gallery/Gallery";
-import { GalleryAddImageButton } from "./Gallery/GalleryAddImageButton";
import { makeImageIds, makeImageLocation } from "./Gallery/util";
const fetcher = (urls: string[]) => {
@@ -51,8 +25,8 @@ interface ImageResponse {
export const FeatureGallery: FC<{
feature: AnyFeature;
- focusImage?: string;
-}> = ({ feature, focusImage }) => {
+ activeImageId?: string;
+}> = ({ feature, activeImageId }) => {
const ids = makeImageIds(feature);
const { baseUrl, appToken } = useAccessibilityCloudAPI({ cached: true });
const { data } = useSWR(
@@ -65,8 +39,7 @@ export const FeatureGallery: FC<{
return (
<>
-
-
+
>
);
};
diff --git a/src/components/CombinedFeaturePanel/components/FeatureImageUpload.tsx b/src/components/CombinedFeaturePanel/components/FeatureImageUpload.tsx
new file mode 100644
index 000000000..6ae1e8c07
--- /dev/null
+++ b/src/components/CombinedFeaturePanel/components/FeatureImageUpload.tsx
@@ -0,0 +1,68 @@
+import { CameraIcon } from "@radix-ui/react-icons";
+import { Button, Dialog, Flex } from "@radix-ui/themes";
+import React, {
+ type FC,
+ type MouseEventHandler,
+ useContext,
+ useRef,
+ useState,
+} from "react";
+import { t } from "ttag";
+import { AppStateLink } from "~/components/App/AppStateLink";
+import { FeaturePanelContext } from "~/components/CombinedFeaturePanel/FeaturePanelContext";
+import { ImageUploadCallToAction } from "~/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCallToAction";
+import { ImageUploadCriteriaList } from "~/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCriteriaList";
+import type { AnyFeature } from "~/lib/model/geo/AnyFeature";
+
+export const FeatureImageUpload: FC<{
+ feature: AnyFeature;
+ isUploadDialogOpen?: boolean;
+}> = ({ feature, isUploadDialogOpen }) => {
+ const { baseFeatureUrl } = useContext(FeaturePanelContext);
+
+ const [dialogOpen, setDialogOpen] = useState(isUploadDialogOpen);
+
+ const open = () => {
+ setDialogOpen(true);
+ };
+ const close = () => {
+ setDialogOpen(false);
+ };
+
+ const linkRef = useRef(null);
+ const handleOnClickAddImageButton: MouseEventHandler = (event) => {
+ event.preventDefault();
+ open();
+ };
+
+ return (
+
+
+
+
+
+
+
+
+ {t`Add new image`}
+ {t`Before uploading a new image, please make sure that the image meets the following criteria:`}
+ <>
+
+
+
+
+
+ >
+
+
+ );
+};
diff --git a/src/components/CombinedFeaturePanel/components/Gallery/GalleryAddImageButton.tsx b/src/components/CombinedFeaturePanel/components/Gallery/GalleryAddImageButton.tsx
deleted file mode 100644
index 1ec661360..000000000
--- a/src/components/CombinedFeaturePanel/components/Gallery/GalleryAddImageButton.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { CameraIcon } from "@radix-ui/react-icons";
-import { Button, Flex } from "@radix-ui/themes";
-import { type FC, useContext } from "react";
-import { t } from "ttag";
-import { AppStateLink } from "~/components/App/AppStateLink";
-import { FeaturePanelContext } from "~/components/CombinedFeaturePanel/FeaturePanelContext";
-import { GalleryCallToAction } from "./GalleryCallToAction";
-
-export const GalleryAddImageButton: FC = () => {
- const { baseFeatureUrl } = useContext(FeaturePanelContext);
-
- return (
-
-
-
-
- );
-};
diff --git a/src/components/CombinedFeaturePanel/components/Gallery/GalleryCallToAction.tsx b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCallToAction.tsx
similarity index 96%
rename from src/components/CombinedFeaturePanel/components/Gallery/GalleryCallToAction.tsx
rename to src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCallToAction.tsx
index e43918090..c9b63b288 100644
--- a/src/components/CombinedFeaturePanel/components/Gallery/GalleryCallToAction.tsx
+++ b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCallToAction.tsx
@@ -56,7 +56,7 @@ const CallToAction = styled.div`
}
`;
-export const GalleryCallToAction: FC = () => (
+export const ImageUploadCallToAction: FC = () => (
{t`Your good deed of the day!`}
diff --git a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCriteriaList.tsx b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCriteriaList.tsx
new file mode 100644
index 000000000..4a7c44a7a
--- /dev/null
+++ b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCriteriaList.tsx
@@ -0,0 +1,121 @@
+import { CheckIcon } from "@radix-ui/react-icons";
+import { Box, Card, Flex, Grid, Text } from "@radix-ui/themes";
+import React, { type FC } from "react";
+import styled from "styled-components";
+import { t } from "ttag";
+
+const ImageCriteriaList = styled.ul`
+ list-style: none;
+ padding: 0;
+
+ .image-criteria-list__list-item {
+ img {
+ max-width: 100%;
+ }
+ }
+
+ .image-criteria-list__icon {
+ fill: var(--green-a10);
+ stroke: var(--green-a10);
+ width: 1.5rem;
+ height: 1.5rem;
+ flex-shrink: 0;
+ }
+
+ .image-criteria-list__heading {
+ margin: 0;
+ font-size: 1rem;
+ }
+
+ .image-criteria-list__pictogram {
+ margin: 0;
+
+ & > figcaption {
+ text-align: center;
+ }
+ }
+ `;
+
+export const ImageUploadCriteriaList: FC = () => {
+ return (
+
+
+
+
+
+
+
+
+ {t`It contains useful information on accessibility.`}
+
+
+ {t`For example by showing entrances, toilets or a map of the site.`}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {t`Was taken by me.`}
+
+
+
+ {t`By uploading this image, I hereby publish it in the public domain as renounce copyright protection.`}
+
+
+ ({t`CC0 1.0 Universal license`})
+
+
+
+
+
+
+
+
+
+ {t`Doesn't show identifiable persons.`}
+
+
+
+
+
+
+ );
+};
diff --git a/src/components/CombinedFeaturePanel/type-specific/poi/PlaceOfInterestDetails.tsx b/src/components/CombinedFeaturePanel/type-specific/poi/PlaceOfInterestDetails.tsx
index fc72c390c..9f768ccab 100644
--- a/src/components/CombinedFeaturePanel/type-specific/poi/PlaceOfInterestDetails.tsx
+++ b/src/components/CombinedFeaturePanel/type-specific/poi/PlaceOfInterestDetails.tsx
@@ -1,34 +1,43 @@
-import { Callout } from '@blueprintjs/core'
-import { t } from 'ttag'
-import Link from 'next/link'
-import React, { useContext } from 'react'
-import { AnyFeature, isPlaceInfo } from '../../../../lib/model/geo/AnyFeature'
-import FeatureAccessibility from '../../components/AccessibilitySection/FeatureAccessibility'
-import FeatureContext from '../../components/FeatureContext'
-import FeatureNameHeader from '../../components/FeatureNameHeader'
-import AddressMapsLinkItems from '../../components/IconButtonList/AddressMapsLinkItems'
-import ExternalInfoAndEditPageLinks from '../../components/IconButtonList/ExternalInfoAndEditPageLinks'
-import PhoneNumberLinks from '../../components/IconButtonList/PhoneNumberLinks'
-import PlaceWebsiteLink from '../../components/IconButtonList/PlaceWebsiteLink'
-import StyledIconButtonList from '../../components/IconButtonList/StyledIconButtonList'
-import FeatureImage from '../../components/image/FeatureImage'
-import FeaturesDebugJSON from '../../components/FeaturesDebugJSON'
-import NextToiletDirections from '../../components/AccessibilitySection/NextToiletDirections'
-import { AppStateLink } from '../../../App/AppStateLink'
-import { FeaturePanelContext } from '../../FeaturePanelContext'
-import { useMap } from '../../../Map/useMap'
-import { AccessibilityItems } from '../../components/AccessibilitySection/PlaceAccessibility/AccessibilityItems'
-import { FeatureGallery } from '../../components/FeatureGallery'
-import { bbox } from '@turf/turf'
+import { Callout } from "@blueprintjs/core";
+import { bbox } from "@turf/turf";
+import Link from "next/link";
+import React, { useContext } from "react";
+import { t } from "ttag";
+import { FeatureImageUpload } from "~/components/CombinedFeaturePanel/components/FeatureImageUpload";
+import {
+ type AnyFeature,
+ isPlaceInfo,
+} from "../../../../lib/model/geo/AnyFeature";
+import { AppStateLink } from "../../../App/AppStateLink";
+import { useMap } from "../../../Map/useMap";
+import { FeaturePanelContext } from "../../FeaturePanelContext";
+import FeatureAccessibility from "../../components/AccessibilitySection/FeatureAccessibility";
+import NextToiletDirections from "../../components/AccessibilitySection/NextToiletDirections";
+import { AccessibilityItems } from "../../components/AccessibilitySection/PlaceAccessibility/AccessibilityItems";
+import FeatureContext from "../../components/FeatureContext";
+import { FeatureGallery } from "../../components/FeatureGallery";
+import FeatureNameHeader from "../../components/FeatureNameHeader";
+import FeaturesDebugJSON from "../../components/FeaturesDebugJSON";
+import AddressMapsLinkItems from "../../components/IconButtonList/AddressMapsLinkItems";
+import ExternalInfoAndEditPageLinks from "../../components/IconButtonList/ExternalInfoAndEditPageLinks";
+import PhoneNumberLinks from "../../components/IconButtonList/PhoneNumberLinks";
+import PlaceWebsiteLink from "../../components/IconButtonList/PlaceWebsiteLink";
+import StyledIconButtonList from "../../components/IconButtonList/StyledIconButtonList";
+import FeatureImage from "../../components/image/FeatureImage";
type Props = {
feature: AnyFeature;
- focusImage?: string;
-}
+ activeImageId?: string;
+ isUploadDialogOpen?: boolean;
+};
-export default function PlaceOfInterestDetails({ feature, focusImage }: Props) {
- const { baseFeatureUrl } = useContext(FeaturePanelContext)
- const map = useMap()
+export default function PlaceOfInterestDetails({
+ feature,
+ activeImageId,
+ isUploadDialogOpen,
+}: Props) {
+ const { baseFeatureUrl } = useContext(FeaturePanelContext);
+ const map = useMap();
if (!feature.properties) {
return (
@@ -41,7 +50,7 @@ export default function PlaceOfInterestDetails({ feature, focusImage }: Props) {
-
-
-
+ <>
+
+ {t`Before uploading a new image, please make sure that the image meets the following criteria:`}
+
+
+
+
+
+
+
+
+
+
+ {t`It contains useful information on accessibility.`}
+
+
+ {t`For example by showing entrances, toilets or a map of the site.`}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- {t`It contains useful information on accessibility.`}
+ {t`Was taken by me.`}
-
- {t`For example by showing entrances, toilets or a map of the site.`}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {t`Was taken by me.`}
-
-
-
- {t`By uploading this image, I hereby publish it in the public domain as renounce copyright protection.`}
-
-
- ({t`CC0 1.0 Universal license`})
-
-
-
-
-
-
-
-
-
- {t`Doesn't show identifiable persons.`}
-
-
-
-
-
-
+
+
+ {t`By uploading this image, I hereby publish it in the public domain as renounce copyright protection.`}
+ (
+
+
+
+ {t`CC0 1.0 Universal license`}
+
+
+
+
+
+ )
+
+ {t`This link opens in a new window.`}
+
+
+
+
+
+
- {t`It contains useful information on accessibility.`}
-
-
- {t`For example by showing entrances, toilets or a map of the site.`}
-
-
-
-
-
-
-
+
+
+
+ {t`It contains useful information on accessibility.`}
+
+
+
+ {t`For example by showing entrances, toilets or a map of the site.`}
+
+
+
+
+
+
+
-
+
- {t`Was taken by me.`}
+ {t`It was taken by me.`}
- {t`By uploading this image, I hereby publish it in the public domain as renounce copyright protection.`}
- (
-
-
-
- {t`CC0 1.0 Universal license`}
-
-
-
-
-
- )
+ {t`By uploading this image, I hereby publish it in the public domain as renounce copyright protection: `}
+
+
+ {t`CC0 1.0 Universal license`}
+
+
+
{t`This link opens in a new window.`}
@@ -136,9 +131,9 @@ export const ImageUploadCriteriaList: FC = () => {
-
+
- {t`Doesn't show identifiable persons.`}
+ {t`It doesn't show identifiable persons.`}
diff --git a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadDropzone.tsx b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadDropzone.tsx
index d5ffe12fa..4f7b2b02f 100644
--- a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadDropzone.tsx
+++ b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadDropzone.tsx
@@ -6,23 +6,37 @@ import { t } from "ttag";
import { ImageUploadContext } from "~/components/CombinedFeaturePanel/components/FeatureImageUpload";
const Dropzone = styled.div<{ $isDragActive?: boolean }>`
- padding: 3rem 4rem;
- border-style: dashed;
- border-width: 2px;
- border-color: var(--accent-9);
- border-radius: var(--radius-4);
- background: ${(props) => (props.$isDragActive ? "var(--accent-3)" : "var(--gray-3)")};
- transition: all 100ms ease;
- text-align: center;
-
- &:hover {
- border-color: var(--accent-11);
- }
-
- &:after {
- border: none;
- outline: none;
- }
+ padding: 3rem 4rem;
+ border-style: dashed;
+ border-width: 2px;
+ border-color: var(--accent-9);
+ border-radius: var(--radius-4);
+ background: ${(props) => (props.$isDragActive ? "var(--accent-3)" : "var(--gray-3)")};
+ transition: all 100ms ease;
+ text-align: center;
+
+ &:hover {
+ border-color: var(--accent-11);
+ }
+
+ &:after {
+ border: none;
+ outline: none;
+ }
+
+ .image-upload-dropzone__text--on-desktop {
+ @media (hover: none) {
+ display: none;
+ }
+ }
+
+ .image-upload-dropzone__text--on-mobile {
+ display: none;
+
+ @media (hover: none) {
+ display: block;
+ }
+ }
`;
export type ImageWithPreview = File & {
@@ -54,10 +68,19 @@ export const ImageUploadDropzone: FC = () => {
<>
-
+ {t`Drag an image here to select it`}
- {t`or click the select button.`}
+
+ {t`or click the select button.`}
+
+
+ {t`Use the following button to select an image:`}
+ {t`Select image`}
diff --git a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadPreview.tsx b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadPreview.tsx
index bf37c06df..d31af9519 100644
--- a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadPreview.tsx
+++ b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadPreview.tsx
@@ -22,19 +22,19 @@ const uncachedUrl =
process.env.NEXT_PUBLIC_ACCESSIBILITY_CLOUD_UNCACHED_BASE_URL || "";
const ImagePreview = styled.div`
- position: relative;
-
- .image-upload-review__preview-image {
- width: 100%;
- height: 100%;
- object-fit: cover;
- }
+ position: relative;
+
+ .image-upload-review__preview-image {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
.image-upload-review__overlay {
position: absolute;
inset: 0;
z-index: 1;
- background: rgba(0,0,0,0.7);
+ background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(6px);
display: flex;
justify-content: center;
@@ -81,7 +81,6 @@ export const ImageUploadPreview: FC<{
return (
<>
- {t`Please review your selected image:`}
{isUploading && (
@@ -119,7 +118,7 @@ export const ImageUploadPreview: FC<{
-
+ = ({
uploadStep,
}) => {
return (
-
+
{t`1. Criteria`}
diff --git a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadProgressItem.tsx b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadProgressItem.tsx
index 663685ada..c5281f497 100644
--- a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadProgressItem.tsx
+++ b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadProgressItem.tsx
@@ -6,7 +6,12 @@ export const ImageUploadProgressItem: FC<{
active?: boolean;
}> = ({ children, active }) => {
return (
-
+ {children}
);
diff --git a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadSuccess.tsx b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadSuccess.tsx
index e1da12c90..dfa7c821d 100644
--- a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadSuccess.tsx
+++ b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadSuccess.tsx
@@ -10,12 +10,12 @@ export const ImageUploadSuccess: FC = () => {
return (
<>
-
-
+
+ {t`Image uploaded successfully!`}
- {t`Thank you for your contribution. The image will be checked by our staff before it will be visible on Wheelmap. This can take a while, please be patient.`}
+ {t`Thank you for your contribution. The image will be checked by our staff before it's visible on Wheelmap. This can take a while, please be patient.`}
From 3c69d1aa91b06f8bc2f8f935e13373b2fb360552 Mon Sep 17 00:00:00 2001
From: Kris Siepert
Date: Wed, 18 Dec 2024 16:11:56 +0100
Subject: [PATCH 06/12] chore: remove unused props
---
src/components/CombinedFeaturePanel/CombinedFeaturePanel.tsx | 3 ---
.../type-specific/poi/PlaceOfInterestDetails.tsx | 2 --
2 files changed, 5 deletions(-)
diff --git a/src/components/CombinedFeaturePanel/CombinedFeaturePanel.tsx b/src/components/CombinedFeaturePanel/CombinedFeaturePanel.tsx
index dc5a8eb9f..9d54b15b0 100644
--- a/src/components/CombinedFeaturePanel/CombinedFeaturePanel.tsx
+++ b/src/components/CombinedFeaturePanel/CombinedFeaturePanel.tsx
@@ -2,7 +2,6 @@ import { useHotkeys } from "@blueprintjs/core";
import { Box, Callout } from "@radix-ui/themes";
import { uniqBy } from "lodash";
import React, { useMemo, useState } from "react";
-import styled from "styled-components";
import { t } from "ttag";
import {
type AnyFeature,
@@ -10,7 +9,6 @@ import {
isOSMFeature,
isSearchResultFeature,
} from "../../lib/model/geo/AnyFeature";
-import colors from "../../lib/util/colors";
import ErrorBoundary from "../shared/ErrorBoundary";
import FeaturesDebugJSON from "./components/FeaturesDebugJSON";
import OSMBuildingDetails from "./type-specific/building/OSMBuildingDetails";
@@ -21,7 +19,6 @@ type Props = {
features: AnyFeature[];
activeImageId?: string;
isUploadDialogOpen?: boolean;
- uploadStep?: string;
};
function FeatureSection({ feature }: { feature: AnyFeature }) {
diff --git a/src/components/CombinedFeaturePanel/type-specific/poi/PlaceOfInterestDetails.tsx b/src/components/CombinedFeaturePanel/type-specific/poi/PlaceOfInterestDetails.tsx
index 2e0153a05..9f768ccab 100644
--- a/src/components/CombinedFeaturePanel/type-specific/poi/PlaceOfInterestDetails.tsx
+++ b/src/components/CombinedFeaturePanel/type-specific/poi/PlaceOfInterestDetails.tsx
@@ -29,14 +29,12 @@ type Props = {
feature: AnyFeature;
activeImageId?: string;
isUploadDialogOpen?: boolean;
- uploadStep?: string;
};
export default function PlaceOfInterestDetails({
feature,
activeImageId,
isUploadDialogOpen,
- uploadStep,
}: Props) {
const { baseFeatureUrl } = useContext(FeaturePanelContext);
const map = useMap();
From 56c9187ed7722aa5e95555a6866aac9146d7aca2 Mon Sep 17 00:00:00 2001
From: Kris Siepert
Date: Thu, 2 Jan 2025 17:13:03 +0100
Subject: [PATCH 07/12] chore: make imports absolute
---
.../CombinedFeaturePanel/components/Gallery/Gallery.tsx | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/components/CombinedFeaturePanel/components/Gallery/Gallery.tsx b/src/components/CombinedFeaturePanel/components/Gallery/Gallery.tsx
index 9819a1e58..436bbe9df 100644
--- a/src/components/CombinedFeaturePanel/components/Gallery/Gallery.tsx
+++ b/src/components/CombinedFeaturePanel/components/Gallery/Gallery.tsx
@@ -5,12 +5,11 @@ import {
createContext,
useContext,
useEffect,
- useRef,
useState,
} from "react";
import { t } from "ttag";
-import type { AccessibilityCloudImage } from "../../../../lib/model/ac/Feature";
-import { useAppStateAwareRouter } from "../../../../lib/util/useAppStateAwareRouter";
+import type { AccessibilityCloudImage } from "~/lib/model/ac/Feature";
+import { useAppStateAwareRouter } from "~/lib/util/useAppStateAwareRouter";
import { FeaturePanelContext } from "../../FeaturePanelContext";
import { GalleryFullscreenItem } from "./GalleryFullscreenItem";
import { GalleryGrid } from "./GalleryGrid";
From 1ea36c85c4496ada8c192f91e0c7c38ca6a96b67 Mon Sep 17 00:00:00 2001
From: Kris Siepert
Date: Thu, 2 Jan 2025 17:13:23 +0100
Subject: [PATCH 08/12] fix: flickering
---
.../components/FeatureImageUpload.tsx | 25 +++++++++++++++----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/src/components/CombinedFeaturePanel/components/FeatureImageUpload.tsx b/src/components/CombinedFeaturePanel/components/FeatureImageUpload.tsx
index 190180f71..de3394e96 100644
--- a/src/components/CombinedFeaturePanel/components/FeatureImageUpload.tsx
+++ b/src/components/CombinedFeaturePanel/components/FeatureImageUpload.tsx
@@ -51,7 +51,6 @@ export const FeatureImageUpload: FC<{
isUploadDialogOpen?: boolean;
}> = ({ feature, isUploadDialogOpen }) => {
const { baseFeatureUrl } = useContext(FeaturePanelContext);
- const router = useRouter();
const [step, setStep] = useState(1);
const [image, setImage] = useState();
@@ -68,7 +67,7 @@ export const FeatureImageUpload: FC<{
}, []);
const close = useCallback(() => {
setIsDialogOpen(false);
- }, []);
+ }, [step]);
const nextStep = useCallback(() => {
if (step < 4) setStep(step + 1);
}, [step]);
@@ -76,6 +75,7 @@ export const FeatureImageUpload: FC<{
if (step > 1) setStep(step - 1);
}, [step]);
+ // biome-ignore lint/correctness/useExhaustiveDependencies:
const handleOnClickAddImageButton: MouseEventHandler = useCallback(
(event) => {
event.preventDefault();
@@ -99,6 +99,14 @@ export const FeatureImageUpload: FC<{
event.preventDefault();
}, []);
+ // biome-ignore lint/correctness/useExhaustiveDependencies:
+ useEffect(() => {
+ if (!isDialogOpen && step === 4) {
+ setStep(1);
+ setImage(undefined);
+ }
+ }, [isDialogOpen]);
+
useEffect(() => {
if (image) {
window.addEventListener("beforeunload", confirmWindowUnload);
@@ -110,11 +118,18 @@ export const FeatureImageUpload: FC<{
};
}, [image, confirmWindowUnload]);
- // Reset the url when closing the dialog
+ // Reset the url when closing the dialog. This is not using react router on purpose.
+ // When using react-router it will re-render the whole FeaturePanel, because it's a
+ // new page. This introduces lag, and we want the dialog to open immediately after
+ // clicking on the image. This is temporary, the proper solution should be to use
+ // a catch-all router in the `[placeType]/[id]/index.tsx` and handle different
+ // nested-routes like image upload or fullscreen image there, without re-rendering
+ // the whole FeaturePanel.
+ // TODO: replace with catch-all route
// biome-ignore lint/correctness/useExhaustiveDependencies:
useEffect(() => {
if (!isDialogOpen && window.location.pathname !== baseFeatureUrl) {
- router.push(baseFeatureUrl, undefined, { shallow: true });
+ window.history.replaceState(null, document.title, baseFeatureUrl);
}
}, [isDialogOpen]);
@@ -122,7 +137,7 @@ export const FeatureImageUpload: FC<{
// biome-ignore lint/correctness/useExhaustiveDependencies:
useEffect(() => {
if (isDialogOpen && window.location.pathname !== baseUploadUrl) {
- router.push(baseUploadUrl, undefined, { shallow: true });
+ window.history.replaceState(null, document.title, baseUploadUrl);
}
}, [isDialogOpen]);
From 80e7f19a8c5e464766632ec2cc016e64b67fe19a Mon Sep 17 00:00:00 2001
From: Kris Siepert
Date: Mon, 6 Jan 2025 15:16:38 +0100
Subject: [PATCH 09/12] refactor: replace BEM with styled components in image
upload
---
.../ImageUpload/ImageUploadCriteriaList.tsx | 97 +++++++++----------
1 file changed, 47 insertions(+), 50 deletions(-)
diff --git a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCriteriaList.tsx b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCriteriaList.tsx
index 88fb3bbc8..cf3f41750 100644
--- a/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCriteriaList.tsx
+++ b/src/components/CombinedFeaturePanel/components/ImageUpload/ImageUploadCriteriaList.tsx
@@ -14,37 +14,34 @@ import styled from "styled-components";
import { t } from "ttag";
import { ImageUploadContext } from "~/components/CombinedFeaturePanel/components/FeatureImageUpload";
-const ImageCriteriaList = styled.ul`
+const CriteriaList = styled.ul`
list-style: none;
padding: 0;
+`;
- .image-criteria-list__list-item {
- img {
- max-width: 100%;
- }
- }
-
- .image-criteria-list__icon {
- fill: var(--green-a10);
- stroke: var(--green-a10);
- width: 1.5rem;
- height: 1.5rem;
- flex-shrink: 0;
- }
+const CriteriaListItem = styled.li`
+ img { max-width: 100%; }
+`;
- .image-criteria-list__heading {
- margin: 0;
- font-size: 1rem;
- }
-
- .image-criteria-list__pictogram {
- margin: 0;
-
- & > figcaption {
- text-align: center;
- }
- }
- `;
+const CriteriaListIcon = styled(CheckIcon)`
+ fill: var(--green-a10);
+ stroke: var(--green-a10);
+ width: 1.5rem;
+ height: 1.5rem;
+ flex-shrink: 0;
+`;
+
+const CriteriaListPictogram = styled.figure`
+ margin: 0;
+ & > figcaption {
+ text-align: center;
+ }
+`;
+
+const CriteriaListHeading = styled.header`
+ margin: 0;
+ font-size: 1rem;
+`;
export const ImageUploadCriteriaList: FC = () => {
const { nextStep, close } = useContext(ImageUploadContext);
@@ -56,21 +53,21 @@ export const ImageUploadCriteriaList: FC = () => {
-
+
-
+
-
-
+
+
{t`It contains useful information on accessibility.`}
-
+
{t`For example by showing entrances, toilets or a map of the site.`}
-
-
-
+
-
+
-
+
-
-
+
+
{t`It was taken by me.`}
-
+
{t`By uploading this image, I hereby publish it in the public domain as renounce copyright protection: `}
@@ -126,19 +123,19 @@ export const ImageUploadCriteriaList: FC = () => {
{t`This link opens in a new window.`}
-