Skip to content

Commit

Permalink
Merge pull request #77 from helsingborg-stad/feature/edit-zone
Browse files Browse the repository at this point in the history
Feature/edit-zone
  • Loading branch information
D3nnis38 authored Jul 29, 2024
2 parents 0fe524b + a85874b commit 7d4d9f9
Show file tree
Hide file tree
Showing 34 changed files with 11,512 additions and 4,461 deletions.
15,356 changes: 10,934 additions & 4,422 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions src/api/zone/zone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@ export const getZones = () => client.get<FeatureCollection>('/zones/');
export const getZonesByOrganisation = (id: string) => client.get<FeatureCollection>(`/organisations/${id}/zones`);
export const getDistributionZones = (id: string) => client.get<FeatureCollection>(`/zones/${id}/distribution`);
export const getDeliveryZones = (id: string) => client.get<FeatureCollection>(`/zones/${id}/delivery`);
export const getZoneById = (id: string) => client.get<FeatureCollection>(`/zones/${id}`);
export const deleteZone = (id: string) => client.delete(`/zones/${id}`);
export const postZones = (zones: FeatureCollection) => client.post('/zones/', zones);
export const patchZone = (id: string, zone: FeatureCollection) => client.patch(`/zones/${id}`, zone);
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FC } from 'react';
import { Feature } from 'types/zone';
import { useRenderMap } from '../../hooks/useRenderMap';
import { useRenderMap } from './useRenderMap';

