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

clue/FEE: Implement User and Admin Menu Dropdowns #392 #487

Merged
merged 46 commits into from
Nov 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
8840b9d
finshed implementing admin menu dropdown
Clue355 Aug 28, 2024
270fcad
completed adding tests and edit profile button directs to /admin/edit…
Clue355 Aug 28, 2024
8aacdcd
attempt at fixing errors
Clue355 Aug 28, 2024
b8cd18b
edit to edit profile route
Clue355 Aug 29, 2024
7a38476
added route change function
Clue355 Aug 29, 2024
d4240cc
added more comments and correct return values
Clue355 Aug 29, 2024
a63b39b
added more jsdoc comments to the /user/edit page
Clue355 Aug 29, 2024
0a4555e
small edit to border stlying to look like figma
Clue355 Sep 4, 2024
f43e026
small edit to styling
Clue355 Sep 4, 2024
e44a123
UI/UX: re-implement league entries UI (#468)
ryandotfurrer Sep 4, 2024
711bae3
#496 Chris/Limit-User-Entries (#498)
chris-nowicki Sep 5, 2024
cb516d6
added in code to fetch all leagues (#491)
vmaineng Sep 5, 2024
39b2646
feat #315: Make a selection page updates (#447)
jennifertieu Sep 5, 2024
82d4d38
delete user layout
Clue355 Sep 10, 2024
6d1f156
deleted blank space in api functions
Clue355 Sep 10, 2024
32a0357
Merge branch 'develop' into clue355/implement-menu-dropdown
Clue355 Sep 10, 2024
43ab662
Merge branch 'develop' into clue355/implement-menu-dropdown
Clue355 Sep 10, 2024
1624e58
update
Clue355 Sep 10, 2024
18e7fb9
deleted merge conflics
Clue355 Sep 10, 2024
c7548a4
fixed tests
Clue355 Sep 11, 2024
806ba0c
implemented shashi changes
Clue355 Sep 12, 2024
ab630c7
changes to text hover color
Clue355 Sep 12, 2024
dc96191
Merge branch 'develop' into clue355/implement-menu-dropdown
Clue355 Sep 12, 2024
131ea7c
Update page.test.tsx
Clue355 Sep 16, 2024
ecfe368
added back spaces
Clue355 Sep 16, 2024
1f8af16
added back spaces
Clue355 Sep 16, 2024
bca6971
Merge branch 'develop' of https://github.com/LetsGetTechnical/gridiro…
ryandotfurrer Sep 20, 2024
989eb27
refine stylig of AdminUserSettings component and merge in develop
ryandotfurrer Sep 20, 2024
bbac284
update adminusersettings test
ryandotfurrer Sep 20, 2024
2652962
Merge branch 'develop' into clue355/implement-menu-dropdown
Clue355 Oct 1, 2024
56c16c7
Merge branch 'develop' into clue355/implement-menu-dropdown
Clue355 Oct 7, 2024
930b5ca
change PR to include no tests in adminnav.test
Clue355 Oct 7, 2024
1013bfc
small edit adding back test router mocking
Clue355 Oct 7, 2024
199a109
Merge branch 'develop' into clue355/implement-menu-dropdown
Clue355 Oct 8, 2024
b2ef060
Merge branch 'develop' into clue355/implement-menu-dropdown
shashilo Oct 16, 2024
843c317
Cody/link to profile edit page (#614)
kepsteen Oct 22, 2024
9fb7f34
Merge branch 'develop' into clue355/implement-menu-dropdown
kepsteen Oct 22, 2024
52f9cb4
add logout page
kepsteen Oct 28, 2024
8ba358e
switch sign out button to LinkCustom
kepsteen Oct 29, 2024
1a51303
Merge branch 'develop' into clue355/implement-menu-dropdown
kepsteen Oct 29, 2024
053115e
Merge branch 'develop' into clue355/implement-menu-dropdown
kepsteen Nov 7, 2024
49bb7d8
remove logout page and change link to button
kepsteen Nov 7, 2024
cbad1fe
Merge remote-tracking branch 'origin/develop' into clue355/implement-…
kepsteen Nov 13, 2024
993bd01
throw actual error in handleLogout
kepsteen Nov 13, 2024
83680b5
Merge branch 'develop' into clue355/implement-menu-dropdown
Danielle254 Nov 19, 2024
22393ba
Merge branch 'develop' into clue355/implement-menu-dropdown
Danielle254 Nov 19, 2024
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
23 changes: 22 additions & 1 deletion components/AdminNav/AdminNav.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
import { AdminNav } from './AdminNav';
import { AuthContextProvider } from '@/context/AuthContextProvider';
import { render, screen } from '@testing-library/react';
import React from 'react';

const mockPush = jest.fn();
const mockUsePathname = jest.fn();

jest.mock('next/navigation', () => ({
useRouter() {
return {
push: mockPush,
};
},
usePathname() {
return mockUsePathname();
},
}));
alexappleget marked this conversation as resolved.
Show resolved Hide resolved

describe('AdminNav Component', () => {
beforeEach(() => {
render(<AdminNav />);
jest.clearAllMocks();

render(
<AuthContextProvider>
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: Curious as to why AuthContextProvider is render here like this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it has to do with the nav needing the auth context provider to access certain functions

<AdminNav />
</AuthContextProvider>,
);
});

it('should render the navigation links with correct href attributes', () => {
Expand Down
90 changes: 88 additions & 2 deletions components/AdminUserSettings/AdminUserSettings.test.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,98 @@
import { AdminUserSettings } from './AdminUserSettings';
import { render, screen } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import React from 'react';

const mockPush = jest.fn();
const mockUsePathname = jest.fn();
const mockLogoutAccount = jest.fn();

const mockUseAuthContext = {
logoutAccount: mockLogoutAccount,
};

jest.mock('../../context/AuthContextProvider', () => ({
useAuthContext() {
return {
...mockUseAuthContext,
};
},
}));

jest.mock('next/navigation', () => ({
useRouter() {
return {
push: mockPush,
};
},
usePathname() {
return mockUsePathname();
},
}));

describe('AdminUserSettings Component', () => {
it('should render the component', () => {
beforeEach(() => {
jest.clearAllMocks();

render(<AdminUserSettings />);
});

it('should render the component', async () => {
const adminUserSettings = screen.getByTestId('admin-user-settings');

expect(adminUserSettings).toBeInTheDocument();
});

it('should show user options when clicked', () => {
const adminUserSettings = screen.getByTestId('admin-user-settings');

fireEvent.click(adminUserSettings);

waitFor(() => {
expect(screen.getByTestId('edit-profile-link')).toBeInTheDocument();
expect(screen.getByTestId('sign-out-button')).toBeInTheDocument();
});
});

it('should not show user options when closed', () => {
const adminUserSettings = screen.getByTestId('admin-user-settings');

fireEvent.click(adminUserSettings);

fireEvent.click(adminUserSettings);
choir241 marked this conversation as resolved.
Show resolved Hide resolved

waitFor(() => {
expect(screen.getByTestId('edit-profile-link')).not.toBeInTheDocument();
expect(screen.getByTestId('sign-out-button')).not.toBeInTheDocument();
});
});

it('should direct to /account/settings route when the edit profile button is clicked', () => {
const adminUserSettings = screen.getByTestId('admin-user-settings');

fireEvent.click(adminUserSettings);

waitFor(() => {
const editProfileButton = screen.getByTestId('edit-profile-link');
fireEvent.click(editProfileButton);
});

waitFor(() => {
expect(mockPush).toHaveBeenCalledWith('/account/settings');
});
});

it('should direct to /login route when the sign out button is clicked', () => {
const adminUserSettings = screen.getByTestId('admin-user-settings');

fireEvent.click(adminUserSettings);

waitFor(() => {
const signOutButton = screen.getByTestId('sign-out-button');
fireEvent.click(signOutButton);
});

waitFor(() => {
expect(mockPush).toHaveBeenCalledWith('/login');
});
});
});
80 changes: 65 additions & 15 deletions components/AdminUserSettings/AdminUserSettings.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,75 @@
// Copyright (c) Gridiron Survivor.
// Licensed under the MIT License.

'use client';
import React, { JSX } from 'react';
import { Button } from '../Button/Button';
import { useDataStore } from '@/store/dataStore';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '../TableDropDownMenu/TableDropDownMenu';
import { LucideChevronsUpDown } from 'lucide-react';
import React from 'react';
import { useAuthContext } from '@/context/AuthContextProvider';
import { useRouter } from 'next/navigation';
import LinkCustom from '../LinkCustom/LinkCustom';

/**
* The admin user settings component.
* @returns The rendered admin user settings.
* Renders admin user settings.
* @returns {JSX.Element} The rendered admin user settings component.
*/
export const AdminUserSettings = (): React.JSX.Element => {
export const AdminUserSettings = (): JSX.Element => {
const router = useRouter();
const { logoutAccount } = useAuthContext();
const { user } = useDataStore((state) => state);

/**
* Handles the logout.
* @returns {Promise<void>} The logout promise.
*/
const handleLogout = async (): Promise<void> => {
try {
await logoutAccount();
router.push('/login');
} catch (error) {
throw error;
}
};

return (
<div
className="admin-user-settings flex gap-2 px-2 py-2 items-center outline outline-border rounded text-foreground"
data-testid="admin-user-settings"
>
<span className="bg-cyan-500 w-8 h-8 rounded-full" />
<p>Users Name</p>
<LucideChevronsUpDown
className="ml-auto text-muted-foreground"
size={16}
/>
</div>
<DropdownMenu>
<DropdownMenuTrigger
className="w-56 focus:outline-none mx-auto"
data-testid="admin-user-settings"
>
<div className="admin-user-settings w-full flex space-between gap-2 px-2 py-2 items-center border border-border rounded-lg text-foreground overflow-hidden">
<span className="bg-cyan-500 w-8 h-8 rounded-full" />
<p className="truncate ... w-36 ">{user.email}</p>
<LucideChevronsUpDown className="text-muted-foreground" size={16} />
</div>
</DropdownMenuTrigger>
<DropdownMenuContent className="border border-border rounded-lg p-0 w-56 ">
<DropdownMenuItem className="cursor-pointer rounded-b-none flex focus:bg-muted">
<LinkCustom
shashilo marked this conversation as resolved.
Show resolved Hide resolved
className="text-base no-underline hover:text-foreground w-full py-2 px-0 text-muted-foreground hover:underline"
href="/account/settings"
data-testid="edit-profile-link"
>
Edit Profile
</LinkCustom>
</DropdownMenuItem>
<DropdownMenuItem className="cursor-pointer rounded-none focus:bg-muted">
<Button
className="w-full text-base no-underline py-2 px-0 h-auto text-muted-foreground hover:text-foreground font-normal justify-normal hover:underline"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this a special button that it needs all these different class names? @ryandotfurrer Can we create a new variant for this type of button so we're not setting these classes over again?

Copy link
Member

@ryandotfurrer ryandotfurrer Nov 15, 2024

Choose a reason for hiding this comment

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

Hey @shashilo, By default, shadcn uses a different look that I needed to change to match our design (first screenshot). Shadcn's does not take up the full width (second screenshot).

I reckon we could call this variant something like "DropdownMenuToggleButton" or something along those lines to describe what it should be used for.

Figma design

CleanShot 2024-11-14 at 20 57 33@2x

shadcn default

CleanShot 2024-11-14 at 20 53 30@2x

Copy link
Collaborator

Choose a reason for hiding this comment

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

Let's do that, but in another ticket.

variant="link"
label="Sign Out"
onClick={handleLogout}
data-testid="sign-out-button"
/>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
};