Skip to content

Commit 04ca84c

Browse files
committed
changes
1 parent be01120 commit 04ca84c

File tree

11 files changed

+188
-58
lines changed

11 files changed

+188
-58
lines changed

backend/api/participants/types.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
1-
from typing import Optional
1+
from typing import TYPE_CHECKING, Annotated, Optional
22

3+
from submissions.models import Submission as SubmissionModel
34
from strawberry.scalars import JSON
45
import strawberry
56
from strawberry import ID
67

78
from api.submissions.permissions import CanSeeSubmissionPrivateFields
89

10+
if TYPE_CHECKING:
11+
from api.submissions.types import Submission
12+
913

1014
@strawberry.type
1115
class Participant:
@@ -25,6 +29,17 @@ class Participant:
2529

2630
_speaker_level: strawberry.Private[str]
2731
_previous_talk_video: strawberry.Private[str]
32+
_conference_id: strawberry.Private[int]
33+
_user_id: strawberry.Private[int]
34+
35+
@strawberry.field
36+
def proposals(
37+
self, info
38+
) -> list[Annotated["Submission", strawberry.lazy("api.submissions.types")]]:
39+
return SubmissionModel.objects.for_conference(self._conference_id).filter(
40+
speaker_id=self._user_id,
41+
status=SubmissionModel.STATUS.accepted,
42+
)
2843

2944
@strawberry.field
3045
def speaker_level(self, info) -> Optional[str]:
@@ -50,12 +65,14 @@ def from_model(cls, instance):
5065
bio=instance.bio,
5166
website=instance.website,
5267
public_profile=instance.public_profile,
53-
_speaker_level=instance.speaker_level,
54-
_previous_talk_video=instance.previous_talk_video,
5568
twitter_handle=instance.twitter_handle,
5669
instagram_handle=instance.instagram_handle,
5770
linkedin_url=instance.linkedin_url,
5871
facebook_url=instance.facebook_url,
5972
mastodon_handle=instance.mastodon_handle,
6073
speaker_availabilities=instance.speaker_availabilities or {},
74+
_conference_id=instance.conference_id,
75+
_user_id=instance.user_id,
76+
_speaker_level=instance.speaker_level,
77+
_previous_talk_video=instance.previous_talk_video,
6178
)

backend/api/schedule/types/slot.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
from enum import Enum
2+
from typing import TYPE_CHECKING, Annotated
23
from django.utils import timezone
34
from datetime import datetime, time, timedelta
45
from api.schedule.types.schedule_item import ScheduleItem
56

67

78
import strawberry
89

10+
if TYPE_CHECKING:
11+
from api.schedule.types.day import Day
12+
913

1014
@strawberry.enum
1115
class ScheduleSlotType(Enum):
@@ -16,10 +20,11 @@ class ScheduleSlotType(Enum):
1620

1721
@strawberry.type
1822
class ScheduleSlot:
23+
id: strawberry.ID
1924
hour: time
2025
duration: int
2126
type: ScheduleSlotType
22-
id: strawberry.ID
27+
day: Annotated["Day", strawberry.lazy("api.schedule.types.day")]
2328

2429
@strawberry.field
2530
def is_live(self) -> bool:

