Skip to content

Commit

Permalink
integrated custom field access and save apis
Browse files Browse the repository at this point in the history
  • Loading branch information
aatbip committed Feb 1, 2024
1 parent de90790 commit 3236564
Show file tree
Hide file tree
Showing 18 changed files with 380 additions and 80 deletions.
6 changes: 5 additions & 1 deletion src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import './globals.css';
import ThemeRegistry from './ThemeRegistry';
import { AppContextProvider } from '@/context';
import { ToggleDecider } from '@/hoc/ToggleDecider';
import { Footer } from '@/layouts/Footer';

const inter = Inter({ subsets: ['latin'] });

Expand All @@ -18,7 +19,10 @@ export default function RootLayout({ children }: { children: React.ReactNode })
<AppContextProvider>
<body className={inter.className}>
<ThemeRegistry options={{ key: 'mui' }}>
<ToggleDecider>{children}</ToggleDecider>
<ToggleDecider>
{children}
<Footer />
</ToggleDecider>
</ThemeRegistry>
</body>
</AppContextProvider>
Expand Down
36 changes: 29 additions & 7 deletions src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { SidebarDecider } from '@/hoc/SidebarDecider';
import { apiUrl } from '@/config';
import { ParsedClientProfileUpdatesResponse } from '@/types/clientProfileUpdates';
import { CustomFieldAccessResponse } from '@/types/customFieldAccess';
import { ContextUpdate } from '@/hoc/ContextUpdate';

export const revalidate = 0;

Expand Down Expand Up @@ -39,7 +40,19 @@ async function getCustomFieldAccess({
throw new Error('Something went wrong in getCustomFieldAccess');
}

const data = await res.json();
const { data } = await res.json();

return data;
}

