Skip to content

Commit ef927f6

Browse files
Fixes
1 parent c1b826e commit ef927f6

13 files changed

+78
-56
lines changed

backend/core/templatetags/custom_tags.py

+18-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django import template
22
from django.urls import reverse
3-
from urllib.parse import urlparse, urlunparse
3+
from urllib.parse import parse_qs, urlencode, urlparse, urlunparse
44
import math
55

66
register = template.Library()
@@ -47,26 +47,38 @@ def get_display_name(value, mounting_style_options):
4747

4848

4949
@register.filter
50-
def force_https_and_remove_trailing_slash(url):
50+
def force_https_and_clean_canonical(url):
5151
"""
52-
Ensures the URL uses HTTPS and removes the trailing slash if it exists.
52+
Ensures the URL uses HTTPS, includes a trailing slash, and removes unnecessary query parameters.
5353
"""
5454
parsed_url = urlparse(url)
55+
5556
# Force HTTPS
5657
scheme = "https"
57-
# Remove trailing slash
58+
59+
# Ensure trailing slash, except for root "/"
5860
path = parsed_url.path
59-
# Rebuild the URL
61+
if not path.endswith("/") and path != "/":
62+
path += "/"
63+
64+
# Keep only "important" query parameters (modify as needed)
65+
allowed_params = ["lang"] # Add other necessary parameters here
66+
query_dict = parse_qs(parsed_url.query)
67+
cleaned_query = urlencode(
68+
{k: v[0] for k, v in query_dict.items() if k in allowed_params}
69+
)
70+
6071
updated_url = urlunparse(
6172
(
6273
scheme,
6374
parsed_url.netloc,
6475
path,
6576
parsed_url.params,
66-
parsed_url.query,
77+
cleaned_query,
6778
parsed_url.fragment,
6879
)
6980
)
81+
7082
return updated_url
7183

7284

backend/static/js/main.bundle.js

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

backend/static/js/main.bundle.js.gz

6 Bytes
Binary file not shown.

