Skip to content

Commit

Permalink
Remove org in routes (#775)
Browse files Browse the repository at this point in the history
* remove org feature (something different will likely come back later under the same name). All this feature did was ensure that a user's orgs were loaded and store the current org in the browsers URL

* move layout to features directory

* add org loader to layout

* implement new spinner

* replace legacy HtSpinner with Spinner component

* update spinner

* add org select to sidenav
  • Loading branch information
dpgraham4401 authored Aug 20, 2024
1 parent fb69f28 commit 40f6a0a
Show file tree
Hide file tree
Showing 35 changed files with 293 additions and 195 deletions.
4 changes: 2 additions & 2 deletions client/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { HtSpinner } from '~/components/legacyUi';
import { ReactElement, Suspense } from 'react';
import { Container } from 'react-bootstrap';
import { RouterProvider } from 'react-router-dom';
Expand All @@ -9,10 +8,11 @@ import { Notifications } from '~/components/Notifications/Notifications';
import { router } from '~/routes';
import './App.scss';
import './globals.css';
import { Spinner } from './components/ui';

const GlobalSpinner = () => (
<Container fluid className="d-flex justify-content-center align-items-center vh-100">
<HtSpinner size="6x" className="my-auto" />
<Spinner size="sm" className="my-auto" />
</Container>
);

Expand Down
13 changes: 8 additions & 5 deletions client/app/components/Auth/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { HtForm, HtSpinner } from '~/components/legacyUi';

import { FloatingLabel, Form } from 'react-bootstrap';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { HtForm } from '~/components/legacyUi';
import { Spinner } from '~/components/ui/Spinner/Spinner';
import { useAuth } from '~/hooks/useAuth/useAuth';

const loginSchema = z.object({
Expand Down Expand Up @@ -51,10 +52,12 @@ export function LoginForm() {
</FloatingLabel>
<div className="invalid-feedback">{errors.password?.message}</div>
</HtForm.Group>
<button type="submit" disabled={isSubmitting} className="btn btn-primary m-2">
<span>Login </span>
{isLoading && <HtSpinner size="lg" className="text-reset" />}
</button>
<div className="tw-flex tw-items-center tw-gap-5">
<button type="submit" disabled={isSubmitting} className="btn btn-primary">
<span>Login </span>
</button>
<Spinner show={isLoading} size="sm" />
</div>
{error && <div className="alert alert-danger mt-3 mb-0">{error.message}</div>}
</HtForm>
);
Expand Down
4 changes: 0 additions & 4 deletions client/app/components/Layout/index.ts

This file was deleted.

5 changes: 3 additions & 2 deletions client/app/components/Manifest/Generator/GeneratorSection.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ErrorMessage } from '@hookform/error-message';
import { HtButton, HtSpinner } from '~/components/legacyUi';
import React, { useEffect, useState } from 'react';
import { Alert, Button, Col, Stack } from 'react-bootstrap';
import { useFormContext } from 'react-hook-form';
import { useSearchParams } from 'react-router-dom';
import { HtButton } from '~/components/legacyUi';
import { ContactForm, PhoneForm } from '~/components/Manifest/Contact';
import { Handler, Manifest } from '~/components/Manifest/manifestSchema';
import { QuickSignBtn } from '~/components/Manifest/QuickerSign';
import { RcraSiteDetails } from '~/components/RcraSite/RcraSiteDetails';
import { Spinner } from '~/components/ui';
import { useReadOnly } from '~/hooks/manifest';
import { useHandlerSearchConfig } from '~/hooks/manifest/useOpenHandlerSearch/useHandlerSearchConfig';
import { useGetRcrainfoSiteQuery } from '~/store';
Expand Down Expand Up @@ -40,7 +41,7 @@ export function GeneratorSection({ setupSign, signAble }: GeneratorSectionProps)
}, [data]);

if (isLoading) {
return <HtSpinner size="xl" center className="m-5" />;
return <Spinner size="xl" className="m-5" />;
}

if (error) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Badge } from 'react-bootstrap';
import { FaCheck } from 'react-icons/fa';
import { FaXmark } from 'react-icons/fa6';
import { HtSpinner } from '~/components/legacyUi';
import { Spinner } from '~/components/ui';

