Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/edit-zone #77

Merged
merged 4 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
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
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
Loading