Skip to content

Commit 1b0beb0

Browse files
feat: discussion page
1 parent 532f92f commit 1b0beb0

File tree

7 files changed

+618
-436
lines changed

7 files changed

+618
-436
lines changed

packages/backend/src/resolvers/user.resolver.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { AuthenticatedContext, GqlResolvers, User } from '@lara/api'
22

3-
import { isAdmin, isTrainee, isTrainer } from '../permissions'
3+
import { isAdmin, isTrainee, isTrainer, isMentor } from '../permissions'
44
import { allTrainees } from '../repositories/trainee.repo'
55
import { saveUser } from '../repositories/user.repo'
66
import { generateAdmin } from '../services/admin.service'
77
import { alexaSkillLinked } from '../services/alexa.service'
88
import { generateTrainee } from '../services/trainee.service'
99
import { generateTrainer } from '../services/trainer.service'
10+
import { generateMentor } from '../services/mentor.service'
1011

1112
export const userResolver: GqlResolvers<AuthenticatedContext> = {
1213
UserInterface: {
@@ -41,6 +42,14 @@ export const userResolver: GqlResolvers<AuthenticatedContext> = {
4142
}
4243
}
4344

45+
if (!isMentor(currentUser) && type === 'Mentor') {
46+
newUser = {
47+
...(await generateMentor(currentUser)),
48+
...currentUser,
49+
type,
50+
}
51+
}
52+
4453
if (!isAdmin(currentUser) && type === 'Admin') {
4554
newUser = {
4655
...generateAdmin(currentUser),

packages/frontend/src/graphql/index.tsx

Lines changed: 431 additions & 424 deletions
Large diffs are not rendered by default.

packages/frontend/src/pages/mentor-paper-page.tsx

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ export const MentorPaperPage: React.FC = () => {
1414
const { loading, data } = useMentorPaperPageDataQuery()
1515
const navigate = useNavigate()
1616

17+
const navigateToPaperFeedbackPage = (paperId: string) => {
18+
navigate('/paper/feedback/' + paperId)
19+
}
20+
21+
const navigateToPaperDiscussionPage = (paperId: string) => {
22+
navigate('/paper/feedback/discussion/' + paperId)
23+
}
24+
1725
if (!data) {
1826
return (
1927
<Template type="Main">
@@ -98,13 +106,25 @@ export const MentorPaperPage: React.FC = () => {
98106
<Spacer y="xl">
99107
<ProgressBar progress={mapStatusToProgess(paper.status)} color={'primaryDefault'} />
100108
</Spacer>
101-
{paper?.status === PaperStatus.TraineeDone ? (
109+
{[
110+
PaperStatus.NotStarted,
111+
PaperStatus.InProgress,
112+
PaperStatus.TraineeDone,
113+
PaperStatus.Archived,
114+
PaperStatus.MentorDone,
115+
].includes(paper?.status) && (
102116
<Flex justifyContent={'flex-end'}>
103-
<PrimaryButton onClick={() => navigate(`/paper/feedback/${paper?.id}`)}>
104-
{paper.feedbackMentor.length > 0 ? strings.edit : strings.start}
117+
<PrimaryButton
118+
onClick={() =>
119+
(paper?.feedbackTrainee?.length ?? 0) > 0 && (paper?.feedbackMentor?.length ?? 0) > 0
120+
? navigateToPaperDiscussionPage(paper.id)
121+
: navigateToPaperFeedbackPage(paper.id)
122+
}
123+
>
124+
{(paper?.feedbackTrainee?.length ?? 0) > 0 ? strings.edit : strings.start}
105125
</PrimaryButton>
106126
</Flex>
107-
) : null}
127+
)}
108128
</Container>
109129
</Spacer>
110130
) : null
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import React from 'react'
2+
import { useParams } from 'react-router'
3+
import { Box, PaperH2, PaperLayout, Spacer } from '@lara/components'
4+
import NavigationButtonLink from '../components/navigation-button-link'
5+
import { Template } from '../templates/template'
6+
import strings from '../locales/localization'
7+
import {
8+
useTraineePaperPageDataQuery,
9+
useMentorPaperPageDataQuery,
10+
FeedbackEntryProps,
11+
PaperFormData,
12+
} from '../graphql'
13+
import CommentSection from '../components/comment-section'
14+
15+
// FeedbackEntryProps already declares:
16+
// { entry: PaperFormData; comments: string[]; onSubmit: (comment: string) => void; displayTextInput: boolean }
17+
18+
export const FeedbackEntry: React.FC<FeedbackEntryProps> = ({ entry, comments, onSubmit, displayTextInput }) => {
19+
// If CommentSection expects richer objects, convert at boundary (kept minimal)
20+
const commentSectionData = (comments || []).map((text, i) => ({
21+
id: `generated-${i}`,
22+
text,
23+
published: true,
24+
user: {
25+
id: 'unknown',
26+
firstName: '',
27+
lastName: '',
28+
},
29+
}))
30+
31+
return (
32+
<Box mb="4" p="4">
33+
<Box mb="3">
34+
<strong>{entry.question}</strong>
35+
<p>{entry.answer}</p>
36+
</Box>
37+
38+
<CommentSection comments={commentSectionData} onSubmit={onSubmit} displayTextInput={displayTextInput} />
39+
</Box>
40+
)
41+
}
42+
43+
type PaperWithFeedback = {
44+
id: string
45+
feedbackTrainee?: PaperFormData[]
46+
feedbackMentor?: PaperFormData[]
47+
}
48+
49+
/**
50+
* Keep minimal changes: type the currentUser->papers access so we can call .map
51+
* with concrete PaperFormData elements instead of `any`.
52+
*/
53+
export const PaperFeedbackDiscussionPage: React.FC = () => {
54+
const { paperId } = useParams<{ paperId: string }>()
55+
const traineePaperData = useTraineePaperPageDataQuery()
56+
const mentorPaperData = useMentorPaperPageDataQuery()
57+
58+
const currentUser = traineePaperData.data?.currentUser || mentorPaperData.data?.currentUser
59+
60+
// Narrow `papers` to a known shape (no `any`)
61+
const papers = (currentUser as unknown as { papers?: PaperWithFeedback[] })?.papers
62+
const paper = papers?.find((p) => p.id === paperId)
63+
64+
if (!paper || !currentUser) {
65+
return (
66+
<Template type="Main">
67+
<div>Loading...</div>
68+
</Template>
69+
)
70+
}
71+
72+
// keep returning string[] as per FeedbackEntryProps
73+
const getCommentsForEntry = (_entryId: string): string[] => {
74+
return []
75+
}
76+
77+
// prefix unused args with _ to satisfy eslint no-unused-vars rule
78+
const handleCommentSubmit = (_entryId: string, _text: string) => {
79+
// TODO: Implement mutation to save comment for entry
80+
}
81+
82+
return (
83+
<Template type="Main">
84+
<Spacer bottom="m">
85+
<NavigationButtonLink
86+
label={strings.back}
87+
to="/paper"
88+
icon="ChevronLeft"
89+
isLeft
90+
alignLeft
91+
iconColor="iconLightGrey"
92+
/>
93+
</Spacer>
94+
<PaperLayout>
95+
<div style={{ width: '100%' }}>
96+
<PaperH2>{strings.paper.feedback.headlineEvaluationByTrainee}</PaperH2>
97+
98+
{Array.isArray(paper.feedbackTrainee) &&
99+
paper.feedbackTrainee.map((entry: PaperFormData) => (
100+
<FeedbackEntry
101+
key={entry.id}
102+
entry={entry}
103+
comments={getCommentsForEntry(entry.id)}
104+
onSubmit={(text) => handleCommentSubmit(entry.id, text)}
105+
displayTextInput={true}
106+
/>
107+
))}
108+
109+
<PaperH2>{strings.paper.feedback.headlineEvaluationByMentor}</PaperH2>
110+
111+
{Array.isArray(paper.feedbackMentor) &&
112+
paper.feedbackMentor.map((entry: PaperFormData) => (
113+
<FeedbackEntry
114+
key={entry.id}
115+
entry={entry}
116+
comments={getCommentsForEntry(entry.id)}
117+
onSubmit={(text) => handleCommentSubmit(entry.id, text)}
118+
displayTextInput={true}
119+
/>
120+
))}
121+
</div>
122+
</PaperLayout>
123+
</Template>
124+
)
125+
}
126+
127+
export default PaperFeedbackDiscussionPage

packages/frontend/src/pages/trainee-paper-page.tsx

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export const TraineePaperPage: React.FC = () => {
1919
navigate('/paper/feedback/' + paperId)
2020
}
2121

22+
const navigateToPaperDiscussionPage = (paperId: string) => {
23+
navigate('/paper/feedback/discussion/' + paperId)
24+
}
25+
2226
if (!data) {
2327
return (
2428
<Template type="Main">
@@ -101,13 +105,25 @@ export const TraineePaperPage: React.FC = () => {
101105
<Spacer y="xl">
102106
<ProgressBar progress={mapStatusToProgess(paper.status)} color={'primaryDefault'} />
103107
</Spacer>
104-
{paper?.status === PaperStatus.InProgress ? (
108+
{[
109+
PaperStatus.NotStarted,
110+
PaperStatus.InProgress,
111+
PaperStatus.TraineeDone,
112+
PaperStatus.Archived,
113+
PaperStatus.MentorDone,
114+
].includes(paper?.status) && (
105115
<Flex justifyContent={'flex-end'}>
106-
<PrimaryButton onClick={() => navigateToPaperFeedbackPage(paper.id)}>
107-
{paper?.feedbackTrainee.length > 0 ? strings.edit : strings.start}
116+
<PrimaryButton
117+
onClick={() =>
118+
(paper?.feedbackTrainee?.length ?? 0) > 0 && (paper?.feedbackMentor?.length ?? 0) > 0
119+
? navigateToPaperDiscussionPage(paper.id)
120+
: navigateToPaperFeedbackPage(paper.id)
121+
}
122+
>
123+
{(paper?.feedbackTrainee?.length ?? 0) > 0 ? strings.edit : strings.start}
108124
</PrimaryButton>
109125
</Flex>
110-
) : null}
126+
)}
111127
</Container>
112128
</Spacer>
113129
) : null

packages/frontend/src/pages/trainer-paper-page.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,13 +184,13 @@ export const TrainerPaperPage: React.FC = () => {
184184
<Spacer y="xl">
185185
<ProgressBar progress={mapStatusToProgess(paper.status)} color={'primaryDefault'} />
186186
</Spacer>
187-
{paper.status === 'NotStarted' ? (
187+
{[PaperStatus.NotStarted, PaperStatus.InProgress].includes(paper?.status) && (
188188
<Flex justifyContent={'flex-end'}>
189189
<PrimaryButton onClick={() => navigateToEditPaperPage(paper.id)}>
190-
{paper?.briefing.length > 0 ? strings.edit : strings.start}
190+
{(paper?.feedbackTrainee?.length ?? 0) > 0 ? strings.edit : strings.start}
191191
</PrimaryButton>
192192
</Flex>
193-
) : null}
193+
)}
194194
<Modal show={showDeletePaperModal} customClose handleClose={() => toggleDeletePaperModal(undefined)}>
195195
<Flex flexDirection={'row'} alignItems={'center'}>
196196
<Box width={1 / 3}>

packages/frontend/src/routes.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import { isWikiFeatureEnabled } from './helper/wiki-helper'
3434
import { AdminAdminsPage } from './pages/admin-admins-page'
3535
import { TraineePaperFeedbackPage } from './pages/trainee-paper-feedback-page'
3636
import { MentorPaperFeedbackPage } from './pages/mentor-paper-feedback-page'
37+
import PaperFeedbackDiscussionPage from './pages/paper-feedback-discussion-page'
3738
import { isPaperFeatureEnabled } from './helper/paper-helper'
3839

3940
type RoutesProps = {
@@ -92,6 +93,7 @@ const AppRoutes: React.FunctionComponent<RoutesProps> = ({ currentUser }) => {
9293
<>
9394
<Route path="/paper" element={<TraineePaperPage />} />
9495
<Route path="/paper/feedback/:paperId" element={<TraineePaperFeedbackPage />} />
96+
<Route path="/paper/feedback/discussion/:paperId" element={<PaperFeedbackDiscussionPage />} />
9597
</>
9698
)}
9799
</>
@@ -127,6 +129,7 @@ const AppRoutes: React.FunctionComponent<RoutesProps> = ({ currentUser }) => {
127129
<Route path="/" element={<MentorPaperPage />} />
128130
<Route path="/paper" element={<MentorPaperPage />} />
129131
<Route path="/paper/feedback/:paperId" element={<MentorPaperFeedbackPage />} />
132+
<Route path="/paper/feedback/discussion/:paperId" element={<PaperFeedbackDiscussionPage />} />
130133
</>
131134
)}
132135

0 commit comments

Comments
 (0)