interface RcrainfoInfoStatusProps {
data: any;
Expand Down Expand Up @@ -40,7 +40,7 @@ export function RcrainfoSiteSearchBadge({
<div className="my-2">
<Badge className="p-2" bg={bg} text={text} pill>
<span>{message}</span>
{isFetching ? <HtSpinner size="lg" /> : error ? <FaXmark /> : data ? <FaCheck /> : <></>}
{isFetching ? <Spinner size="md" /> : error ? <FaXmark /> : data ? <FaCheck /> : <></>}
</Badge>
</div>
);
Expand Down
5 changes: 3 additions & 2 deletions client/app/components/Manifest/Tsdf/TsdfSection.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { ErrorMessage } from '@hookform/error-message';
import { HtButton, HtSpinner } from '~/components/legacyUi';
import React, { useEffect } from 'react';
import { Alert, Col } from 'react-bootstrap';
import { useFormContext } from 'react-hook-form';
import { useSearchParams } from 'react-router-dom';
import { HtButton } from '~/components/legacyUi';
import { Handler, Manifest } from '~/components/Manifest/manifestSchema';
import { QuickSignBtn } from '~/components/Manifest/QuickerSign';
import { RcraSiteDetails } from '~/components/RcraSite/RcraSiteDetails';
import { Spinner } from '~/components/ui';
import { useReadOnly } from '~/hooks/manifest';
import { useHandlerSearchConfig } from '~/hooks/manifest/useOpenHandlerSearch/useHandlerSearchConfig';
import { useGetRcrainfoSiteQuery } from '~/store';
Expand Down Expand Up @@ -37,7 +38,7 @@ export function TsdfSection({ signAble, setupSign }: TsdfSectionProps) {
}, [data]);

if (isLoading) {
return <HtSpinner size="xl" center className="m-5" />;
return <Spinner size="xl" className="tw-m-5" />;
}

if (error) {
Expand Down
4 changes: 2 additions & 2 deletions client/app/components/Manifest/UpdateRcra/UpdateRcra.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HtSpinner } from '~/components/legacyUi';
import React, { useEffect } from 'react';
import { Navigate } from 'react-router-dom';
import { Spinner } from '~/components/ui';
import { addAlert, useAppDispatch, useGetTaskStatusQuery } from '~/store';

interface UpdateRcraProps {
Expand Down Expand Up @@ -47,7 +47,7 @@ export function UpdateRcra({ taskId }: UpdateRcraProps) {
} else {
return (
<div className="overlay-spinner">
<HtSpinner center className="text-light" />
<Spinner className="text-light" />
</div>
);
}
Expand Down
7 changes: 4 additions & 3 deletions client/app/components/RcraProfile/RcraProfile.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { zodResolver } from '@hookform/resolvers/zod';
import { HtForm, HtSpinner } from '~/components/legacyUi';
import React, { useEffect, useState } from 'react';
import { Button, Col, Container, Form, Row, Table } from 'react-bootstrap';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { HtForm } from '~/components/legacyUi';
import { SyncRcrainfoProfileBtn } from '~/components/RcraProfile/SyncRcrainfoProfileBtn';
import { Spinner } from '~/components/ui';
import { useProgressTracker } from '~/hooks';
import { RcrainfoProfileState, useAppDispatch, useUpdateRcrainfoProfileMutation } from '~/store';
import { userApi } from '~/store/userApi/userApi';
Expand Down Expand Up @@ -54,7 +55,7 @@ export function RcraProfile({ profile }: ProfileViewProps) {
updateRcrainfoProfile({ username: profile.user, data: data });
};

if (profile.isLoading) return <HtSpinner center />;
if (profile.isLoading) return <Spinner size="xl" />;

return (
<>
Expand Down Expand Up @@ -130,7 +131,7 @@ export function RcraProfile({ profile }: ProfileViewProps) {
<Container>
<h4>RCRAInfo Sites</h4>
{inProgress ? (
<HtSpinner center />
<Spinner />
) : (
<Table striped bordered hover responsive>
<thead>
Expand Down
7 changes: 4 additions & 3 deletions client/app/components/User/UserInfoForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { Button, Col, Form, Row } from 'react-bootstrap';
import { useForm } from 'react-hook-form';
import { FaUser } from 'react-icons/fa';
import { z } from 'zod';
import { HtForm, HtSpinner } from '~/components/legacyUi';
import { HtForm } from '~/components/legacyUi';
import { Spinner } from '~/components/ui';
import { HaztrakUser, ProfileSlice, useUpdateUserMutation } from '~/store';

interface UserProfileProps {
Expand Down Expand Up @@ -37,7 +38,7 @@ export function UserInfoForm({ user }: UserProfileProps) {
updateUser({ ...user, ...data });
};

if (!user) return <HtSpinner center />;
if (!user) return <Spinner />;

return (
<HtForm onSubmit={handleSubmit(onSubmit)}>
Expand All @@ -56,7 +57,7 @@ export function UserInfoForm({ user }: UserProfileProps) {
onClick={() => fileRef.current?.click()}
className="bg-secondary rounded-circle border-0 shadow"
>
<FaUser size="5x" className="m-3" />
<FaUser size={32} className="m-3" />
</Button>
</div>
<div className="d-flex justify-content-center">
Expand Down
30 changes: 0 additions & 30 deletions client/app/components/legacyUi/HtSpinner.tsx

This file was deleted.

1 change: 0 additions & 1 deletion client/app/components/legacyUi/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export { HtPageControls } from '~/components/legacyUi/HtPaginate/HtPageControls'
export { HtPaginate } from '~/components/legacyUi/HtPaginate/HtPaginate';
export { HtCard } from './HtCard/HtCard';
export { HtModal } from './HtModal/HtModal';
export { HtSpinner } from './HtSpinner';
export { HtTooltip, InfoIconTooltip } from './HtTooltip';
export { FeatureDescription } from './FeatureDescription';
export { FloatingActionBtn } from './FloatingActionBtn';
41 changes: 41 additions & 0 deletions client/app/components/ui/Spinner/Spinner.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { render } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { Spinner } from './Spinner';

describe('Spinner', () => {
it('renders with default size and show true', () => {
const { container } = render(<Spinner />);
expect(container.querySelector('span')).toHaveClass('tw-flex');
expect(container.querySelector('svg')).toHaveClass('tw-animate-spin');
});

it('renders hidden with show false', () => {
const { container } = render(<Spinner show={false} />);
expect(container.querySelector('span')).toHaveClass('tw-hidden');
});

it('renders with custom className', () => {
const { container } = render(<Spinner className="custom-class" />);
expect(container.querySelector('svg')).toHaveClass('custom-class');
});

it('renders children correctly', () => {
const { getByText } = render(<Spinner>Loading...</Spinner>);
expect(getByText('Loading...')).toBeInTheDocument();
});

it('renders asChild when true', () => {
const { container } = render(
<Spinner asChild>
<div>Child Element</div>
</Spinner>
);
expect(container.querySelector('div')).toHaveClass('tw-animate-spin');
expect(container.querySelector('div')).toHaveTextContent('Child Element');
});

it('renders with additional props', () => {
const { container } = render(<Spinner data-testid="spinner-test" />);
expect(container.querySelector('span')).toHaveAttribute('data-testid', 'spinner-test');
});
});
63 changes: 63 additions & 0 deletions client/app/components/ui/Spinner/Spinner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { cva, VariantProps } from 'class-variance-authority';
import * as React from 'react';
import { FaGear } from 'react-icons/fa6';
import { cn } from '~/lib/utils';

const spinnerVariants = cva('tw-flex-col tw-items-center tw-justify-center', {
variants: {
show: {
true: 'tw-flex',
false: 'tw-hidden',
},
},
defaultVariants: {
show: true,
},
});

const loaderVariants = cva('tw-text-reset tw-animate-spin', {
variants: {
size: {
sm: 'tw-size-6',
md: 'tw-size-8',
lg: 'tw-size-24',
xl: 'tw-size-32',
},
},
defaultVariants: {
size: 'md',
},
});

interface SpinnerContentProps
extends VariantProps<typeof spinnerVariants>,
VariantProps<typeof loaderVariants> {
className?: string;
children?: React.ReactNode;
asChild?: boolean;
}

type SpinnerElement = React.ElementRef<'span'>;

const Spinner = React.forwardRef<SpinnerElement, SpinnerContentProps>(
({ size, show, children, className, asChild, ...props }, ref) => {
return (
<span ref={ref} className={cn(spinnerVariants({ show }), className)} {...props}>
{asChild && children ? (
React.cloneElement(children as React.ReactElement, {
className: cn(loaderVariants({ size }), children),
})
) : (
<>
<FaGear className={cn(loaderVariants({ size }), className)} data-testid="spinner" />
{children}
</>
)}
</span>
);
}
);

Spinner.displayName = 'Spinner';

export { Spinner };
2 changes: 2 additions & 0 deletions client/app/components/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ export {
} from '~/components/ui/Sheet/Sheet';

export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from './Card/Card';

export { Spinner } from './Spinner/Spinner';
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { HtSpinner } from '~/components/legacyUi';
import React, { createContext, Dispatch, SetStateAction, Suspense, useState } from 'react';
import { Container } from 'react-bootstrap';
import { Outlet } from 'react-router-dom';
import { LoaderFunction, Outlet } from 'react-router-dom';
import { ErrorBoundary } from '~/components/Error';
import { Spinner } from '~/components/ui';
import { rootStore as store } from '~/store';
import { haztrakApi } from '~/store/htApi.slice';
import { Sidebar } from './Sidebar/Sidebar';
import { TopNav } from './TopNav/TopNav';

Expand All @@ -16,6 +18,15 @@ export const NavContext = createContext<NavContextProps>({
setShowSidebar: () => console.warn('no showSidebar context'),
});

export const rootLoader: LoaderFunction = async () => {
const query = store.dispatch(haztrakApi.endpoints.getOrgs.initiate());

return query
.unwrap()
.catch((_err) => console.error('Error fetching orgs'))
.finally(() => query.unsubscribe());
};

export function Root() {
const [showSidebar, setShowSidebar] = useState(false);
return (
Expand All @@ -25,7 +36,7 @@ export function Root() {
<Sidebar />
<Container fluid className="tw-mt-20">
<ErrorBoundary>
<Suspense fallback={<HtSpinner center className="my-auto" />}>
<Suspense fallback={<Spinner className="my-auto" />}>
<Outlet />
</Suspense>
</ErrorBoundary>
Expand Down
Loading

0 comments on commit 40f6a0a

Please sign in to comment.