Skip to content

Commit

Permalink
restructure routes
Browse files Browse the repository at this point in the history
  • Loading branch information
alan2207 committed May 4, 2024
1 parent 17beb80 commit 336214f
Show file tree
Hide file tree
Showing 26 changed files with 153 additions and 166 deletions.
11 changes: 2 additions & 9 deletions e2e/smoke.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ test('smoke', async ({ page }) => {
});

await page.goto('/');
await page.waitForTimeout(1000);
await expect(page.getByRole('heading', { name: 'Bulletproof React' })).toBeVisible();
await page.getByRole('button', { name: 'Get started' }).click();

Expand Down Expand Up @@ -41,10 +40,8 @@ test('smoke', async ({ page }) => {

// log out:
await page.getByRole('button', { name: 'Open user menu' }).click();
await page.getByRole('menuitem', { name: 'Sign out' }).click();
await page.waitForURL('/');
await page.getByRole('button', { name: 'Get started' }).click();
await page.waitForURL('/auth/login');
await page.getByRole('menuitem', { name: 'Sign Out' }).click();
await page.waitForURL('/auth/login?redirectTo=%2Fapp');

// log in:
await page.getByLabel('Email Address').click();
Expand All @@ -57,7 +54,6 @@ test('smoke', async ({ page }) => {
).toBeVisible();

// create discussion:

await page.getByRole('link', { name: 'Discussions' }).click();
await page.waitForURL('/app/discussions');

Expand All @@ -72,13 +68,10 @@ test('smoke', async ({ page }) => {
// visit discussion page:
await page.getByRole('link', { name: 'View' }).click();

// todo: assert the page:
await page.waitForTimeout(1000);
await expect(page.getByRole('heading', { name: discussion.title })).toBeVisible();
await expect(page.getByText(discussion.body)).toBeVisible();

// update discussion:

await page.getByRole('button', { name: 'Update Discussion' }).click();
await page.getByLabel('Title').click();
await page.getByLabel('Title').fill(`${discussion.title} - updated`);
Expand Down
56 changes: 23 additions & 33 deletions src/components/Layout/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,9 @@ const SideNavigation = () => {
);
};

type UserNavigationItem = {
name: string;
to: string;
onClick?: () => void;
};

const UserNavigation = () => {
const { mutate: logout } = useLogout();

const userNavigation = [
{ name: 'Your Profile', to: './profile' },
{
name: 'Sign out',
to: '',
onClick: () => {
logout({});
},
},
].filter(Boolean) as UserNavigationItem[];

return (
<Menu as="div" className="relative ml-3">
{({ open }) => (
Expand All @@ -102,22 +85,29 @@ const UserNavigation = () => {
static
className="absolute right-0 mt-2 w-48 origin-top-right rounded-md bg-white py-1 shadow-lg ring-1 ring-black/5 focus:outline-none"
>
{userNavigation.map((item) => (
<Menu.Item key={item.name}>
{({ active }) => (
<Link
onClick={item.onClick}
to={item.to}
className={clsx(
active ? 'bg-gray-100' : '',
'block px-4 py-2 text-sm text-gray-700'
)}
>
{item.name}
</Link>
)}
</Menu.Item>
))}
<Menu.Item>
{({ active }) => (
<Link
to="./profile"
className={clsx(
active ? 'bg-gray-100' : '',
'block px-4 py-2 text-sm text-gray-700'
)}
>
Your Profile
</Link>
)}
</Menu.Item>
<Menu.Item>
{() => (
<button
onClick={() => logout({})}
className={clsx('block px-4 py-2 text-sm text-gray-700')}
>
Sign Out
</button>
)}
</Menu.Item>
</Menu.Items>
</Transition>
</>
Expand Down
9 changes: 7 additions & 2 deletions src/features/auth/components/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Link } from 'react-router-dom';
import { Link, useSearchParams } from 'react-router-dom';
import * as z from 'zod';

import { Button } from '@/components/Elements';
Expand All @@ -22,6 +22,8 @@ type LoginFormProps = {

export const LoginForm = ({ onSuccess }: LoginFormProps) => {
const login = useLogin();
const [searchParams] = useSearchParams();
const redirectTo = searchParams.get('redirectTo');

return (
<div>
Expand Down Expand Up @@ -56,7 +58,10 @@ export const LoginForm = ({ onSuccess }: LoginFormProps) => {
</Form>
<div className="mt-2 flex items-center justify-end">
<div className="text-sm">
<Link to="../register" className="font-medium text-blue-600 hover:text-blue-500">
<Link
to={`/auth/register${redirectTo ? `?redirectTo=${encodeURIComponent(redirectTo)}` : ''}`}
className="font-medium text-blue-600 hover:text-blue-500"
>
Register
</Link>
</div>
Expand Down
9 changes: 7 additions & 2 deletions src/features/auth/components/RegisterForm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Switch } from '@headlessui/react';
import * as React from 'react';
import { Link } from 'react-router-dom';
import { Link, useSearchParams } from 'react-router-dom';
import * as z from 'zod';

import { Button } from '@/components/Elements';
Expand Down Expand Up @@ -40,6 +40,8 @@ type RegisterFormProps = {
export const RegisterForm = ({ onSuccess }: RegisterFormProps) => {
const registering = useRegister();
const [chooseTeam, setChooseTeam] = React.useState(false);
const [searchParams] = useSearchParams();
const redirectTo = searchParams.get('redirectTo');

const teamsQuery = useTeams({
config: {
Expand Down Expand Up @@ -133,7 +135,10 @@ export const RegisterForm = ({ onSuccess }: RegisterFormProps) => {
</Form>
<div className="mt-2 flex items-center justify-end">
<div className="text-sm">
<Link to="../login" className="font-medium text-blue-600 hover:text-blue-500">
<Link
to={`/auth/login${redirectTo ? `?redirectTo=${encodeURIComponent(redirectTo)}` : ''}`}
className="font-medium text-blue-600 hover:text-blue-500"
>
Log In
</Link>
</div>
Expand Down
4 changes: 3 additions & 1 deletion src/features/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export * from './lib/auth';
export * from './lib/authorization';
export * from './lib/protected-route';

export * from './routes';
export * from './routes/Register';
export * from './routes/Login';

export * from './types';
2 changes: 1 addition & 1 deletion src/features/auth/lib/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ async function registerFn(data: RegisterCredentialsDTO) {

async function logoutFn() {
await logout();
window.location.assign(window.location.origin as unknown as string);
// window.location.assign(window.location.origin as unknown as string);
}

const authConfig = {
Expand Down
16 changes: 16 additions & 0 deletions src/features/auth/lib/protected-route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Navigate, useLocation } from 'react-router-dom';

import { useUser } from './auth';

export const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
const user = useUser();
const location = useLocation();

if (!user.data) {
return (
<Navigate to={`/auth/login?redirectTo=${encodeURIComponent(location.pathname)}`} replace />
);
}

return children;
};
10 changes: 7 additions & 3 deletions src/features/auth/routes/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { useNavigate } from 'react-router-dom';
import { useNavigate, useSearchParams } from 'react-router-dom';

import { Layout } from '../components/Layout';
import { LoginForm } from '../components/LoginForm';

export const Login = () => {
export const LoginRoute = () => {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const redirectTo = searchParams.get('redirectTo');

return (
<Layout title="Log in to your account">
<LoginForm onSuccess={() => navigate('/app')} />
<LoginForm
onSuccess={() => navigate(`${redirectTo ? `${redirectTo}` : '/app'}`, { replace: true })}
/>
</Layout>
);
};
10 changes: 7 additions & 3 deletions src/features/auth/routes/Register.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { useNavigate } from 'react-router-dom';
import { useNavigate, useSearchParams } from 'react-router-dom';

import { Layout } from '../components/Layout';
import { RegisterForm } from '../components/RegisterForm';

export const Register = () => {
export const RegisterRoute = () => {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const redirectTo = searchParams.get('redirectTo');

return (
<Layout title="Register your account">
<RegisterForm onSuccess={() => navigate('/app')} />
<RegisterForm
onSuccess={() => navigate(`${redirectTo ? `${redirectTo}` : '/app'}`, { replace: true })}
/>
</Layout>
);
};
13 changes: 0 additions & 13 deletions src/features/auth/routes/index.tsx

This file was deleted.

3 changes: 2 additions & 1 deletion src/features/discussions/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './types';
export * from './routes';
export * from './routes/Discussion';
export * from './routes/Discussions';
2 changes: 1 addition & 1 deletion src/features/discussions/routes/Discussion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { formatDate } from '@/utils/format';
import { useDiscussion } from '../api/getDiscussion';
import { UpdateDiscussion } from '../components/UpdateDiscussion';

export const Discussion = () => {
export const DiscussionRoute = () => {
const params = useParams();
const discussionId = params.discussionId as string;
const discussionQuery = useDiscussion({ discussionId });
Expand Down
2 changes: 1 addition & 1 deletion src/features/discussions/routes/Discussions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ContentLayout } from '@/components/Layout';
import { CreateDiscussion } from '../components/CreateDiscussion';
import { DiscussionsList } from '../components/DiscussionsList';

export const Discussions = () => {
export const DiscussionsRoute = () => {
return (
<ContentLayout title="Discussions">
<div className="flex justify-end">
Expand Down
4 changes: 2 additions & 2 deletions src/features/discussions/routes/__tests__/Discussion.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
within,
} from '@/test/test-utils';

import { Discussion } from '../Discussion';
import { DiscussionRoute } from '../Discussion';

vi.mock('react-router-dom', () => ({
...vi.importActual('react-router-dom'), // keep the rest of the exports intact
Expand All @@ -27,7 +27,7 @@ const renderDiscussion = async () => {
discussionId: fakeDiscussion.id,
}));

const utils = await renderApp(<Discussion />, {
const utils = await renderApp(<DiscussionRoute />, {
user: fakeUser,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { discussionGenerator } from '@/test/data-generators';
import { renderApp, screen, userEvent, waitFor, within } from '@/test/test-utils';
import { formatDate } from '@/utils/format';

import { Discussions } from '../Discussions';
import { DiscussionsRoute } from '../Discussions';

beforeAll(() => {
vi.spyOn(console, 'error').mockImplementation(() => {});
Expand All @@ -15,7 +15,7 @@ afterAll(() => {
});

test('should create, render and delete discussions', async () => {
await renderApp(<Discussions />);
await renderApp(<DiscussionsRoute />);

const newDiscussion = discussionGenerator();

Expand Down
14 changes: 0 additions & 14 deletions src/features/discussions/routes/index.tsx

This file was deleted.

4 changes: 3 additions & 1 deletion src/features/misc/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './routes';
export * from './routes/Landing';
export * from './routes/NotFound';
export * from './routes/Dashboard';
2 changes: 1 addition & 1 deletion src/features/misc/routes/Dashboard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ContentLayout } from '@/components/Layout';
import { useUser, ROLES } from '@/features/auth';

export const Dashboard = () => {
export const DashboardRoute = () => {
const user = useUser();
return (
<ContentLayout title="Dashboard">
Expand Down
2 changes: 1 addition & 1 deletion src/features/misc/routes/Landing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Button } from '@/components/Elements';
import { Head } from '@/components/Head';
import { useUser } from '@/features/auth';

export const Landing = () => {
export const LandingRoute = () => {
const navigate = useNavigate();
const user = useUser();

Expand Down
14 changes: 12 additions & 2 deletions src/features/misc/routes/NotFound.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
export const NotFound = () => {
return <div>404</div>;
import { Link } from '@/components/Elements';

export const NotFoundRoute = () => {
return (
<div className="mt-52 flex flex-col items-center font-semibold">
<h1>404 - Not Found</h1>
<p>Sorry, the page you are looking for does not exist.</p>
<Link to="/" replace>
Go to Home
</Link>
</div>
);
};
3 changes: 0 additions & 3 deletions src/features/misc/routes/index.tsx

This file was deleted.

2 changes: 1 addition & 1 deletion src/features/users/routes/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Entry = ({ label, value }: EntryProps) => (
</div>
);

export const Profile = () => {
export const ProfileRoute = () => {
const user = useUser();

if (!user.data) return null;
Expand Down
Loading

0 comments on commit 336214f

Please sign in to comment.