Skip to content

Commit ca49e13

Browse files
committed
added label on the module frontend
1 parent 2838aa0 commit ca49e13

File tree

15 files changed

+111
-19
lines changed

15 files changed

+111
-19
lines changed

backend/apps/mentorship/api/internal/mutations/module.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ def create_module(self, info: strawberry.Info, input_data: CreateModuleInput) ->
100100
started_at=started_at,
101101
ended_at=ended_at,
102102
domains=input_data.domains,
103+
labels=input_data.labels,
103104
tags=input_data.tags,
104105
program=program,
105106
project=project,
@@ -239,6 +240,7 @@ def update_module(self, info: strawberry.Info, input_data: UpdateModuleInput) ->
239240
"started_at": started_at,
240241
"ended_at": ended_at,
241242
"domains": input_data.domains,
243+
"labels": input_data.labels,
242244
"tags": input_data.tags,
243245
}
244246

backend/apps/mentorship/api/internal/nodes/module.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ModuleNode:
2424
domains: list[str] | None = None
2525
ended_at: datetime
2626
experience_level: ExperienceLevelEnum
27+
labels: list[str] | None = None
2728
program: ProgramNode | None = None
2829
project_id: strawberry.ID | None = None
2930
started_at: datetime
@@ -109,6 +110,7 @@ class CreateModuleInput:
109110
domains: list[str] = strawberry.field(default_factory=list)
110111
ended_at: datetime
111112
experience_level: ExperienceLevelEnum
113+
labels: list[str] = strawberry.field(default_factory=list)
112114
mentor_logins: list[str] | None = None
113115
program_key: str
114116
project_name: str
@@ -128,6 +130,7 @@ class UpdateModuleInput:
128130
domains: list[str] = strawberry.field(default_factory=list)
129131
ended_at: datetime
130132
experience_level: ExperienceLevelEnum
133+
labels: list[str] = strawberry.field(default_factory=list)
131134
mentor_logins: list[str] | None = None
132135
project_id: strawberry.ID
133136
project_name: str

frontend/__tests__/unit/components/SingleModuleCard.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ const mockModule: Module = {
106106
endedAt: '2024-12-31T23:59:59Z',
107107
domains: ['frontend', 'backend'],
108108
tags: ['react', 'nodejs'],
109+
labels: ['good first issue', 'bug'],
109110
}
110111

111112
const mockAdmins = [{ login: 'admin1' }, { login: 'admin2' }]

