Skip to content

Commit 7fa55c3

Browse files
Merge branch 'master' into patch-1
2 parents 3a63030 + 6efd3ba commit 7fa55c3

File tree

15 files changed

+126
-85
lines changed

15 files changed

+126
-85
lines changed

backend/app/tests/api/routes/test_login.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
from unittest.mock import patch
22

33
from fastapi.testclient import TestClient
4-
from sqlmodel import Session, select
4+
from sqlmodel import Session
55

66
from app.core.config import settings
77
from app.core.security import verify_password
8-
from app.models import User
8+
from app.crud import create_user
9+
from app.models import UserCreate
10+
from app.tests.utils.user import user_authentication_headers
11+
from app.tests.utils.utils import random_email, random_lower_string
912
from app.utils import generate_password_reset_token
1013

1114

@@ -69,23 +72,34 @@ def test_recovery_password_user_not_exits(
6972
assert r.status_code == 404
7073

7174

72-
def test_reset_password(
73-
client: TestClient, superuser_token_headers: dict[str, str], db: Session
74-
) -> None:
75-
token = generate_password_reset_token(email=settings.FIRST_SUPERUSER)
76-
data = {"new_password": "changethis", "token": token}
75+
def test_reset_password(client: TestClient, db: Session) -> None:
76+
email = random_email()
77+
password = random_lower_string()
78+
new_password = random_lower_string()
79+
80+
user_create = UserCreate(
81+
email=email,
82+
full_name="Test User",
83+
password=password,
84+
is_active=True,
85+
is_superuser=False,
86+
)
87+
user = create_user(session=db, user_create=user_create)
88+
token = generate_password_reset_token(email=email)
89+
headers = user_authentication_headers(client=client, email=email, password=password)
90+
data = {"new_password": new_password, "token": token}
91+
7792
r = client.post(
7893
f"{settings.API_V1_STR}/reset-password/",
79-
headers=superuser_token_headers,
94+
headers=headers,
8095
json=data,
8196
)
97+
8298
assert r.status_code == 200
8399
assert r.json() == {"message": "Password updated successfully"}
84100

85-
user_query = select(User).where(User.email == settings.FIRST_SUPERUSER)
86-
user = db.exec(user_query).first()
87-
assert user
88-
assert verify_password(data["new_password"], user.hashed_password)
101+
db.refresh(user)
102+
assert verify_password(new_password, user.hashed_password)
89103

90104

91105
def test_reset_password_invalid_token(

frontend/src/components/Admin/EditUser.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ const EditUser = ({ user }: EditUserProps) => {
129129
</Field>
130130

131131
<Field
132-
required
133132
invalid={!!errors.password}
134133
errorText={errors.password?.message}
135134
label="Set Password"
@@ -148,7 +147,6 @@ const EditUser = ({ user }: EditUserProps) => {
148147
</Field>
149148

150149
<Field
151-
required
152150
invalid={!!errors.confirm_password}
153151
errorText={errors.confirm_password?.message}
154152
label="Confirm Password"

frontend/src/components/Common/Navbar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ function Navbar() {
2020
p={4}
2121
>
2222
<Link to="/">
23-
<Image src={Logo} alt="Logo" w="180px" maxW="2xs" px={2} />
23+
<Image src={Logo} alt="Logo" maxW="3xs" p={2} />
2424
</Link>
2525
<Flex gap={2} alignItems="center">
2626
<UserMenu />

frontend/src/components/Common/Sidebar.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ const Sidebar = () => {
2222
const { logout } = useAuth()
2323
const [open, setOpen] = useState(false)
2424

25-
const handleLogout = async () => {
26-
logout()
27-
}
28-
2925
return (
3026
<>
3127
{/* Mobile */}
@@ -48,15 +44,17 @@ const Sidebar = () => {
4844
<FaBars />
4945
</IconButton>
5046
</DrawerTrigger>
51-
<DrawerContent maxW="280px">
47+
<DrawerContent maxW="xs">
5248
<DrawerCloseTrigger />
5349
<DrawerBody>
5450
<Flex flexDir="column" justify="space-between">
5551
<Box>
5652
<SidebarItems />
5753
<Flex
5854
as="button"
59-
onClick={handleLogout}
55+
onClick={() => {
56+
logout()
57+
}}
6058
alignItems="center"
6159
gap={4}
6260
px={4}
@@ -67,7 +65,7 @@ const Sidebar = () => {
6765
</Flex>
6866
</Box>
6967
{currentUser?.email && (
70-
<Text fontSize="sm" p={2}>
68+
<Text fontSize="sm" p={2} truncate maxW="sm">
7169
Logged in as: {currentUser.email}
7270
</Text>
7371
)}
@@ -84,7 +82,7 @@ const Sidebar = () => {
8482
position="sticky"
8583
bg="bg.subtle"
8684
top={0}
87-
minW="280px"
85+
minW="xs"
8886
h="100vh"
8987
p={4}
9088
>

frontend/src/components/Common/UserMenu.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,7 @@ const UserMenu = () => {
1919
<Flex>
2020
<MenuRoot>
2121
<MenuTrigger asChild p={2}>
22-
<Button
23-
data-testid="user-menu"
24-
variant="solid"
25-
maxW="150px"
26-
truncate
27-
>
22+
<Button data-testid="user-menu" variant="solid" maxW="sm" truncate>
2823
<FaUserAstronaut fontSize="18" />
2924
<Text>{user?.full_name || "User"}</Text>
3025
</Button>

frontend/src/components/Pending/PendingItems.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,30 @@
1-
import { Skeleton, Table } from "@chakra-ui/react"
1+
import { Table } from "@chakra-ui/react"
2+
import { SkeletonText } from "../ui/skeleton"
23

34
const PendingItems = () => (
45
<Table.Root size={{ base: "sm", md: "md" }}>
56
<Table.Header>
67
<Table.Row>
7-
<Table.ColumnHeader w="30%">ID</Table.ColumnHeader>
8-
<Table.ColumnHeader w="30%">Title</Table.ColumnHeader>
9-
<Table.ColumnHeader w="30%">Description</Table.ColumnHeader>
10-
<Table.ColumnHeader w="10%">Actions</Table.ColumnHeader>
8+
<Table.ColumnHeader w="sm">ID</Table.ColumnHeader>
9+
<Table.ColumnHeader w="sm">Title</Table.ColumnHeader>
10+
<Table.ColumnHeader w="sm">Description</Table.ColumnHeader>
11+
<Table.ColumnHeader w="sm">Actions</Table.ColumnHeader>
1112
</Table.Row>
1213
</Table.Header>
1314
<Table.Body>
1415
{[...Array(5)].map((_, index) => (
1516
<Table.Row key={index}>
1617
<Table.Cell>
17-
<Skeleton h="20px" />
18+
<SkeletonText noOfLines={1} />
1819
</Table.Cell>
1920
<Table.Cell>
20-
<Skeleton h="20px" />
21+
<SkeletonText noOfLines={1} />
2122
</Table.Cell>
2223
<Table.Cell>
23-
<Skeleton h="20px" />
24+
<SkeletonText noOfLines={1} />
2425
</Table.Cell>
2526
<Table.Cell>
26-
<Skeleton h="20px" />
27+
<SkeletonText noOfLines={1} />
2728
</Table.Cell>
2829
</Table.Row>
2930
))}

frontend/src/components/Pending/PendingUsers.tsx

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
1-
import { Skeleton, Table } from "@chakra-ui/react"
1+
import { Table } from "@chakra-ui/react"
2+
import { SkeletonText } from "../ui/skeleton"
23

34
const PendingUsers = () => (
45
<Table.Root size={{ base: "sm", md: "md" }}>
56
<Table.Header>
67
<Table.Row>
7-
<Table.ColumnHeader w="20%">Full name</Table.ColumnHeader>
8-
<Table.ColumnHeader w="25%">Email</Table.ColumnHeader>
9-
<Table.ColumnHeader w="15%">Role</Table.ColumnHeader>
10-
<Table.ColumnHeader w="20%">Status</Table.ColumnHeader>
11-
<Table.ColumnHeader w="20%">Actions</Table.ColumnHeader>
8+
<Table.ColumnHeader w="sm">Full name</Table.ColumnHeader>
9+
<Table.ColumnHeader w="sm">Email</Table.ColumnHeader>
10+
<Table.ColumnHeader w="sm">Role</Table.ColumnHeader>
11+
<Table.ColumnHeader w="sm">Status</Table.ColumnHeader>
12+
<Table.ColumnHeader w="sm">Actions</Table.ColumnHeader>
1213
</Table.Row>
1314
</Table.Header>
1415
<Table.Body>
1516
{[...Array(5)].map((_, index) => (
1617
<Table.Row key={index}>
1718
<Table.Cell>
18-
<Skeleton h="20px" />
19+
<SkeletonText noOfLines={1} />
1920
</Table.Cell>
2021
<Table.Cell>
21-
<Skeleton h="20px" />
22+
<SkeletonText noOfLines={1} />
2223
</Table.Cell>
2324
<Table.Cell>
24-
<Skeleton h="20px" />
25+
<SkeletonText noOfLines={1} />
2526
</Table.Cell>
2627
<Table.Cell>
27-
<Skeleton h="20px" />
28+
<SkeletonText noOfLines={1} />
2829
</Table.Cell>
2930
<Table.Cell>
30-
<Skeleton h="20px" />
31+
<SkeletonText noOfLines={1} />
3132
</Table.Cell>
3233
</Table.Row>
3334
))}

frontend/src/components/UserSettings/ChangePassword.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,8 @@ const ChangePassword = () => {
4747
<Heading size="sm" py={4}>
4848
Change Password
4949
</Heading>
50-
<Box
51-
w={{ sm: "full", md: "300px" }}
52-
as="form"
53-
onSubmit={handleSubmit(onSubmit)}
54-
>
55-
<VStack gap={4}>
50+
<Box as="form" onSubmit={handleSubmit(onSubmit)}>
51+
<VStack gap={4} w={{ base: "100%", md: "sm" }}>
5652
<PasswordInput
5753
type="current_password"
5854
startElement={<FiLock />}

frontend/src/components/UserSettings/UserInformation.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const UserInformation = () => {
7676
User Information
7777
</Heading>
7878
<Box
79-
w={{ sm: "full", md: "50%" }}
79+
w={{ sm: "full", md: "sm" }}
8080
as="form"
8181
onSubmit={handleSubmit(onSubmit)}
8282
>
@@ -86,15 +86,14 @@ const UserInformation = () => {
8686
{...register("full_name", { maxLength: 30 })}
8787
type="text"
8888
size="md"
89-
w="auto"
9089
/>
9190
) : (
9291
<Text
9392
fontSize="md"
9493
py={2}
9594
color={!currentUser?.full_name ? "gray" : "inherit"}
9695
truncate
97-
maxWidth="250px"
96+
maxW="sm"
9897
>
9998
{currentUser?.full_name || "N/A"}
10099
</Text>
@@ -114,10 +113,9 @@ const UserInformation = () => {
114113
})}
115114
type="email"
116115
size="md"
117-
w="auto"
118116
/>
119117
) : (
120-
<Text fontSize="md" py={2} truncate maxWidth="250px">
118+
<Text fontSize="md" py={2} truncate maxW="sm">
121119
{currentUser?.email}
122120
</Text>
123121
)}

frontend/src/main.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
1-
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
1+
import {
2+
MutationCache,
3+
QueryCache,
4+
QueryClient,
5+
QueryClientProvider,
6+
} from "@tanstack/react-query"
27
import { RouterProvider, createRouter } from "@tanstack/react-router"
3-
import React from "react"
8+
import React, { StrictMode } from "react"
49
import ReactDOM from "react-dom/client"
510
import { routeTree } from "./routeTree.gen"
611

7-
import { StrictMode } from "react"
8-
import { OpenAPI } from "./client"
12+
import { ApiError, OpenAPI } from "./client"
913
import { CustomProvider } from "./components/ui/provider"
1014

1115
OpenAPI.BASE = import.meta.env.VITE_API_URL
1216
OpenAPI.TOKEN = async () => {
1317
return localStorage.getItem("access_token") || ""
1418
}
1519

16-
const queryClient = new QueryClient()
20+
const handleApiError = (error: Error) => {
21+
if (error instanceof ApiError && [401, 403].includes(error.status)) {
22+
localStorage.removeItem("access_token")
23+
window.location.href = "/login"
24+
}
25+
}
26+
const queryClient = new QueryClient({
27+
queryCache: new QueryCache({
28+
onError: handleApiError,
29+
}),
30+
mutationCache: new MutationCache({
31+
onError: handleApiError,
32+
}),
33+
})
1734

1835
const router = createRouter({ routeTree })
1936
declare module "@tanstack/react-router" {

0 commit comments

Comments
 (0)