Skip to content

Commit

Permalink
Merge pull request #117 from jamalsoueidan/update-mantine-ui
Browse files Browse the repository at this point in the history
update mantine and fix some other issues
  • Loading branch information
jamalsoueidan authored Jul 2, 2024
2 parents e7593be + cc627fe commit 91786dd
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 129 deletions.
88 changes: 40 additions & 48 deletions app/components/LeafletMap.client.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import {Avatar, MantineProvider} from '@mantine/core';
import {Avatar, Box, MantineProvider} from '@mantine/core';
import L, {divIcon, point} from 'leaflet';
import {useEffect} from 'react';
import {renderToStaticMarkup} from 'react-dom/server';
import {MapContainer, Marker, Popup, TileLayer, useMap} from 'react-leaflet';
import {type TreatmentsForCollectionFragment} from 'storefrontapi.generated';
import {type CustomerLocationAllOfGeoLocation} from '~/lib/api/model';
import {
Circle,
MapContainer,
Marker,
Popup,
TileLayer,
useMap,
} from 'react-leaflet';

export type Coordinates = {
lat: number;
Expand All @@ -29,72 +34,59 @@ const AutoCenterMap = ({markers}: {markers: Coordinates[]}) => {
useEffect(() => {
if (markers.length > 0) {
const bounds = L.latLngBounds(markers);
map.fitBounds(bounds, {padding: [100, 100]});
map.fitBounds(bounds, {padding: [1000, 1000]});
map.zoomOut(12);
}
}, [markers, map]);

return null;
};

export function LeafletMap({
products,
}: {
products: TreatmentsForCollectionFragment[];
}) {
const geoLocations = products.reduce((geos, product) => {
const newGeos = product.locations?.references?.nodes.reduce((geos, l) => {
if (l.geoLocation?.value) {
const value = JSON.parse(
l.geoLocation.value,
) as CustomerLocationAllOfGeoLocation;
geos.push({
lat: value.coordinates[1],
lng: value.coordinates[0],
image: product.user?.reference?.image?.reference?.image?.url || '',
});
}
return geos;
}, [] as Coordinates[]);
if (newGeos) {
geos.push(...newGeos);
}
return geos;
}, [] as Coordinates[]);
export type LeafletMapMarker = {
id: string;
lng: number;
lat: number;
image: string;
radius: number | null;
};

export function LeafletMap({markers}: {markers: Array<LeafletMapMarker>}) {
return (
<div
style={{
height: '100vh',
border: '1px solid #dee2e6',
borderRadius: '10px',
}}
>
<Box h="250px">
<MapContainer
style={{
height: '100%',
borderRadius: '10px',
}}
zoom={6}
>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
{geoLocations.map((geo) => {
return (
{markers.map((geo) =>
geo.radius ? (
<Circle
key={geo.lat}
color="red"
fillColor="#f04"
fillOpacity={0.5}
radius={geo.radius}
center={[geo.lat, geo.lng]}
>
<Popup>Kører ud til de her områder.</Popup>
</Circle>
) : (
<Marker
key={geo.lat + geo.lng}
position={geo}
key={geo.lng}
position={[geo.lat, geo.lng]}
icon={createClusterCustomIcon(geo.image)}
>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
<Popup>Salon/Hjem position.</Popup>
</Marker>
);
})}
<AutoCenterMap markers={geoLocations} />
),
)}
<AutoCenterMap markers={markers} />
</MapContainer>
</div>
</Box>
);
}
130 changes: 100 additions & 30 deletions app/routes/$.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Flex,
Grid,
Group,
Loader,
rem,
Skeleton,
Spoiler,
Expand All @@ -18,13 +19,14 @@ import {
UnstyledButton,
} from '@mantine/core';
import '@mantine/tiptap/styles.css';
import {Await, Link, Outlet, useLoaderData} from '@remix-run/react';
import {Await, Link, useLoaderData} from '@remix-run/react';
import {
defer,
type LinksFunction,
type LoaderFunctionArgs,
type MetaFunction,
} from '@shopify/remix-oxygen';
import {Suspense, useEffect, useMemo, useState} from 'react';
import React, {Suspense, useEffect, useMemo, useState} from 'react';

import {parseGid} from '@shopify/hydrogen';
import {da} from 'date-fns/locale';
Expand All @@ -43,16 +45,38 @@ import type {
} from 'storefrontapi.generated';
import {LocationIcon} from '~/components/LocationIcon';

import {type CustomerScheduleSlot} from '~/lib/api/model';
import {
type CustomerLocationAllOfGeoLocation,
type CustomerScheduleSlot,
} from '~/lib/api/model';
import {convertLocations} from '~/lib/convertLocations';
import {useDuration} from '~/lib/duration';

import {AE, DK, US} from 'country-flag-icons/react/3x2';
import leafletStyles from 'leaflet/dist/leaflet.css?url';
import {useTranslation} from 'react-i18next';
import {ClientOnly} from 'remix-utils/client-only';
import {
LeafletMap,
type LeafletMapMarker,
} from '~/components/LeafletMap.client';
import {USER_METAOBJECT_QUERY} from '~/graphql/fragments/UserMetaobject';
import {GET_USER_PRODUCTS} from '~/graphql/queries/GetUserProducts';
import {UserProvider, useUser} from '~/hooks/use-user';

import localLeafletStyles from '~/styles/leaflet.css?url';

export const links: LinksFunction = () => [
{
rel: 'stylesheet',
href: leafletStyles,
},
{
rel: 'stylesheet',
href: localLeafletStyles,
},
];

export const handle: Handle = {
i18n: ['global', 'profile', 'professions', 'skills'],
};
Expand Down Expand Up @@ -338,6 +362,7 @@ function UserTreatments() {
<Title order={2} fw="600" mb="md">
{t('treatments_title')}
</Title>

<Suspense fallback={<Skeleton height={8} radius="xl" />}>
<Await resolve={data.collection}>
{({collection}) => {
Expand All @@ -349,22 +374,28 @@ function UserTreatments() {
collections[product.productType].push(product);
return collections;
}, {} as Record<string, TreatmentProductFragment[]>) || {};

return (
<Grid gutter="xl">
<Grid.Col span={{base: 12, md: 8}}>
<Stack gap="xl">
{Object.keys(collections).map((key) => (
<Stack key={key} gap="sm">
<Title order={4} fw="600">
{key}
</Title>
<Stack gap="md">
{collections[key].map((product) => (
<ArtistProduct key={product.id} product={product} />
))}
{Object.keys(collections)
.sort()
.map((key) => (
<Stack key={key} gap="sm">
<Title order={4} fw="600">
{key}
</Title>
<Stack gap="md">
{collections[key].map((product) => (
<ArtistProduct
key={product.id}
product={product}
/>
))}
</Stack>
</Stack>
</Stack>
))}
))}
</Stack>
</Grid.Col>
<Grid.Col span={{base: 12, md: 4}}>
Expand Down Expand Up @@ -393,7 +424,6 @@ function UserTreatments() {
);
}}
</Await>
<Outlet />
</Suspense>
</>
);
Expand All @@ -417,8 +447,32 @@ async function wordToColor(word: string) {

function Schedule({schedule}: {schedule: ScheduleFragment}) {
const {t} = useTranslation(['profile', 'global']);
const user = useUser();
const [scheduleColor, setScheduleColor] = useState<string>('#fff');

const markers = useMemo(
() =>
schedule.locations?.references?.nodes.reduce((geos, l) => {
if (l.geoLocation?.value) {
const value = JSON.parse(
l.geoLocation.value,
) as CustomerLocationAllOfGeoLocation;
geos.push({
id: l.id,
lat: value.coordinates[1],
lng: value.coordinates[0],
radius:
l.locationType?.value === 'destination'
? parseInt(l.maxDriveDistance?.value || '0') * 1000
: null,
image: user.image.url,
});
}
return geos;
}, [] as LeafletMapMarker[]) || [],
[schedule.locations?.references?.nodes, user.image.url],
);

useEffect(() => {
const fetchColor = async () => {
const color = await wordToColor(schedule.handle || '');
Expand All @@ -443,7 +497,7 @@ function Schedule({schedule}: {schedule: ScheduleFragment}) {
<Title order={4} mb="xs">
{t('openingtime')}
</Title>
<Stack gap={rem(3)}>
<Stack gap={rem(3)} mb="md">
{slots?.map((slot) => {
return (
<Group key={slot.day}>
Expand All @@ -467,31 +521,47 @@ function Schedule({schedule}: {schedule: ScheduleFragment}) {
);
})}
</Stack>
<Card.Section>
<Divider my="md" />
</Card.Section>
<Stack gap="xs">
{schedule.locations?.references?.nodes.map((location) => (
<Group key={location.handle}>

{schedule.locations?.references?.nodes.map((location) => (
<React.Fragment key={location.handle}>
<Card.Section>
<Divider mb="md" />
</Card.Section>
<Group mb="md">
<LocationIcon
location={{locationType: location.locationType?.value as any}}
color={scheduleColor || '#000000'}
/>
{location.locationType?.value === 'destination' ||
location.locationType?.value === 'virtual' ? (
<>
{
location.fullAddress?.value?.split(',')[
location.fullAddress?.value?.split(',').length - 1
]
}
<Text>
{
location.fullAddress?.value?.split(',')[
location.fullAddress?.value?.split(',').length - 1
]
}
</Text>
<Text>Hvor skønhedseksperten kører ud til!</Text>
</>
) : (
<>{location.fullAddress?.value}</>
<>
<Text>{location.fullAddress?.value}</Text>
<Text>Hvor behandling finder sted!</Text>
</>
)}
</Group>
))}
</Stack>
<Card.Section>
<ClientOnly fallback={<Loader />}>
{() => (
<LeafletMap
markers={markers.filter((m) => m.id === location.id)}
/>
)}
</ClientOnly>
</Card.Section>
</React.Fragment>
))}
</Card>
);
}
Expand Down
Loading

0 comments on commit 91786dd

Please sign in to comment.