frontend/src/pages/Components.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ const Components: React.FC = () => {
253253
) : (
254254
<a
255255
className="text-blue-500 hover:text-blue-700"
256-
href={`${getBaseUrl()}/components/${row.id}`}
256+
href={`${getBaseUrl()}/components/${row.id}/`}
257257
>
258258
{row.description}
259259
</a>

frontend/src/pages/UserPage.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ const UserPage: React.FC = () => {
140140
</ul>
141141
</li>
142142
<li className="justify-between mt-auto -mx-6">
143-
<Link to="settings">
143+
<Link to="settings/">
144144
<div className="flex items-center px-6 py-3 text-sm font-semibold leading-6 text-gray-900 group/settings gap-x-4 hover:bg-gray-200">
145145
{!!user?.emails?.[0].email ? (
146146
<Gravatar

frontend/src/projects/ModulesList.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ const ModulesList: React.FC<ModulesListProps> = ({
128128
>
129129
<div className="flex justify-center w-full h-64 md:w-48 md:h-48">
130130
{module.slug && (
131-
<Link reloadDocument to={`/projects/${module.slug}`}>
131+
<Link reloadDocument to={`/projects/${module.slug}/`}>
132132
{module.thumb_image_webp && module.thumb_image_jpeg ? (
133133
<picture>
134134
<source
@@ -141,6 +141,7 @@ const ModulesList: React.FC<ModulesListProps> = ({
141141
/>
142142
<LazyImage
143143
alt={module.name}
144+
className=""
144145
src={module.thumb_image_jpeg}
145146
/>
146147
</picture>
@@ -151,7 +152,7 @@ const ModulesList: React.FC<ModulesListProps> = ({
151152
<div className="flex-1 p-4 md:px-4 md:py-5 sm:p-6">
152153
<div className="flex flex-col flex-wrap justify-between w-full md:flex-row">
153154
{module.slug && (
154-
<Link reloadDocument to={`/projects/${module.slug}`}>
155+
<Link reloadDocument to={`/projects/${module.slug}/`}>
155156
<h2 className="text-xl font-medium text-center text-gray-900 md:text-left">
156157
{module.name}
157158
</h2>
@@ -162,7 +163,7 @@ const ModulesList: React.FC<ModulesListProps> = ({
162163
{"by "}
163164
<a
164165
className="text-gray-500 hover:text-gray-400"
165-
href={`/manufacturer/${module.manufacturer_slug}`}
166+
href={`/manufacturer/${module.manufacturer_slug}/`}
166167
>
167168
{module.manufacturer.name}
168169
</a>
@@ -186,7 +187,7 @@ const ModulesList: React.FC<ModulesListProps> = ({
186187
{"by "}
187188
<a
188189
className="text-gray-500 hover:text-gray-400"
189-
href={`/manufacturer/${module.manufacturer_slug}`}
190+
href={`/manufacturer/${module.manufacturer_slug}/`}
190191
>
191192
{module.manufacturer.name}
192193
</a>

frontend/src/services/useGetAllNotes.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ const useGetAllNotes = (moduleType) => {
1919
};
2020

2121
const { data: notes, isLoading, isError } = useQuery({
22-
queryKey: ['userNotes', moduleType],
23-
queryFn: fetchAllNotes,
2422
enabled: !!moduleType,
2523
onError: (error) => {
2624
console.error('Error while fetching notes:', error);
2725
},
26+
queryFn: fetchAllNotes,
27+
queryKey: ['userNotes', moduleType],
2828
});
2929

30-
return { notes, isLoading, isError };
30+
return { isError, isLoading, notes };
3131
};
3232

3333
export default useGetAllNotes;

frontend/src/services/useGetUserAnonymousShoppingListQuantity.js

-29
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { UseQueryResult } from "@tanstack/react-query";
2+
3+
import { useQuery } from "@tanstack/react-query";
4+
5+
import axios from "axios";
6+
import removeAfterUnderscore from "../utils/removeAfterUnderscore";
7+
8+
/**
9+
* Custom React Query hook to fetch the shopping list quantity for an anonymous user.
10+
*
11+
* @param componentPk - The primary key (ID) of the component.
12+
* @returns A React Query result containing the component quantity in the shopping list.
13+
*/
14+
const useGetUserAnonymousShoppingListQuantity = (componentPk: string): UseQueryResult<number, Error> => {
15+
// Ensure `componentPk` is cleaned up before use
16+
const componentPkCleaned = removeAfterUnderscore(String(componentPk));
17+
18+
return useQuery<number, Error>({
19+
enabled: !!componentPkCleaned,
20+
queryFn: async () => {
21+
try {
22+
const response = await axios.get<{ quantity: number }>(
23+
`/api/shopping-list/${componentPkCleaned}/component-quantity/`
24+
);
25+
return response.data.quantity; // Ensuring return type is `number`
26+
} catch (error: any) {
27+
throw new Error(error.response?.data?.error || "Unknown error");
28+
}
29+
},
30+
queryKey: ["userAnonymousInventoryQuantity", componentPkCleaned],
31+
});
32+
};
33+
34+
export default useGetUserAnonymousShoppingListQuantity;

frontend/src/services/useGetUserCurrency.ts

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const useGetUserCurrency = () => {
3939
currency_name: currencyLookup[currency].name,
4040
currency_symbol: currencyLookup[currency].symbol,
4141
};
42+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
4243
} catch (error) {
4344
// Fallback to localStorage
4445
const localCurrency = localStorage.getItem("currency") || "USD";
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,26 @@
1-
import axios from "axios";
1+
import { Module } from "../types/modules";
2+
23
import { useQuery } from "@tanstack/react-query";
34

4-
const useModule = (slug) => {
5-
const { data: module, isLoading: moduleIsLoading, isError: moduleIsError } = useQuery({
6-
queryKey: ["module", slug],
5+
import axios from "axios";
6+
7+
const useModule = (slug: string) => {
8+
const { data: module, isLoading: moduleIsLoading, isError: moduleIsError } = useQuery<Module>({
79
queryFn: async () => {
810
try {
9-
const response = await axios.get(`/api/module/${slug}/`, {
11+
const response = await axios.get<Module>(`/api/module/${slug}/`, {
1012
withCredentials: true,
1113
});
1214
return response.data;
1315
} catch (error) {
1416
console.error("Error fetching data:", error);
1517
throw new Error("Network response was not ok");
1618
}
17-
}
19+
},
20+
queryKey: ["module", slug]
1821
});
1922

20-
return { module, moduleIsLoading, moduleIsError };
23+
return { module, moduleIsError, moduleIsLoading };
2124
};
2225

2326
export default useModule;

frontend/src/ui/RowWarning.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const RowWarning: React.FC<RowWarningProps> = ({
2424
{user_submitted_status === "pending" && (
2525
<Tippy content="This component is a user submission. User submissions are reviewed for accuracy and relevance, typically within 24 hours.">
2626
<div
27-
className="flex justify-center align-middle text-2xl"
27+
className="flex justify-center text-2xl align-middle"
2828
style={{
2929
backgroundColor: "#db2777",
3030
borderRadius: "12px",
@@ -49,7 +49,7 @@ const RowWarning: React.FC<RowWarningProps> = ({
4949
)}
5050
<a
5151
className="text-blue-500 hover:text-blue-700"
52-
href={`${getBaseUrl()}/components/${id}`}
52+
href={`${getBaseUrl()}/components/${id}/`}
5353
>
5454
{children}
5555
</a>

frontend/src/utils/errorBoundary.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const ErrorFallback: React.FC<{
2121
</p>
2222
<a
2323
className="text-sm font-medium text-blue-600 hover:underline"
24-
href="https://github.com/PleatherStarfish/bomsquad/issues"
24+
href="https://github.com/PleatherStarfish/bomsquad/issues/"
2525
rel="noopener noreferrer"
2626
target="_blank"
2727
>

0 commit comments

Comments
 (0)