From b8b75dd8e2303b85789d0ba05020980ae11d7b4b Mon Sep 17 00:00:00 2001 From: belledw Date: Sun, 1 Feb 2026 05:31:13 +0000 Subject: [PATCH 01/15] Adding backend support for fetching games by their contributors (WIP) --- server/game_dev/serializers.py | 50 ++++++++++++++++++++++++++++++---- server/game_dev/urls.py | 6 ++-- server/game_dev/views.py | 14 ++++++++-- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/server/game_dev/serializers.py b/server/game_dev/serializers.py index a9e5c811..1cfa6d95 100644 --- a/server/game_dev/serializers.py +++ b/server/game_dev/serializers.py @@ -18,7 +18,8 @@ class Meta: # This is child serializer of GameSerializer class GameContributorSerializer(serializers.ModelSerializer): - member_id = serializers.IntegerField(source="member.id") # to link contributors to their member/[id] page + # to link contributors to their member/[id] page + member_id = serializers.IntegerField(source="member.id") name = serializers.CharField(source="member.name") class Meta: @@ -35,7 +36,8 @@ class GamesSerializer(serializers.ModelSerializer): class Meta: model = Game - fields = ('id', 'name', 'description', 'completion', 'active', 'hostURL', 'itchEmbedID', 'thumbnail', 'event', "contributors") + fields = ('id', 'name', 'description', 'completion', 'active', + 'hostURL', 'itchEmbedID', 'thumbnail', 'event', "contributors") # Contributor serializer for name and role @@ -54,13 +56,16 @@ class Meta: class GameshowcaseSerializer(serializers.ModelSerializer): game_id = serializers.IntegerField(source='game.id', read_only=True) game_name = serializers.CharField(source='game.name', read_only=True) - game_description = serializers.CharField(source='game.description', read_only=True) - game_cover_thumbnail = serializers.ImageField(source='game.thumbnail', read_only=True) + game_description = serializers.CharField( + source='game.description', read_only=True) + game_cover_thumbnail = serializers.ImageField( + source='game.thumbnail', read_only=True) contributors = serializers.SerializerMethodField() class Meta: model = GameShowcase - fields = ('game_id', 'game_name', 'game_description', 'description', 'contributors', 'game_cover_thumbnail') + fields = ('game_id', 'game_name', 'game_description', + 'description', 'contributors', 'game_cover_thumbnail') def get_contributors(self, obj): # Always fetch contributors from GameContributor for the related game @@ -68,6 +73,41 @@ def get_contributors(self, obj): return ShowcaseContributorSerializer(contributors, many=True).data +class ContributorGameInfoSerializer(serializers.ModelSerializer): + + class Meta: + model = Game + fields = ('name', 'thumbnail', + 'description') + + +class ContributorGameSerializer(serializers.ModelSerializer): + game_id = serializers.IntegerField(source='game.id', read_only=True) + game_data = serializers.SerializerMethodField() + + class Meta: + model = GameContributor + fields = ['game_id', 'game_data'] + + def get_game_data(self, obj): + game_data = Game.objects.get(id=obj.game_id) + return ContributorGameInfoSerializer(game_data).data + + +class ContributorGamesListSerializer(serializers.ModelSerializer): + member = serializers.IntegerField( + source='GameContributor.member', read_only=True) + games = serializers.SerializerMethodField() + + class Meta: + model = GameContributor + fields = ('member', 'games') + + def get_games(self, obj): + games = GameContributor.objects.filter(member=obj.member) + return ContributorGameSerializer(games, many=True).data + + class MemberSerializer(serializers.ModelSerializer): class Meta: model = Member diff --git a/server/game_dev/urls.py b/server/game_dev/urls.py index 1e7f682b..c19abf1d 100644 --- a/server/game_dev/urls.py +++ b/server/game_dev/urls.py @@ -1,10 +1,12 @@ from django.urls import path -from .views import EventListAPIView, EventDetailAPIView, GamesDetailAPIView, GameshowcaseAPIView, MemberAPIView +from .views import EventListAPIView, EventDetailAPIView, GamesDetailAPIView, GameshowcaseAPIView, MemberAPIView, MemberGameAPIView urlpatterns = [ path("events/", EventListAPIView.as_view(), name="events-list"), path("events//", EventDetailAPIView.as_view()), path("games//", GamesDetailAPIView.as_view()), - path("gameshowcase/", GameshowcaseAPIView.as_view(), name="gameshowcase-api"), # Updated line for GameShowcase endpoint + path("games/contributor/", MemberGameAPIView.as_view()), + # Updated line for GameShowcase endpoint + path("gameshowcase/", GameshowcaseAPIView.as_view(), name="gameshowcase-api"), path('members//', MemberAPIView.as_view()) ] diff --git a/server/game_dev/views.py b/server/game_dev/views.py index d78482c4..741262dd 100644 --- a/server/game_dev/views.py +++ b/server/game_dev/views.py @@ -1,6 +1,6 @@ from rest_framework import generics -from .serializers import GamesSerializer, GameshowcaseSerializer, EventSerializer, MemberSerializer -from .models import Game, GameShowcase, Event, Member +from .serializers import ContributorGamesListSerializer, GamesSerializer, GameshowcaseSerializer, EventSerializer, MemberSerializer +from .models import Game, GameContributor, GameShowcase, Event, Member from django.utils import timezone from rest_framework.views import APIView from rest_framework.response import Response @@ -70,6 +70,16 @@ def get(self, request): return Response(serializer.data) +class MemberGameAPIView(APIView): + lookup_url_kwarg = "member" + + def get(self, request, member): + contributions = GameContributor.objects.filter( + member=self.kwargs["member"]) + serializer = ContributorGamesListSerializer(contributions, many=True) + return Response(serializer.data) + + class MemberAPIView(generics.RetrieveAPIView): serializer_class = MemberSerializer lookup_field = "id" From 894a048c62c32d6111c1d0607284e7162e77cc3c Mon Sep 17 00:00:00 2001 From: belledw Date: Sun, 1 Feb 2026 05:41:16 +0000 Subject: [PATCH 02/15] Added backend support for fetching games by their contributors --- server/game_dev/serializers.py | 21 ++++----------------- server/game_dev/urls.py | 5 +++-- server/game_dev/views.py | 6 +++--- 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/server/game_dev/serializers.py b/server/game_dev/serializers.py index 1cfa6d95..531e72dd 100644 --- a/server/game_dev/serializers.py +++ b/server/game_dev/serializers.py @@ -73,7 +73,7 @@ def get_contributors(self, obj): return ShowcaseContributorSerializer(contributors, many=True).data -class ContributorGameInfoSerializer(serializers.ModelSerializer): +class ContributorGameDataSerializer(serializers.ModelSerializer): class Meta: model = Game @@ -83,29 +83,16 @@ class Meta: class ContributorGameSerializer(serializers.ModelSerializer): game_id = serializers.IntegerField(source='game.id', read_only=True) + role = serializers.CharField(read_only=True) game_data = serializers.SerializerMethodField() class Meta: model = GameContributor - fields = ['game_id', 'game_data'] + fields = ['game_id', 'role', 'game_data'] def get_game_data(self, obj): game_data = Game.objects.get(id=obj.game_id) - return ContributorGameInfoSerializer(game_data).data - - -class ContributorGamesListSerializer(serializers.ModelSerializer): - member = serializers.IntegerField( - source='GameContributor.member', read_only=True) - games = serializers.SerializerMethodField() - - class Meta: - model = GameContributor - fields = ('member', 'games') - - def get_games(self, obj): - games = GameContributor.objects.filter(member=obj.member) - return ContributorGameSerializer(games, many=True).data + return ContributorGameDataSerializer(game_data).data class MemberSerializer(serializers.ModelSerializer): diff --git a/server/game_dev/urls.py b/server/game_dev/urls.py index c19abf1d..16ee3bcd 100644 --- a/server/game_dev/urls.py +++ b/server/game_dev/urls.py @@ -1,11 +1,12 @@ from django.urls import path -from .views import EventListAPIView, EventDetailAPIView, GamesDetailAPIView, GameshowcaseAPIView, MemberAPIView, MemberGameAPIView +from .views import ContributorGamesListAPIView, EventListAPIView, EventDetailAPIView, GamesDetailAPIView, GameshowcaseAPIView, MemberAPIView urlpatterns = [ path("events/", EventListAPIView.as_view(), name="events-list"), path("events//", EventDetailAPIView.as_view()), path("games//", GamesDetailAPIView.as_view()), - path("games/contributor/", MemberGameAPIView.as_view()), + path("games/contributor/", + ContributorGamesListAPIView.as_view()), # Updated line for GameShowcase endpoint path("gameshowcase/", GameshowcaseAPIView.as_view(), name="gameshowcase-api"), path('members//', MemberAPIView.as_view()) diff --git a/server/game_dev/views.py b/server/game_dev/views.py index 741262dd..c9b1d754 100644 --- a/server/game_dev/views.py +++ b/server/game_dev/views.py @@ -1,5 +1,5 @@ from rest_framework import generics -from .serializers import ContributorGamesListSerializer, GamesSerializer, GameshowcaseSerializer, EventSerializer, MemberSerializer +from .serializers import ContributorGameSerializer, GamesSerializer, GameshowcaseSerializer, EventSerializer, MemberSerializer from .models import Game, GameContributor, GameShowcase, Event, Member from django.utils import timezone from rest_framework.views import APIView @@ -70,13 +70,13 @@ def get(self, request): return Response(serializer.data) -class MemberGameAPIView(APIView): +class ContributorGamesListAPIView(APIView): lookup_url_kwarg = "member" def get(self, request, member): contributions = GameContributor.objects.filter( member=self.kwargs["member"]) - serializer = ContributorGamesListSerializer(contributions, many=True) + serializer = ContributorGameSerializer(contributions, many=True) return Response(serializer.data) From 5867c237f64b254ced8222632c8a4f3735437108 Mon Sep 17 00:00:00 2001 From: belledw Date: Sun, 1 Feb 2026 06:24:01 +0000 Subject: [PATCH 03/15] Added hook to fetch game data from backend by contributor id --- client/src/hooks/useContributor.ts | 26 ++++++++++++++++++++++++++ server/game_dev/urls.py | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 client/src/hooks/useContributor.ts diff --git a/client/src/hooks/useContributor.ts b/client/src/hooks/useContributor.ts new file mode 100644 index 00000000..bdd831d5 --- /dev/null +++ b/client/src/hooks/useContributor.ts @@ -0,0 +1,26 @@ +import { useQuery } from "@tanstack/react-query"; + +import api from "@/lib/api"; + +type ApiContributorGameData = { + name: string; + thumbnail: string; + description: string; +}; + +type ApiContributorGamesList = { + game_id: number; + role: string; + game_data: ApiContributorGameData; +}; + +export const useContributor = (member: number) => { + return useQuery({ + queryKey: ["contributor", member], + queryFn: async () => { + const response = await api.get(`/games/contributor/${member}/`); + return response.data; + }, + enabled: !!member, + }); +}; diff --git a/server/game_dev/urls.py b/server/game_dev/urls.py index 16ee3bcd..179afef8 100644 --- a/server/game_dev/urls.py +++ b/server/game_dev/urls.py @@ -5,7 +5,7 @@ path("events/", EventListAPIView.as_view(), name="events-list"), path("events//", EventDetailAPIView.as_view()), path("games//", GamesDetailAPIView.as_view()), - path("games/contributor/", + path("games/contributor//", ContributorGamesListAPIView.as_view()), # Updated line for GameShowcase endpoint path("gameshowcase/", GameshowcaseAPIView.as_view(), name="gameshowcase-api"), From 5eb4f8321eb622848151e4f67d8ea48192266c2a Mon Sep 17 00:00:00 2001 From: belledw Date: Sun, 1 Feb 2026 07:47:55 +0000 Subject: [PATCH 04/15] Project section in Member Profile Page now fetches data from backend --- client/src/components/main/MemberProfile.tsx | 17 +--- .../components/ui/MemberProjectSection.tsx | 80 +++++++++++++++++++ client/src/hooks/useContributor.ts | 5 +- 3 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 client/src/components/ui/MemberProjectSection.tsx diff --git a/client/src/components/main/MemberProfile.tsx b/client/src/components/main/MemberProfile.tsx index 8d25ffc3..16268d8d 100644 --- a/client/src/components/main/MemberProfile.tsx +++ b/client/src/components/main/MemberProfile.tsx @@ -2,6 +2,8 @@ import Image from "next/image"; +import MemberProjectSection from "../ui/MemberProjectSection"; + // unused atm, as the member isnt linked a project on the backend /* export type MemberProfileProject = { id: string; @@ -74,20 +76,7 @@ export function MemberProfile({ member }: MemberProfileProps) { {/* Template for Projects section */}

