Skip to content

Commit

Permalink
Merge pull request #102 from jadeallencook/feat/form-toggle
Browse files Browse the repository at this point in the history
feat: added basic components for form toggling
  • Loading branch information
jadeallencook authored Dec 1, 2023
2 parents af03c6a + 98a7cd8 commit 4c3f8a1
Show file tree
Hide file tree
Showing 10 changed files with 266 additions and 72 deletions.
16 changes: 16 additions & 0 deletions src/api/get-form-status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { child, get, getDatabase, ref } from 'firebase/database';

const dbRef = ref(getDatabase());

const getFormStatus = async (): Promise<boolean> => {
try {
return await get(child(dbRef, 'requestFormStatus')).then((snapshot) =>
snapshot.exists() ? snapshot.val() : false
);
} catch (err) {
console.log(err);
return null;
}
};

export default getFormStatus;
8 changes: 8 additions & 0 deletions src/api/update-form-status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { getDatabase, ref, set } from 'firebase/database';

const updateFormStatus = async (status: boolean) => {
const db = getDatabase();
return await set(ref(db, 'requestFormStatus'), status);
};

export default updateFormStatus;
35 changes: 35 additions & 0 deletions src/contexts/RequestFormStatusContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { createContext, useEffect, useState } from 'react';
import getFormStatus from '@api/get-form-status';

interface RequestFormStatusContext {}

const RequestFormStatusContext = createContext<{
requestFormStatus: boolean;
hasFetchedRequestFormStatus: boolean;
}>(null);

export const RequestFormStatusProvider = ({ children }) => {
const [hasFetchedRequestFormStatus, setHasFetchedRequestFormStatus] =
useState<boolean>(false);
const [requestFormStatus, setRequestFormStatus] = useState<boolean>(false);

useEffect(() => {
getFormStatus().then((response) => {
setRequestFormStatus(response);
setHasFetchedRequestFormStatus(true);
});
}, []);

return (
<RequestFormStatusContext.Provider
value={{
requestFormStatus,
hasFetchedRequestFormStatus,
}}
>
{children}
</RequestFormStatusContext.Provider>
);
};