async function getSettings({ token, portalId }: { token: string; portalId: string }) {
const res = await fetch(`${apiUrl}/api/settings?token=${token}&portalId=${portalId}`);

if (!res.ok) {
throw new Error('Something went wrong in getSettings');
}

const { data } = await res.json();

return data;
}
Expand All @@ -49,14 +62,23 @@ export default async function Home({ searchParams }: { searchParams: { token: st

const clientProfileUpdates = await getClientProfileUpdates({ token, portalId });
const customFieldAccess = await getCustomFieldAccess({ token, portalId });
const settings = await getSettings({ token, portalId });

return (
<Stack direction="row">
<MainSection clientProfileUpdates={clientProfileUpdates} />
<ContextUpdate
clientProfileUpdates={clientProfileUpdates}
settings={settings.profileLinks}
access={customFieldAccess}
token={token}
portalId={portalId}
>
<Stack direction="row">
<MainSection />

<SidebarDecider>
<Sidebar />
</SidebarDecider>
</Stack>
<SidebarDecider>
<Sidebar />
</SidebarDecider>
</Stack>
</ContextUpdate>
);
}
12 changes: 1 addition & 11 deletions src/app/views/MainSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,11 @@ import { Header } from '@/layouts/Header';
import { Box } from '@mui/material';
import { Sidebar } from './Sidebar';
import { TableCore } from '@/components/table/Table';
import { ParsedClientProfileUpdatesResponse } from '@/types/clientProfileUpdates';
import { useEffect } from 'react';

interface IMainSection {
clientProfileUpdates: ParsedClientProfileUpdatesResponse[];
}

const MainSection = ({ clientProfileUpdates }: IMainSection) => {
const MainSection = () => {
const appState = useAppState();
const windowWidth = useWindowWidth();

useEffect(() => {
appState?.setAppState((prev) => ({ ...prev, clientProfileUpdates }));
}, [clientProfileUpdates]);

return (
<Box
sx={{
Expand Down
80 changes: 45 additions & 35 deletions src/app/views/Sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
'use client';

import { CustomFieldAccessTable } from '@/components/customFieldAccessTable/CustomFieldAccessTable';
import { Abc, LocationOn, Phone } from '@mui/icons-material';
import { Box, Stack, Typography } from '@mui/material';
import { Switch } from '@/components/switch/Switch';
import { useAppState } from '@/hooks/useAppState';

const customFields = [
{
id: '1',
icon: <LocationOn />,
field: 'Address',
view: true,
edit: true,
},
{
id: '2',
icon: <Phone />,
field: 'Phone number',
view: true,
edit: false,
},
{
id: '3',
icon: <Abc />,
field: 'Website',
view: true,
edit: true,
},
{
id: '4',
icon: <Phone />,
field: 'Experience',
view: true,
edit: true,
},
];

export const Sidebar = () => {
const appState = useAppState();

const handleMutableSettings = (selected: boolean, type: string) => {
if (!selected) {
if (type === 'profile_settings') {
const newSettings = appState?.mutableSettings.filter((el: string) => el !== type);
appState?.setAppState((prev) => ({ ...prev, mutableSettings: newSettings }));
}
if (type === 'payment_method') {
const newSettings = appState?.mutableSettings.filter((el: string) => el !== type);
appState?.setAppState((prev) => ({ ...prev, mutableSettings: newSettings }));
}
}
if (selected) {
if (type === 'profile_settings') {
appState?.setAppState((prev) => ({
...prev,
mutableSettings: appState?.mutableSettings.includes(type)
? appState?.mutableSettings
: [...appState?.mutableSettings, type],
}));
}
if (type === 'payment_method') {
appState?.setAppState((prev) => ({
...prev,
mutableSettings: appState?.mutableSettings.includes(type)
? appState?.mutableSettings
: [...appState?.mutableSettings, type],
}));
}
}
};

return (
<Box
sx={(theme) => ({
Expand All @@ -60,7 +60,7 @@ export const Sidebar = () => {
</Box>

<Box sx={{ padding: '0px 20px' }}>
<CustomFieldAccessTable customFields={customFields} />
<CustomFieldAccessTable />
</Box>

<Box
Expand All @@ -74,12 +74,22 @@ export const Sidebar = () => {

<Stack direction="row" justifyContent="space-between" p="12px 0px 6px 0px">
<Typography variant="bodyMd">General profile settings</Typography>
<Switch selected={true} getValue={(s) => {}} />
<Switch
selected={appState?.mutableSettings.includes('profile_settings')}
getValue={(selected) => {
handleMutableSettings(selected, 'profile_settings');
}}
/>
</Stack>

<Stack direction="row" justifyContent="space-between" p="6px 0px">
<Typography variant="bodyMd">Manage payment method</Typography>
<Switch selected={false} getValue={(s) => {}} />
<Switch
selected={appState?.mutableSettings.includes('payment_method')}
getValue={(selected) => {
handleMutableSettings(selected, 'payment_method');
}}
/>
</Stack>
</Box>
</Box>
Expand Down
95 changes: 70 additions & 25 deletions src/components/customFieldAccessTable/CustomFieldAccessTable.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,50 @@
'use client';

import { Box, Stack, Typography, Divider } from '@mui/material';
import { StyledCheckBox } from '../styled/StyledCheckbox';
import { useState } from 'react';
import { useAppState } from '@/hooks/useAppState';
import { iconsTypeMap } from './iconsTypeMap';

interface ICustomFieldAccessTable {
customFields: {
id: string;
icon: any;
field: string;
view: boolean;
edit: boolean;
}[];
}
export const CustomFieldAccessTable = () => {
const appState = useAppState();

export const CustomFieldAccessTable = ({ customFields }: ICustomFieldAccessTable) => {
const [data, setData] = useState<
{
id: string;
icon: any;
field: string;
view: boolean;
edit: boolean;
}[]
>(customFields);
const updateCustomFieldAccess = (checked: boolean, permission: string, id: string) => {
let customField = appState?.mutableCustomFieldAccess.find((el: any) => el.id === id);
if (checked) {
if (permission === 'VIEW') {
customField = {
...customField,
permission: customField.permission.includes('VIEW') ? customField.permission : [...customField.permission, 'VIEW'],
};
}
if (permission === 'EDIT') {
customField = {
...customField,
permission: customField.permission.includes('EDIT') ? customField.permission : [...customField.permission, 'EDIT'],
};
}
}
if (!checked) {
if (permission === 'VIEW') {
customField = {
...customField,
permission: customField.permission.includes('VIEW') ? [] : customField.permission,
};
}
if (permission === 'EDIT') {
customField = {
...customField,
permission: customField.permission.includes('EDIT')
? customField.permission.filter((item: string) => item !== 'EDIT')
: customField.permission,
};
}
}
let indexToUpdate = appState?.mutableCustomFieldAccess.findIndex((item: any) => item.id === id);
let allCustomFields = appState?.mutableCustomFieldAccess;
allCustomFields[indexToUpdate] = customField;
appState?.setAppState((prev) => ({ ...prev, mutableCustomFieldAccess: allCustomFields }));
};

return (
<>
Expand All @@ -35,18 +58,40 @@ export const CustomFieldAccessTable = ({ customFields }: ICustomFieldAccessTable
</Stack>
</Stack>
<Divider flexItem />
{data.map((field, key) => {
{appState?.mutableCustomFieldAccess.map((field: any, key: number) => {
return (
<Stack direction="row" justifyContent="space-between" alignItems="center" p="8px 0px" key={key}>
<Box minWidth="215px">
<Stack direction="row" alignItems="center" columnGap={2}>
{field.icon}
<Typography variant="bodyMd">{field.field}</Typography>
{iconsTypeMap[field.type]}
<Typography variant="bodyMd">{field.name}</Typography>
</Stack>
</Box>
<Stack direction="row" columnGap={12} alignItems="center">
<StyledCheckBox checked={field.view} handleChange={(c) => {}} />
<StyledCheckBox checked={field.edit} handleChange={(c) => {}} />
<StyledCheckBox
checked={field.permission.includes('VIEW')}
handleChange={(checked) => {
updateCustomFieldAccess(checked, 'VIEW', field.id);
}}
/>
{field.permission.includes('VIEW') ? (
<StyledCheckBox
checked={field.permission.includes('EDIT')}
handleChange={(checked) => {
updateCustomFieldAccess(checked, 'EDIT', field.id);
}}
/>
) : (
<Stack
direction="row"
justifyContent="end"
sx={{
width: '20px',
}}
>
<Typography variant="sm">-</Typography>
</Stack>
)}
</Stack>
</Stack>
);
Expand Down
9 changes: 9 additions & 0 deletions src/components/customFieldAccessTable/iconsTypeMap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { AddressIcon, MultiSelectIcon, PhoneNumberIcon, TextIcon } from '@/icons';

export const iconsTypeMap: any = {
phoneNumber: <PhoneNumberIcon />,
text: <TextIcon />,
multiSelect: <MultiSelectIcon />,
number: <PhoneNumberIcon />,
address: <AddressIcon />,
};
1 change: 1 addition & 0 deletions src/components/styled/SimpleButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export const SimpleButton = styled(Box)(({ theme }) => ({
border: `1px solid ${theme.color.borders.border}`,
background: theme.color.base.white,
cursor: 'pointer',
color: '#212B36',
}));
21 changes: 21 additions & 0 deletions src/components/styled/VariantButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use client';

import { styled, Box } from '@mui/material';

export const VariantButton1 = styled(Box)(({ theme }) => ({
padding: '4px 8px',
borderRadius: theme.shape.radius400,
border: `1px solid ${theme.color.borders.border}`,
background: theme.color.base.white,
cursor: 'pointer',
color: '#212B36',
}));

export const VariantButton2 = styled(Box)(({ theme }) => ({
padding: '4px 8px',
border: '1px solid #212B36',
borderRadius: theme.shape.radius400,
cursor: 'pointer',
background: '#212B36',
color: '#fff',
}));
6 changes: 5 additions & 1 deletion src/components/switch/Switch.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { SwitchIconSelected, SwitchIconUnselected } from '@/icons';
import { Box } from '@mui/material';
import { useState } from 'react';
import { useEffect, useState } from 'react';

export const Switch = ({ selected, getValue }: { selected: boolean; getValue: (selected: boolean) => void }) => {
const [_selected, setSelected] = useState(selected);

useEffect(() => {
setSelected(selected);
}, [selected]);

return (
<Box
onClick={() => {
Expand Down
Loading

0 comments on commit 3236564

Please sign in to comment.