type MapSnippetProps = {
zone: Feature;
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/components/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const Menu = () => {
<Styled.SectionTwo>
<Styled.Text onClick={() => navigate('/account')}>Konto</Styled.Text>
<Styled.Text onClick={() => navigate('/account/zones')}>Hantera zoner</Styled.Text>
<Styled.Text onClick={() => navigate('/account/zones/create-zones')}>Lägg till zoner</Styled.Text>
<Styled.Text onClick={() => navigate('/account/zones/create')}>Lägg till zoner</Styled.Text>
</Styled.SectionTwo>
<Styled.SectionThree>
<Styled.Text onClick={() => logOutAndRedirect()}>Logga ut</Styled.Text>
Expand Down
6 changes: 3 additions & 3 deletions src/components/SideBar/SideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ export const SideBar = () => {
Hantera zoner
</Button>
<Button
onClick={handleNavigate('/account/zones/create-zones')}
onClick={handleNavigate('/account/zones/create')}
buttonSize={ButtonSize.SMALL}
secondary={activePath === '/account/zones/create-zones'}
tertiary={activePath !== '/account/zones/create-zones'}
secondary={activePath === '/account/zones/create'}
tertiary={activePath !== '/account/zones/create'}
type="button"
>
Lägg till zoner
Expand Down
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ export * from './Loading';
export * from './Menu';
export * from './SideBar';
export * from './Select';
export * from './ClickOutsideCloser';
6 changes: 6 additions & 0 deletions src/hooks/useZoneApi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
getZones, getDistributionZones, getDeliveryZones, getZonesByOrganisation, deleteZone, postZones,
patchZone,
getZoneById,
} from 'api/zone';
import { FeatureCollection } from 'types/zone';

Expand All @@ -8,15 +10,19 @@ export const useZoneApi = () => {
const getAllZonesByOrganisation = (id: string) => getZonesByOrganisation(id);
const getRelatedDistributionZones = (id: string) => getDistributionZones(id);
const getRelatedDeliveryZones = (id: string) => getDeliveryZones(id);
const getZone = (id: string) => getZoneById(id);
const deleteZoneById = (id: string) => deleteZone(id);
const createZones = (zones: FeatureCollection) => postZones(zones);
const editZone = (id: string, zone: FeatureCollection) => patchZone(id, zone);

return {
getAllZones,
getAllZonesByOrganisation,
getRelatedDistributionZones,
getRelatedDeliveryZones,
getZone,
deleteZoneById,
createZones,
editZone,
};
};
4 changes: 3 additions & 1 deletion src/modules/Account/AccountRouter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { Route, Routes } from 'react-router-dom';
const AccountSettings = lazy(() => import('./AccountSettings'));
const ZonesSettings = lazy(() => import('./ZonesSettings'));
const CreateZones = lazy(() => import('./CreateZones'));
const EditZone = lazy(() => import('./EditZone'));

export const AccountRouter = () => (
<DeliveryLayout>
<Routes>
<Route path="/zones/create-zones" element={<CreateZones />} />
<Route path="/zones/create" element={<CreateZones />} />
<Route path="/zones/:id/edit" element={<EditZone />} />
<Route path="/zones" element={<ZonesSettings />} />
<Route path="/" element={<AccountSettings />} />
</Routes>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/* eslint-disable react/jsx-props-no-spreading */
import { useDropzone } from 'react-dropzone';
import { Input, Button, Select } from 'components';
import { ClickOutsideCloser } from '../ClickOutsideCloser';
import { useCreateZonesForm } from '../../hooks/useCreateZonesForm';
import { MapSnippet } from '../MapSnippet';
import {
Input, Button, Select, ClickOutsideCloser,
} from 'components';
import { useCreateZonesForm } from './hooks/useCreateZonesForm';
import { MapSnippet } from '../../../../../components/MapSnippet';
import * as Styled from './styled';

export const CreateZonesForm = () => {
Expand Down Expand Up @@ -75,6 +76,15 @@ export const CreateZonesForm = () => {
placeholder="Namn på zon"
error={errors[index]?.name}
/>
<Input
label="GLN"
type="text"
value={zone.properties.gln}
onChange={setFieldValue(index, 'gln')}
name="gln"
placeholder="GLN (Lokaliseringsnummer)"
error={errors[index]?.gln}
/>
<ClickOutsideCloser
onClick={() => {
if (activeAddress === zone.properties.id) { clearSuggestions(); }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './useCreateZonesForm';
export * from '../../../../../../components/MapSnippet/useRenderMap';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { z } from 'zod';

export const featureCollectionValidation = z.object({
type: z.literal('FeatureCollection'),
features: z.array(z.object({
type: z.literal('Feature'),
geometry: z.object({
type: z.literal('Polygon'),
coordinates: z.array(z.array(z.array(z.number()))),
}),
properties: z.object({
name: z.string().min(1, { message: 'Namn är obligatoriskt' }),
address: z.string().min(1, { message: 'Adress är obligatoriskt' }),
area: z.string().min(1, { message: 'Område är obligatoriskt' }),
type: z.enum(['distribution', 'delivery']),
gln: z.string().min(1, { message: 'GLN är obligatoriskt' }),
}),
})),
});
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ export const useCreateZonesForm = () => {
navigate('/login');
} else if (err.response.status === 400) {
setApiErrorText('En eller flera av zonerna finns redan registrerade.');
} else if (err.response.status === 409) {
setApiErrorText('En eller flera zoner har samma GLN.');
}
});
};
Expand Down
2 changes: 0 additions & 2 deletions src/modules/Account/CreateZones/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
export * from './CreateZonesForm';
export * from './ClickOutsideCloser';
export * from './MapSnippet';
2 changes: 0 additions & 2 deletions src/modules/Account/CreateZones/hooks/index.ts

This file was deleted.

38 changes: 38 additions & 0 deletions src/modules/Account/EditZone/EditZone.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { useEffect, useRef } from 'react';
import { useLoadScript } from '@react-google-maps/api';
import { useAuth } from 'hooks/useAuth';
import { SideBar } from 'components';
import { EditZoneForm } from './components';
import * as Styled from './styled';

const { VITE_GOOGLE_MAPS_API_KEY } = import.meta.env;

export const EditZone = () => {
const { hasToken } = useAuth();
const libraries = useRef<any>(['places']);
const isAuthenticated = hasToken();
const { isLoaded } = useLoadScript({
googleMapsApiKey: VITE_GOOGLE_MAPS_API_KEY,
libraries: libraries.current,
});

useEffect(() => {
if (!isAuthenticated) {
window.location.href = '/auth/login';
}
}, [isAuthenticated]);

if (!isAuthenticated) {
return null;
}

return (
<Styled.ContentContainer>
<SideBar />
<Styled.FormContainer>
<Styled.Header>Lägg till zoner</Styled.Header>
{isLoaded && <EditZoneForm />}
</Styled.FormContainer>
</Styled.ContentContainer>
);
};
124 changes: 124 additions & 0 deletions src/modules/Account/EditZone/components/EditZoneForm/EditZoneForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import {
Input, Button, Select, ClickOutsideCloser,
Loading,
} from 'components';
import { useNavigate } from 'react-router-dom';
import { useEditZoneForm } from './hooks/useEditZoneForm';
import { MapSnippet } from '../../../../../components/MapSnippet';
import * as Styled from './styled';

export const EditZoneForm = () => {
const navigate = useNavigate();
const {
featureCollection,
setFieldValue,
submitForm,
errors,
apiErrorText,
addressStatus,
clearSuggestions,
ready,
addressData,
handleSelectAddress,
activeAddress,
isLoadingData,
} = useEditZoneForm();

const renderSuggestions = (index: number) => addressData.map((suggestion) => {
const {
place_id: placeId,
structured_formatting: { main_text: mainText, secondary_text: secondaryText },
} = suggestion;

return (
<Styled.ListItem
key={placeId}
onClick={handleSelectAddress(index, suggestion)}
title={mainText}
>
<strong>{mainText}</strong>
{' '}
<small>{secondaryText}</small>
</Styled.ListItem>
);
});

if (isLoadingData) {
return (
<Loading />
);
}

return (
<Styled.ContentContainer>
<form onSubmit={submitForm}>
{featureCollection.features
.map((zone, index) => (
<Styled.SplitContainer key={zone.properties.id}>
<Styled.InputContainer>
<Input
label="Namn"
type="text"
value={zone.properties.name}
onChange={setFieldValue(index, 'name')}
name="name"
placeholder="Namn på zon"
error={errors[index]?.name}
/>
<Input
label="GLN"
type="text"
value={zone.properties.gln}
onChange={setFieldValue(index, 'gln')}
name="gln"
placeholder="GLN (Lokaliseringsnummer)"
error={errors[index]?.gln}
/>
<ClickOutsideCloser
onClick={() => {
if (activeAddress === zone.properties.id) { clearSuggestions(); }
}}
key={zone.properties.id}
>
<>
<Input
label="Adress"
type="text"
value={zone.properties.address}
onChange={setFieldValue(index, 'address')}
placeholder="Adress till zon"
name="address"
error={errors[index]?.address}
disabled={!ready}
/>
{addressStatus === 'OK' && activeAddress === zone.properties.id && <Styled.List>{renderSuggestions(index)}</Styled.List>}
</>
</ClickOutsideCloser>
<Input
label="Område"
type="text"
value={zone.properties.area}
onChange={setFieldValue(index, 'area')}
name="area"
placeholder="Område"
error={errors[index]?.area}
/>
<Select label="Typ" value={zone.properties.type} name="type" onChange={setFieldValue(index, 'type')}>
<option value="delivery">Leverans zon</option>
<option value="distribution">Distributions zon</option>
</Select>
</Styled.InputContainer>
<Styled.MapContainer>
<MapSnippet zone={zone} />
</Styled.MapContainer>
</Styled.SplitContainer>
))}
{apiErrorText && <Styled.ErrorText>{apiErrorText}</Styled.ErrorText>}
<Styled.ButtonContainer>
<Button type="submit" onClick={() => submitForm} primary>Spara</Button>
<Button type="submit" onClick={() => navigate('/account/zones')} secondary>Avbryt</Button>
</Styled.ButtonContainer>
</form>
</Styled.ContentContainer>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useEditZoneForm';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './useEditZoneForm';
Loading

0 comments on commit 7d4d9f9

Please sign in to comment.