frontend/src/components/public-profile-page-handler/fetch-participant.graphql

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
query ParticipantPublicProfile($id: ID!, $conference: String!) {
1+
#import "../../fragments/schedule-item.graphql"
2+
3+
query ParticipantPublicProfile(
4+
$id: ID!
5+
$conference: String!
6+
$language: String!
7+
) {
28
participant(id: $id, conference: $conference) {
39
id
410
fullname
@@ -11,5 +17,24 @@ query ParticipantPublicProfile($id: ID!, $conference: String!) {
1117
linkedinUrl
1218
facebookUrl
1319
mastodonHandle
20+
proposals {
21+
id
22+
title(language: $language)
23+
type {
24+
id
25+
name
26+
}
27+
audienceLevel {
28+
id
29+
name
30+
}
31+
duration {
32+
id
33+
duration
34+
}
35+
scheduleItems {
36+
...ScheduleItemFragment
37+
}
38+
}
1439
}
1540
}

frontend/src/components/public-profile-page-handler/index.tsx

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,39 @@
1-
import { Page, Section } from "@python-italia/pycon-styleguide";
1+
import {
2+
CardPart,
3+
Heading,
4+
Link,
5+
MultiplePartsCard,
6+
MultiplePartsCardCollection,
7+
Page,
8+
Section,
9+
Spacer,
10+
Text,
11+
} from "@python-italia/pycon-styleguide";
212

313
import { useRouter } from "next/router";
414

5-
import { useParticipantPublicProfileQuery } from "~/types";
15+
import {
16+
Participant,
17+
type ParticipantPublicProfileQueryResult,
18+
useParticipantPublicProfileQuery,
19+
} from "~/types";
620

21+
import { FormattedMessage } from "react-intl";
22+
import { useCurrentLanguage } from "~/locale/context";
23+
import { createHref } from "../link";
724
import { ParticipantInfoSection } from "../participant-info-section";
25+
import { ScheduleItemList } from "../schedule-view/schedule-list";
826

927
export const PublicProfilePageHandler = () => {
1028
const router = useRouter();
29+
const language = useCurrentLanguage();
1130
const {
1231
data: { participant },
1332
} = useParticipantPublicProfileQuery({
1433
variables: {
1534
id: router.query.hashid as string,
1635
conference: process.env.conferenceCode,
36+
language,
1737
},
1838
});
1939

@@ -25,6 +45,60 @@ export const PublicProfilePageHandler = () => {
2545
participant={participant}
2646
/>
2747
</Section>
48+
{participant.proposals.length > 0 && (
49+
<Section>
50+
<Heading size={2}>
51+
<FormattedMessage id="global.sessions" />
52+
</Heading>
53+
<Spacer size="2md" />
54+
<MultiplePartsCardCollection>
55+
{participant.proposals.map((proposal) => (
56+
<ProposalCard proposal={proposal} />
57+
))}
58+
</MultiplePartsCardCollection>
59+
</Section>
60+
)}
2861
</Page>
2962
);
3063
};
64+
65+
const ProposalCard = ({
66+
proposal,
67+
}: {
68+
proposal: ParticipantPublicProfileQueryResult["data"]["participant"]["proposals"][0];
69+
}) => {
70+
const language = useCurrentLanguage();
71+
return (
72+
<MultiplePartsCard>
73+
<CardPart contentAlign="left">
74+
<div className="flex flex-row items-center md:gap-3 lg:gap-6">
75+
<Text size={3} color="grey-500">
76+
<FormattedMessage
77+
id="voting.minutes"
78+
values={{
79+
type: proposal.type.name,
80+
duration: proposal.duration.duration,
81+
}}
82+
/>
83+
, {proposal.audienceLevel.name}
84+
</Text>
85+
</div>
86+
<Spacer size="xs" />
87+
88+
<Link
89+
href={createHref({
90+
path:
91+
proposal.scheduleItems.length > 0
92+
? `/event/${proposal.scheduleItems[0].slug}`
93+
: `/submission/${proposal.id}`,
94+
locale: language,
95+
})}
96+
>
97+
<Heading color="none" size={4}>
98+
{proposal.title}
99+
</Heading>
100+
</Link>
101+
</CardPart>
102+
</MultiplePartsCard>
103+
);
104+
};

frontend/src/components/schedule-view/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ export const isItemVisible = (
498498
const query = currentFilters.search[0].toLowerCase().split(" ");
499499
const title = item.title.toLowerCase();
500500
const speakersNames = item.speakers
501-
.reduce((acc, speaker) => `${acc} ${speaker.fullName}`, "")
501+
.reduce((acc, speaker) => `${acc} ${speaker.fullname}`, "")
502502
.toLowerCase();
503503

504504
if (

frontend/src/components/schedule-view/schedule-list.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export const ScheduleList = ({
5757
}
5858

5959
return (
60-
<ScheduleItem
60+
<ScheduleItemList
6161
key={item.id}
6262
item={item}
6363
currentDay={currentDay}
@@ -76,7 +76,7 @@ export const ScheduleList = ({
7676
);
7777
};
7878

79-
const ScheduleItem = ({
79+
export const ScheduleItemList = ({
8080
item,
8181
slot,
8282
isLive,
@@ -193,7 +193,7 @@ const ScheduleItem = ({
193193
{item.speakers.length > 0 && (
194194
<Heading size={6}>
195195
{item.speakers
196-
.map((speaker) => speaker.fullName)
196+
.map((speaker) => speaker.fullname)
197197
.join(", ")}
198198
</Heading>
199199
)}

frontend/src/components/schedule-view/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export type Item = {
4040
submission?: Submission | null;
4141
keynote?: Keynote | null;
4242
audienceLevel?: { name: string; id: string } | null;
43-
speakers: { fullName: string; participant?: Participant }[];
43+
speakers: { fullname: string; participant?: Participant }[];
4444
hasLimitedCapacity: boolean;
4545
userHasSpot: boolean;
4646
hasSpacesLeft: boolean;

frontend/src/locale/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export const messages = {
1111
"We have groups discounts for groups with 6+ people, contact us to know more. After you have purchased your tickets, you will be able to access the {page} with our discounted codes.",
1212
"tickets.description.page": "hotels page",
1313

14+
"global.sessions": "Sessions",
15+
1416
"input.placeholder": "Type here...",
1517
"global.accordion.close": "Close",
1618
"global.accordion.readMore": "Read more",
@@ -1935,6 +1937,8 @@ Affrettati a comprare il biglietto!`,
19351937
"scheduleEventDetail.materials.open": "Apri ({hostname})",
19361938
"scheduleEventDetail.materials.download": "Scarica ({mimeType})",
19371939

1940+
"global.sessions": "Sessioni",
1941+
19381942
"scheduleEventDetail.eventTime": "{start} - {end}",
19391943
"voting.minutes": "{type} ({duration} minuti)",
19401944
"voting.pagination":

frontend/src/pages/profile/[hashid].tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const getServerSideProps: GetServerSideProps = async ({
1717
queryParticipantPublicProfile(client, {
1818
conference: process.env.conferenceCode,
1919
id: params.hashid as string,
20+
language: locale,
2021
}),
2122
]);
2223

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
fragment ScheduleItemFragment on ScheduleItem {
2+
id
3+
title
4+
slug
5+
type
6+
7+
duration
8+
9+
hasLimitedCapacity
10+
userHasSpot
11+
hasSpacesLeft
12+
spacesLeft
13+
linkTo
14+
15+
audienceLevel {
16+
id
17+
name
18+
}
19+
20+
language {
21+
id
22+
name
23+
code
24+
}
25+
26+
submission {
27+
...SubmissionFragment
28+
}
29+
30+
keynote {
31+
...KeynoteFragment
32+
}
33+
34+
speakers {
35+
id
36+
fullname
37+
participant {
38+
id
39+
photo
40+
}
41+
}
42+
43+
rooms {
44+
id
45+
name
46+
type
47+
}
48+
}

0 commit comments

Comments
 (0)