Projects

-
- {/* Div below is a single project card */} -
-
- {/* Image and/or Link to Project */} -
-

- {/* Project Title */} -

-

- {/* Project description */} -

-
-
+
); diff --git a/client/src/components/ui/MemberProjectSection.tsx b/client/src/components/ui/MemberProjectSection.tsx new file mode 100644 index 00000000..dd91ded3 --- /dev/null +++ b/client/src/components/ui/MemberProjectSection.tsx @@ -0,0 +1,80 @@ +import Image from "next/image"; +import React from "react"; + +import { useContributor } from "@/hooks/useContributor"; + +type MemberProjectSectionProps = { + id: string; +}; + +// From useGamesShowcase +function getGameCoverUrl( + game_cover_thumbnail: string | null | undefined, +): string { + if (!game_cover_thumbnail) return "/game_dev_club_logo.svg"; + if (game_cover_thumbnail.startsWith("http")) return game_cover_thumbnail; + // Use environment variable for Django backend base URL + const apiBaseUrl = + process.env.NEXT_PUBLIC_API_BASE_URL || "http://localhost:8000"; + return `${apiBaseUrl}${game_cover_thumbnail}`; +} + +export default function MemberProjectSection(props: MemberProjectSectionProps) { + const { data: games, isPending, isError, error } = useContributor(props.id); + + { + /* Error handling from Games Showcase page */ + } + if (isPending) { + return ( +
+