frontend/src/app/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const ModuleDetailsPage = () => {
6565
admins={admins}
6666
tags={module.tags}
6767
domains={module.domains}
68+
labels={module.labels}
6869
summary={module.description}
6970
mentors={module.mentors}
7071
type="module"

frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/edit/page.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ const EditModulePage = () => {
8282
domains: (m.domains || []).join(', '),
8383
projectName: m.projectName,
8484
tags: (m.tags || []).join(', '),
85+
labels: (m.labels || []).join(', '),
8586
projectId: m.projectId || '',
8687
mentorLogins: (m.mentors || []).map((mentor: { login: string }) => mentor.login).join(', '),
8788
})
@@ -103,6 +104,7 @@ const EditModulePage = () => {
103104
endedAt: formData.endedAt || null,
104105
domains: parseCommaSeparated(formData.domains),
105106
tags: parseCommaSeparated(formData.tags),
107+
labels: parseCommaSeparated(formData.labels),
106108
projectName: formData.projectName,
107109
projectId: formData.projectId,
108110
mentorLogins: parseCommaSeparated(formData.mentorLogins),

frontend/src/app/my/mentorship/programs/[programKey]/modules/[moduleKey]/page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const ModuleDetailsPage = () => {
6565
admins={admins}
6666
tags={module.tags}
6767
domains={module.domains}
68+
labels={module.labels}
6869
summary={module.description}
6970
mentors={module.mentors}
7071
type="module"

frontend/src/app/my/mentorship/programs/[programKey]/modules/create/page.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const CreateModulePage = () => {
3939
endedAt: '',
4040
domains: '',
4141
tags: '',
42+
labels: '',
4243
projectId: '',
4344
projectName: '',
4445
mentorLogins: '',
@@ -88,6 +89,7 @@ const CreateModulePage = () => {
8889
endedAt: formData.endedAt || null,
8990
domains: parseCommaSeparated(formData.domains),
9091
tags: parseCommaSeparated(formData.tags),
92+
labels: parseCommaSeparated(formData.labels),
9193
programKey: programKey,
9294
projectId: formData.projectId,
9395
projectName: formData.projectName,

frontend/src/components/CardDetailsPage.tsx

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const DetailsCard = ({
4343
canUpdateStatus,
4444
tags,
4545
domains,
46+
labels,
4647
modules,
4748
mentors,
4849
admins,
@@ -211,26 +212,38 @@ const DetailsCard = ({
211212
</div>
212213
)}
213214
{(type === 'program' || type === 'module') && (
214-
<div
215-
className={`mb-8 grid grid-cols-1 gap-6 ${(tags?.length || 0) === 0 || (domains?.length || 0) === 0 ? 'md:col-span-1' : 'md:grid-cols-2'}`}
216-
>
217-
{tags?.length > 0 && (
218-
<ToggleableList
219-
items={tags}
220-
icon={faTags}
221-
label={<AnchorTitle title="Tags" />}
222-
isDisabled={true}
223-
/>
224-
)}
225-
{domains?.length > 0 && (
226-
<ToggleableList
227-
items={domains}
228-
icon={faChartPie}
229-
label={<AnchorTitle title="Domains" />}
230-
isDisabled={true}
231-
/>
215+
<>
216+
<div
217+
className={`mb-8 grid grid-cols-1 gap-6 ${(tags?.length || 0) === 0 || (domains?.length || 0) === 0 ? 'md:col-span-1' : 'md:grid-cols-2'}`}
218+
>
219+
{tags?.length > 0 && (
220+
<ToggleableList
221+
items={tags}
222+
icon={faTags}
223+
label={<AnchorTitle title="Tags" />}
224+
isDisabled={true}
225+
/>
226+
)}
227+
{domains?.length > 0 && (
228+
<ToggleableList
229+
items={domains}
230+
icon={faChartPie}
231+
label={<AnchorTitle title="Domains" />}
232+
isDisabled={true}
233+
/>
234+
)}
235+
</div>
236+
{labels?.length > 0 && (
237+
<div className="mb-8">
238+
<ToggleableList
239+
items={labels}
240+
icon={faTags}
241+
label={<AnchorTitle title="Labels" />}
242+
isDisabled={true}
243+
/>
244+
</div>
232245
)}
233-
</div>
246+
</>
234247
)}
235248
{topContributors && (
236249
<TopContributorsList
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from 'react'
2+
3+
interface LabelProps {
4+
label: string
5+
className?: string
6+
}
7+
8+
const Label: React.FC<LabelProps> = ({ label, className = '' }) => {
9+
return (
10+
<span
11+
className={`inline-block rounded-lg border border-gray-400 px-2 py-0.5 text-xs text-gray-700 hover:bg-gray-200 dark:border-gray-300 dark:text-gray-300 dark:hover:bg-gray-700 ${className}`}
12+
>
13+
{label}
14+
</span>
15+
)
16+
}
17+
18+
interface LabelListProps {
19+
labels: string[]
20+
maxVisible?: number
21+
className?: string
22+
}
23+
24+
const LabelList: React.FC<LabelListProps> = ({ labels, maxVisible = 5, className = '' }) => {
25+
if (!labels || labels.length === 0) return null
26+
27+
const visibleLabels = labels.slice(0, maxVisible)
28+
const remainingCount = labels.length - maxVisible
29+
30+
return (
31+
<div className={`flex flex-wrap gap-2 ${className}`}>
32+
{visibleLabels.map((label, index) => (
33+
<Label key={`${label}-${index}`} label={label} />
34+
))}
35+
{remainingCount > 0 && <Label label={`+${remainingCount} more`} />}
36+
</div>
37+
)
38+
}
39+
40+
export { LabelList }

frontend/src/components/ModuleCard.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { useState } from 'react'
1313
import type { Module } from 'types/mentorship'
1414
import { formatDate } from 'utils/dateFormatter'
1515
import { TextInfoItem } from 'components/InfoItem'
16+
import { LabelList } from 'components/LabelList'
1617
import SingleModuleCard from 'components/SingleModuleCard'
1718
import { TruncatedText } from 'components/TruncatedText'
1819

@@ -85,6 +86,11 @@ const ModuleItem = ({ details }: { details: Module }) => {
8586
label="Duration"
8687
value={getSimpleDuration(details.startedAt, details.endedAt)}
8788
/>
89+
{details.labels && details.labels.length > 0 && (
90+
<div className="mt-2">
91+
<LabelList labels={details.labels} maxVisible={3} />
92+
</div>
93+
)}
8894
</div>
8995
)
9096
}

0 commit comments

Comments
 (0)