diff --git a/sticker-catalogue/pom.xml b/sticker-catalogue/pom.xml index 4ce03796..bebd0a10 100644 --- a/sticker-catalogue/pom.xml +++ b/sticker-catalogue/pom.xml @@ -18,7 +18,7 @@ UTF-8 quarkus-bom io.quarkus.platform - 3.22.1 + 3.31.3 true 3.5.2 10.18.2 @@ -115,12 +115,12 @@ io.quarkiverse.loggingjson quarkus-logging-json - 3.2.0 + 3.4.1 io.quarkus - quarkus-junit5 + quarkus-junit test @@ -136,7 +136,7 @@ io.quarkus - quarkus-junit5-mockito + quarkus-junit-mockito test @@ -224,6 +224,7 @@ org.jboss.logmanager.LogManager ${maven.home} + @{argLine} @@ -243,6 +244,7 @@ org.jboss.logmanager.LogManager ${maven.home} + @{argLine} diff --git a/sticker-catalogue/src/main/resources/application.properties b/sticker-catalogue/src/main/resources/application.properties index 89272f75..183f14ca 100644 --- a/sticker-catalogue/src/main/resources/application.properties +++ b/sticker-catalogue/src/main/resources/application.properties @@ -14,7 +14,7 @@ quarkus.log.json.fields.mdc.flat-fields=true quarkus.datasource.db-kind=postgresql # Hibernate ORM -quarkus.hibernate-orm.database.generation=validate +quarkus.hibernate-orm.schema-management.strategy=validate quarkus.hibernate-orm.log.sql=true # Flyway diff --git a/sticker-catalogue/src/test/resources/application.properties b/sticker-catalogue/src/test/resources/application.properties index c9bb3e82..6ab1c44a 100644 --- a/sticker-catalogue/src/test/resources/application.properties +++ b/sticker-catalogue/src/test/resources/application.properties @@ -3,7 +3,7 @@ quarkus.datasource.db-kind=postgresql quarkus.datasource.devservices.enabled=true # Test Hibernate ORM configuration -quarkus.hibernate-orm.database.generation=drop-and-create +quarkus.hibernate-orm.schema-management.strategy=drop-and-create quarkus.hibernate-orm.log.sql=true # Disable Flyway for tests diff --git a/web-frontend/src/App.jsx b/web-frontend/src/App.jsx index fc35aef1..a6ef7e1e 100644 --- a/web-frontend/src/App.jsx +++ b/web-frontend/src/App.jsx @@ -7,7 +7,7 @@ import { datadogRum } from '@datadog/browser-rum'; import "./App.css"; function App() { - const { isAuthenticated, isLoading, user } = useAuth(); + const { isAuthenticated, user } = useAuth(); const navigate = useNavigate(); if (isAuthenticated) { @@ -18,18 +18,10 @@ function App() { } useEffect(() => { - if (!isLoading && isAuthenticated) { + if (isAuthenticated) { navigate("/dashboard"); } - }, [isAuthenticated, isLoading, navigate]); - - if (isLoading) { - return ( -
-

Loading...

-
- ); - } + }, [isAuthenticated, navigate]); return (
diff --git a/web-frontend/src/components/StickerDetail.jsx b/web-frontend/src/components/StickerDetail.jsx index 58200996..087b0e4a 100644 --- a/web-frontend/src/components/StickerDetail.jsx +++ b/web-frontend/src/components/StickerDetail.jsx @@ -4,7 +4,6 @@ import LocalPrintshopOutlinedIcon from "@mui/icons-material/LocalPrintshopOutlin import HeaderBar from "./HeaderBar"; import Sidebar from "./Sidebar"; import { API_BASE_URL } from "../config"; -import AuthService from "../services/AuthService"; import { useAuth } from "../context/AuthContext"; import { authFetch } from "../utils/authFetch"; import { getLastActiveEvent } from "../services/eventStorage"; @@ -12,24 +11,13 @@ import { getLastActiveEvent } from "../services/eventStorage"; function StickerDetail() { const { id } = useParams(); const navigate = useNavigate(); - const { user, isLoading: authLoading } = useAuth(); + const { user } = useAuth(); const [sticker, setSticker] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [isOwned, setIsOwned] = useState(false); useEffect(() => { - const userId = user?.sub || user?.email; - - // Validate userId before fetching - if (!userId) { - if (!authLoading) { - setError('Unable to identify user. Please log in again.'); - setLoading(false); - } - return; - } - const controller = new AbortController(); const fetchSticker = async () => { @@ -47,20 +35,14 @@ function StickerDetail() { } const data = await response.json(); - setSticker(data); - - // Check if user owns this sticker - const awardsResponse = await authFetch( - `${API_BASE_URL}/api/awards/v1/assignments/${encodeURIComponent(userId)}` - ); - if (awardsResponse.ok) { - const awardsData = await awardsResponse.json(); - const assignments = awardsData.stickers || []; - setIsOwned(assignments.some((a) => a.stickerId === id)); + if (!controller.signal.aborted) { + setSticker(data); } } catch (err) { console.error("Error fetching sticker:", err); - setError(err.message); + if (!controller.signal.aborted) { + setError(err.message); + } } finally { if (!controller.signal.aborted) { setLoading(false); @@ -69,8 +51,35 @@ function StickerDetail() { }; fetchSticker(); + return () => controller.abort(); }, [id]); + // Check ownership when user context is available + useEffect(() => { + const userId = user?.sub || user?.email; + if (!userId || !sticker) return; + + const controller = new AbortController(); + + const checkOwnership = async () => { + try { + const awardsResponse = await authFetch( + `${API_BASE_URL}/api/awards/v1/assignments/${encodeURIComponent(userId)}` + ); + if (awardsResponse.ok && !controller.signal.aborted) { + const awardsData = await awardsResponse.json(); + const assignments = awardsData.stickers || []; + setIsOwned(assignments.some((a) => a.stickerId === id)); + } + } catch (err) { + console.error("Error checking ownership:", err); + } + }; + + checkOwnership(); + return () => controller.abort(); + }, [id, user, sticker]); + const formatDate = (dateString) => { if (!dateString) return "Unknown"; return new Date(dateString).toLocaleDateString("en-US", { diff --git a/web-frontend/src/components/UserInfo.jsx b/web-frontend/src/components/UserInfo.jsx index 99bc2866..8ac35ca7 100644 --- a/web-frontend/src/components/UserInfo.jsx +++ b/web-frontend/src/components/UserInfo.jsx @@ -28,9 +28,9 @@ function UserInfo() { {isLoading ? "..." - : user?.role?.length - ? user.role.join(", ") - : "No roles assigned"} + : user?.role?.includes("admin") + ? "Sticker Admin" + : "Sticker Collector"}
diff --git a/web-frontend/src/context/AuthContext.jsx b/web-frontend/src/context/AuthContext.jsx index 58fe44c6..0e89037d 100644 --- a/web-frontend/src/context/AuthContext.jsx +++ b/web-frontend/src/context/AuthContext.jsx @@ -119,6 +119,14 @@ export const AuthProvider = ({ children }) => { clearLoginError } + if (isLoading) { + return ( +
+

Loading...

+
+ ) + } + return ( {children}