Loading games...

+
+ ); + } + + if (isError) { + const errorMessage = + error?.response?.status === 404 + ? "Games not found." + : "Failed to Load Games"; + return ( +
+

+ {errorMessage} +

+
+ ); + } + + return ( +
+ {!games || games.length === 0 ? ( +

No games available.

+ ) : ( +
+ {games.map((game) => ( + +
+
+ {`${game.game_data.name} +
+

+ {game.game_data.name} +

+

+ {game.game_data.description} +

+
+
+ ))} +
+ )} +
+ ); +} diff --git a/client/src/hooks/useContributor.ts b/client/src/hooks/useContributor.ts index bdd831d5..d29e7843 100644 --- a/client/src/hooks/useContributor.ts +++ b/client/src/hooks/useContributor.ts @@ -1,4 +1,5 @@ import { useQuery } from "@tanstack/react-query"; +import { AxiosError } from "axios"; import api from "@/lib/api"; @@ -14,8 +15,8 @@ type ApiContributorGamesList = { game_data: ApiContributorGameData; }; -export const useContributor = (member: number) => { - return useQuery({ +export const useContributor = (member: string | string[] | undefined) => { + return useQuery({ queryKey: ["contributor", member], queryFn: async () => { const response = await api.get(`/games/contributor/${member}/`); From 9025848190c3d410b508bc84e3f320087cc0441f Mon Sep 17 00:00:00 2001 From: belledw Date: Mon, 2 Feb 2026 03:51:02 +0000 Subject: [PATCH 05/15] Added links to the game detail page for each game on the member profile --- client/src/components/main/MemberProfile.tsx | 7 +++++-- client/src/components/ui/MemberProjectSection.tsx | 10 +++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/client/src/components/main/MemberProfile.tsx b/client/src/components/main/MemberProfile.tsx index 16268d8d..55277dcc 100644 --- a/client/src/components/main/MemberProfile.tsx +++ b/client/src/components/main/MemberProfile.tsx @@ -1,5 +1,6 @@ "use client"; +import { Sparkles } from "lucide-react"; import Image from "next/image"; import MemberProjectSection from "../ui/MemberProjectSection"; @@ -73,9 +74,11 @@ export function MemberProfile({ member }: MemberProfileProps) { - {/* Template for Projects section */}
-

Projects

+

+ Projects{" "} + +

diff --git a/client/src/components/ui/MemberProjectSection.tsx b/client/src/components/ui/MemberProjectSection.tsx index dd91ded3..e8dbd969 100644 --- a/client/src/components/ui/MemberProjectSection.tsx +++ b/client/src/components/ui/MemberProjectSection.tsx @@ -1,4 +1,5 @@ import Image from "next/image"; +import Link from "next/link"; import React from "react"; import { useContributor } from "@/hooks/useContributor"; @@ -56,13 +57,20 @@ export default function MemberProjectSection(props: MemberProjectSectionProps) { {games.map((game) => (
-
+
{`${game.game_data.name} + + Visit Game +

{game.game_data.name} From 8ced90a2473564a81e6d196191634033a0c01a62 Mon Sep 17 00:00:00 2001 From: belledw Date: Tue, 3 Feb 2026 05:35:11 +0000 Subject: [PATCH 06/15] Separated sections for games and artwork on Member Profile page. --- client/src/components/main/MemberProfile.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/client/src/components/main/MemberProfile.tsx b/client/src/components/main/MemberProfile.tsx index 55277dcc..62ec5582 100644 --- a/client/src/components/main/MemberProfile.tsx +++ b/client/src/components/main/MemberProfile.tsx @@ -1,6 +1,6 @@ "use client"; -import { Sparkles } from "lucide-react"; +import { Palette, Sparkles } from "lucide-react"; import Image from "next/image"; import MemberProjectSection from "../ui/MemberProjectSection"; @@ -74,12 +74,16 @@ export function MemberProfile({ member }: MemberProfileProps) {

-
+

- Projects{" "} + Games

+

+ Artwork + +

); From cc8148ebad9ac9b5d50f9fc0011eaf263df991b2 Mon Sep 17 00:00:00 2001 From: belledw Date: Tue, 3 Feb 2026 05:51:33 +0000 Subject: [PATCH 07/15] Removed 'line too long' error from game_dev urls.py --- server/game_dev/urls.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/game_dev/urls.py b/server/game_dev/urls.py index 7b86b669..5a713a6a 100644 --- a/server/game_dev/urls.py +++ b/server/game_dev/urls.py @@ -1,5 +1,6 @@ from django.urls import path -from .views import ContributorGamesListAPIView, EventListAPIView, EventDetailAPIView, GamesDetailAPIView, GameshowcaseAPIView, MemberAPIView, CommitteeAPIView +from .views import ContributorGamesListAPIView, EventListAPIView, EventDetailAPIView +from .views import GamesDetailAPIView, GameshowcaseAPIView, MemberAPIView, CommitteeAPIView urlpatterns = [ path("events/", EventListAPIView.as_view(), name="events-list"), From 8fced48eafbcd76aa08bd91734abb71596edc84c Mon Sep 17 00:00:00 2001 From: Phillip Date: Wed, 4 Feb 2026 09:06:58 +0000 Subject: [PATCH 08/15] Fix link to member pages in IndividualGamePage component --- client/src/pages/games/[id].tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/pages/games/[id].tsx b/client/src/pages/games/[id].tsx index a83c5102..d892a13d 100644 --- a/client/src/pages/games/[id].tsx +++ b/client/src/pages/games/[id].tsx @@ -111,7 +111,7 @@ export default function IndividualGamePage() { {game.contributors.map((c) => ( {c.name} From 3374f54764a26668f852fb0fddb21c9e19f08d92 Mon Sep 17 00:00:00 2001 From: belledw Date: Sat, 7 Feb 2026 03:21:01 +0000 Subject: [PATCH 09/15] Re-positioned member initials to be exactly in the centre of the frame --- client/src/components/main/MemberProfile.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/main/MemberProfile.tsx b/client/src/components/main/MemberProfile.tsx index 62ec5582..d076c0c3 100644 --- a/client/src/components/main/MemberProfile.tsx +++ b/client/src/components/main/MemberProfile.tsx @@ -52,7 +52,7 @@ export function MemberProfile({ member }: MemberProfileProps) { /> ) : (
- {initials} +

{initials}

)}
From 47aed7066ade51a1df6596f3d825ad0bd950bb6e Mon Sep 17 00:00:00 2001 From: belledw Date: Sat, 7 Feb 2026 03:32:59 +0000 Subject: [PATCH 10/15] Added documentation to backend --- server/game_dev/serializers.py | 2 ++ server/game_dev/views.py | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/server/game_dev/serializers.py b/server/game_dev/serializers.py index 531e72dd..7ad1c4ff 100644 --- a/server/game_dev/serializers.py +++ b/server/game_dev/serializers.py @@ -74,6 +74,7 @@ def get_contributors(self, obj): class ContributorGameDataSerializer(serializers.ModelSerializer): + # Serializes data in Game model to display on a contributor's profile. class Meta: model = Game @@ -82,6 +83,7 @@ class Meta: class ContributorGameSerializer(serializers.ModelSerializer): + # Matches games in the GameContributor model to the information about them in the Game model. game_id = serializers.IntegerField(source='game.id', read_only=True) role = serializers.CharField(read_only=True) game_data = serializers.SerializerMethodField() diff --git a/server/game_dev/views.py b/server/game_dev/views.py index 73ec71b7..d1f7c42f 100644 --- a/server/game_dev/views.py +++ b/server/game_dev/views.py @@ -71,6 +71,10 @@ def get(self, request): class ContributorGamesListAPIView(APIView): + """ + GET /api/games/contributor// + Returns the games a particular member has contributed to. + """ lookup_url_kwarg = "member" def get(self, request, member): From f9b6cc0eb057cb907b495b560dcbde8bd29820d4 Mon Sep 17 00:00:00 2001 From: belledw Date: Sat, 7 Feb 2026 03:34:54 +0000 Subject: [PATCH 11/15] Removed duplicate GameShowcase path in urls.py --- server/game_dev/urls.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/server/game_dev/urls.py b/server/game_dev/urls.py index 5a713a6a..7e103bf9 100644 --- a/server/game_dev/urls.py +++ b/server/game_dev/urls.py @@ -6,13 +6,11 @@ path("events/", EventListAPIView.as_view(), name="events-list"), path("events//", EventDetailAPIView.as_view()), path("games//", GamesDetailAPIView.as_view()), - # Updated line for GameShowcase endpoint - path("gameshowcase/", GameshowcaseAPIView.as_view(), name="gameshowcase-api"), - path('members//', MemberAPIView.as_view()), - path("about/", CommitteeAPIView.as_view()), path("games/contributor//", ContributorGamesListAPIView.as_view()), # Updated line for GameShowcase endpoint path("gameshowcase/", GameshowcaseAPIView.as_view(), name="gameshowcase-api"), + path('members//', MemberAPIView.as_view()), + path("about/", CommitteeAPIView.as_view()), path('members//', MemberAPIView.as_view()) ] From cd2451c825a0c63fa47147fa24189abc5d564e0c Mon Sep 17 00:00:00 2001 From: belledw Date: Sat, 7 Feb 2026 03:47:12 +0000 Subject: [PATCH 12/15] Prettified error messages in MemberProjectSection --- .../components/ui/MemberProjectSection.tsx | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/client/src/components/ui/MemberProjectSection.tsx b/client/src/components/ui/MemberProjectSection.tsx index e8dbd969..cfe209e8 100644 --- a/client/src/components/ui/MemberProjectSection.tsx +++ b/client/src/components/ui/MemberProjectSection.tsx @@ -21,19 +21,11 @@ function getGameCoverUrl( } export default function MemberProjectSection(props: MemberProjectSectionProps) { - const { data: games, isPending, isError, error } = useContributor(props.id); + const { data: games, isError, error } = useContributor(props.id); { /* Error handling from Games Showcase page */ } - if (isPending) { - return ( -
-

Loading games...

-
- ); - } - if (isError) { const errorMessage = error?.response?.status === 404 @@ -41,7 +33,10 @@ export default function MemberProjectSection(props: MemberProjectSectionProps) { : "Failed to Load Games"; return (
-

+

{errorMessage}

@@ -51,7 +46,9 @@ export default function MemberProjectSection(props: MemberProjectSectionProps) { return (
{!games || games.length === 0 ? ( -

No games available.

+

+ No games available. +

) : (
{games.map((game) => ( From 8dd2a5b22306f6c2076de3fdfc573f3565d71c78 Mon Sep 17 00:00:00 2001 From: belledw Date: Sat, 7 Feb 2026 06:04:59 +0000 Subject: [PATCH 13/15] Games link now opens in a new tab --- client/src/components/ui/MemberProjectSection.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/client/src/components/ui/MemberProjectSection.tsx b/client/src/components/ui/MemberProjectSection.tsx index cfe209e8..1b5f7e9a 100644 --- a/client/src/components/ui/MemberProjectSection.tsx +++ b/client/src/components/ui/MemberProjectSection.tsx @@ -1,3 +1,4 @@ +import { ArrowUpRight } from "lucide-react"; import Image from "next/image"; import Link from "next/link"; import React from "react"; @@ -63,10 +64,11 @@ export default function MemberProjectSection(props: MemberProjectSectionProps) { className="group-hover:brightness-75 group-hover:duration-200" /> window.open(`/games/${game.game_id}`)} > - Visit Game + Visit Game

From e24bd1ee2b3431e59a6182103460dd88263193c9 Mon Sep 17 00:00:00 2001 From: belledw Date: Sat, 7 Feb 2026 07:37:41 +0000 Subject: [PATCH 14/15] Removed unused commented code in MemberProfile.tsx --- client/src/components/main/MemberProfile.tsx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/client/src/components/main/MemberProfile.tsx b/client/src/components/main/MemberProfile.tsx index d076c0c3..3bbd4c1b 100644 --- a/client/src/components/main/MemberProfile.tsx +++ b/client/src/components/main/MemberProfile.tsx @@ -5,14 +5,6 @@ import Image from "next/image"; import MemberProjectSection from "../ui/MemberProjectSection"; -// unused atm, as the member isnt linked a project on the backend -/* export type MemberProfileProject = { - id: string; - name: string; - description?: string; - href?: string; -}; */ - export type MemberProfileData = { name: string; about: string; @@ -22,7 +14,6 @@ export type MemberProfileData = { type MemberProfileProps = { member: MemberProfileData; - //projects?: MemberProfileProject[]; }; function initialsFromName(name: string) { From 59af88cdb83927d862df8650f3159f68b117a50d Mon Sep 17 00:00:00 2001 From: belledw Date: Sat, 14 Feb 2026 06:19:52 +0000 Subject: [PATCH 15/15] Fixing flake8 issue --- server/game_dev/serializers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/game_dev/serializers.py b/server/game_dev/serializers.py index c8fcb345..90db3a20 100644 --- a/server/game_dev/serializers.py +++ b/server/game_dev/serializers.py @@ -104,7 +104,8 @@ class Meta: def get_game_data(self, obj): game_data = Game.objects.get(id=obj.game_id) return ContributorGameDataSerializer(game_data).data - + + class SocialMediaSerializer(serializers.ModelSerializer): class Meta: model = SocialMedia