export default RequestFormStatusContext;
5 changes: 4 additions & 1 deletion src/forms/AdvancedSearchForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ const AdvancedSearchForm: StyledComponent = styled(
className,
filters,
setFilters,
children,
}: {
className: string;
filters: FiltersInterface;
setFilters: (value: FiltersInterface) => void;
children?: React.ReactNode;
}) => {
const [term, setTerm] = useState<string>('');
const handleSearch = (e) => {
Expand All @@ -23,7 +25,7 @@ const AdvancedSearchForm: StyledComponent = styled(

return (
<Form className={className}>
<InputGroup>
<InputGroup size="sm">
<Form.Control
type="text"
name="driver"
Expand All @@ -32,6 +34,7 @@ const AdvancedSearchForm: StyledComponent = styled(
placeholder="Search by name or email"
onChange={handleSearch}
/>
{children}
</InputGroup>
</Form>
);
Expand Down
4 changes: 4 additions & 0 deletions src/forms/AdvancedSearchForm/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ const style = () => ({
},
'.input-group-text': {
backgroundColor: 'var(--bs-gray-600)',
color: 'var(--white)',
border: 'none',
},
'button.search-btn': {
backgroundColor: 'var(--black) !important',
border: 'none',
},
'.bg-danger': {
backgroundColor: 'var(--primary) !important',
},
});

export default style;
66 changes: 66 additions & 0 deletions src/forms/FormStatusForm/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { Badge, InputGroup, Spinner } from 'react-bootstrap';
import updateFormStatus from '@api/update-form-status';
import getFormStatus from '@api/get-form-status';
import { useQuery } from 'react-query';

const FormStatusForm = () => {
const { data: status, refetch } = useQuery({
queryKey: ['getFormStatus'],
queryFn: () => getFormStatus(),
});

const handleToggle = async () => {
await updateFormStatus(!status);
await refetch();
};

return (
<>
{status !== undefined && (
<InputGroup.Checkbox
checked={status}
aria-label=""
onChange={handleToggle}
style={{ cursor: 'pointer' }}
/>
)}
<InputGroup.Text>
{status === undefined ? (
<>
<Spinner
as="span"
animation="border"
size="sm"
role="status"
aria-hidden="true"
style={{ marginRight: '15px' }}
/>
Getting Request Form Status
</>
) : (
<>
{' '}
Request Form Status{' '}
{status ? (
<Badge
bg="danger"
style={{ marginLeft: '5px', width: '50px' }}
>
Live
</Badge>
) : (
<Badge
bg="dark"
style={{ marginLeft: '5px', width: '50px' }}
>
Offline
</Badge>
)}
</>
)}
</InputGroup.Text>
</>
);
};

export default FormStatusForm;
101 changes: 56 additions & 45 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
QueryClientProvider,
} from 'react-query';
import { DashboardProvider, log } from './contexts/DashboardContext';
import { RequestFormStatusProvider } from './contexts/RequestFormStatusContext';
import toast, { ToastBar, Toaster } from 'react-hot-toast';
import { Button } from 'react-bootstrap';

Expand Down Expand Up @@ -50,51 +51,61 @@ const queryClient = new QueryClient({
});

root.render(
<SnippetProvider>
<QueryClientProvider client={queryClient}>
<Router>
<DashboardProvider>
<Navigation />
<Routes>
{routes.map(({ path, element }) => (
<Route
key={path}
path={path}
element={element}
></Route>
))}
</Routes>
<Footer />
</DashboardProvider>
</Router>
<RequestFormStatusProvider>
<SnippetProvider>
<QueryClientProvider client={queryClient}>
<Router>
<DashboardProvider>
<Navigation />
<Routes>
{routes.map(({ path, element }) => (
<Route
key={path}
path={path}
element={element}
></Route>
))}
</Routes>
<Footer />
</DashboardProvider>
</Router>

<Toaster
position="bottom-center"
toastOptions={{
duration:
process.env.NODE_ENV === 'development' ? 1000000 : 5000,
style: { maxWidth: 'unset' },
}}
>
{(t) => (
<ToastBar toast={t}>
{({ icon, message }) => (
<div
className={'d-flex flex-row align-items-center'}
>
{icon}
<div style={{ width: '12rem' }}>{message}</div>
<Toaster
position="bottom-center"
toastOptions={{
duration:
process.env.NODE_ENV === 'development'
? 1000000
: 5000,
style: { maxWidth: 'unset' },
}}
>
{(t) => (
<ToastBar toast={t}>
{({ icon, message }) => (
<div
className={
'd-flex flex-row align-items-center'
}
>
{icon}
<div style={{ width: '12rem' }}>
{message}
</div>

{t.type !== 'loading' && (
<Button onClick={() => toast.dismiss(t.id)}>
Dismiss
</Button>
)}
</div>
)}
</ToastBar>
)}
</Toaster>
</QueryClientProvider>
</SnippetProvider>
{t.type !== 'loading' && (
<Button
onClick={() => toast.dismiss(t.id)}
>
Dismiss
</Button>
)}
</div>
)}
</ToastBar>
)}
</Toaster>
</QueryClientProvider>
</SnippetProvider>
</RequestFormStatusProvider>
);
20 changes: 17 additions & 3 deletions src/pages/Dashboard/AidRequestsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,30 @@ import { useContext, useState } from 'react';
import DashboardContext from '../../contexts/DashboardContext';
import Loading from '@components/Loading';
import filterRequests from '@utils/filter-requests';
import FormStatusForm from '@forms/FormStatusForm';
import isUserModerator from '@utils/is-user-moderator';
import AdvancedSearchForm from '@forms/AdvancedSearchForm';

const AidRequestsPage = () => {
const { requests, isLoading, requestFilters, setRequestFilters, uid } =
useContext(DashboardContext);
const {
requests,
isLoading,
requestFilters,
setRequestFilters,
uid,
myOrganizations,
organizations,
} = useContext(DashboardContext);
const [show, setShow] = useState<boolean>(false);
const [selected, setSelected] = useState<string>();
const handler = (id?: string): void => {
setSelected(id);
setShow((prev) => !prev);
};

const isMod =
!isLoading && isUserModerator(uid, myOrganizations, organizations);

const filteredRequests = filterRequests(requests, requestFilters);

return (
Expand All @@ -28,7 +40,9 @@ const AidRequestsPage = () => {
<AdvancedSearchForm
filters={requestFilters}
setFilters={setRequestFilters}
/>
>
{isMod && <FormStatusForm />}
</AdvancedSearchForm>
{isLoading ? (
<Loading />
) : (
Expand Down
Loading

1 comment on commit 4c3f8a1

@vercel
Copy link

@vercel vercel bot commented on 4c3f8a1 Dec 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.