@@ -29,6 +29,7 @@ import {
2929 ProjectModel ,
3030} from '../../../../models/Hackathon' ;
3131import { I18nContext } from '../../../../models/Translation' ;
32+ import styles from '../../../../styles/Hackathon.module.less' ;
3233
3334export const getServerSideProps = compose < Record < 'id' | 'tid' , string > > (
3435 cache ( ) ,
@@ -77,48 +78,66 @@ const ProjectPage: FC<ProjectPageProps> = observer(({ activity, project, members
7778 ] ;
7879
7980 return (
80- < Container as = "main" className = "mt-4" >
81+ < >
8182 < PageHead title = { `${ displayName } - ${ activityName } ` } />
8283
83- < Breadcrumb aria-label = "breadcrumb" >
84- { currentRoute . map ( ( { title, href } , index , { length } ) => {
85- const isActive = index === length - 1 ;
86-
87- return (
88- < Breadcrumb . Item key = { title } href = { isActive ? undefined : href } active = { isActive } >
89- { title }
90- </ Breadcrumb . Item >
91- ) ;
92- } ) }
93- </ Breadcrumb >
94-
95- < Row className = "mt-4 g-3" >
96- < Col xs = { 12 } sm = { 4 } >
97- < Card >
98- < Card . Header className = "bg-white" >
99- < h1 className = "h3 my-2" > { displayName as string } </ h1 >
100- < p className = "text-muted" > { description as string } </ p >
101- { score != null && (
102- < div className = "text-center mt-3" >
103- < Button variant = "danger" className = "fs-5" onClick = { ( ) => setShowScoreModal ( true ) } >
104- { t ( 'score' ) } : { score as number }
105- </ Button >
106- </ div >
107- ) }
108- </ Card . Header >
109- < Card . Body >
110- < h2 className = "text-dark fw-bold h6 mb-3" > 👥 { t ( 'team_members' ) } </ h2 >
111- < ul className = "list-unstyled" >
112- { members . map ( ( { id, person, githubAccount } ) => (
113- < li key = { id as string } className = "d-flex gap-3 align-items-center" >
84+ { /* Hero Section */ }
85+ < section className = { styles . hero } >
86+ < Container >
87+ < Breadcrumb aria-label = "breadcrumb" className = "mb-4" >
88+ { currentRoute . map ( ( { title, href } , index , { length } ) => {
89+ const isActive = index === length - 1 ;
90+
91+ return (
92+ < Breadcrumb . Item
93+ key = { title }
94+ href = { isActive ? undefined : href }
95+ active = { isActive }
96+ className = "text-white"
97+ >
98+ { title }
99+ </ Breadcrumb . Item >
100+ ) ;
101+ } ) }
102+ </ Breadcrumb >
103+
104+ < h1 className = { `text-center ${ styles . title } ` } > { displayName as string } </ h1 >
105+ < p className = { `text-center ${ styles . description } ` } > { description as string } </ p >
106+
107+ { score != null && (
108+ < div className = "text-center mt-4" >
109+ < Button
110+ variant = "light"
111+ size = "lg"
112+ className = "shadow-lg"
113+ onClick = { ( ) => setShowScoreModal ( true ) }
114+ >
115+ { t ( 'score' ) } : < strong > { score as number } </ strong >
116+ </ Button >
117+ </ div >
118+ ) }
119+ </ Container >
120+ </ section >
121+
122+ < Container className = "my-5" >
123+ { /* Team Members Section */ }
124+ < section className = { styles . section } >
125+ < h2 className = { styles . sectionTitle } > 👥 { t ( 'team_members' ) } </ h2 >
126+ < Row as = "ul" className = "list-unstyled mt-4 g-4" xs = { 1 } md = { 2 } lg = { 3 } xl = { 4 } >
127+ { members . map ( ( { id, person, githubAccount } ) => (
128+ < Col as = "li" key = { id as string } >
129+ < Card className = { styles . darkCard } body >
130+ < div className = "d-flex gap-3 align-items-center" >
114131 { /* @ts -expect-error Upstream compatibility */ }
115- < Avatar src = { ( person as TableCellUser ) . avatar_url } />
116- < div >
117- < h3 className = "fs-6 m-0 fw-bold" > { ( person as TableCellUser ) . name } </ h3 >
132+ < Avatar src = { ( person as TableCellUser ) . avatar_url } size = { 60 } />
133+ < div className = "flex-grow-1" >
134+ < h3 className = "fs-6 m-0 fw-bold text-white" >
135+ { ( person as TableCellUser ) . name }
136+ </ h3 >
118137
119138 { githubAccount && (
120139 < a
121- className = "text-muted small"
140+ className = "text-white-50 small"
122141 target = "_blank"
123142 rel = "noreferrer"
124143 href = { `https://github.com/${ githubAccount } ` }
@@ -127,45 +146,46 @@ const ProjectPage: FC<ProjectPageProps> = observer(({ activity, project, members
127146 </ a >
128147 ) }
129148 </ div >
130- </ li >
131- ) ) }
132- </ ul >
133- </ Card . Body >
149+ </ div >
150+ </ Card >
151+ </ Col >
152+ ) ) }
153+ </ Row >
154+ </ section >
155+
156+ { /* Team Products Section */ }
157+ < section className = { styles . section } >
158+ < h2 className = { styles . sectionTitle } > 💡 { t ( 'team_works' ) } </ h2 >
159+
160+ { products && products . length > 0 ? (
161+ < Row as = "ul" className = "list-unstyled mt-4 g-4" xs = { 1 } md = { 2 } lg = { 3 } >
162+ { products . map ( product => (
163+ < Col as = "li" key = { product . id as string } >
164+ < ProductCard { ...product } />
165+ </ Col >
166+ ) ) }
167+ </ Row >
168+ ) : (
169+ < div className = "h1 my-5 text-center text-muted" > { t ( 'no_news_yet' ) } </ div >
170+ ) }
171+ </ section >
172+
173+ { /* Creator Information Section */ }
174+ < section className = { styles . section } >
175+ < h2 className = { styles . sectionTitle } > 👤 { t ( 'created_by' ) } </ h2 >
176+ < Card className = { styles . lightCard } body >
177+ < div className = "fw-bold fs-5" > { ( createdBy as TableCellUser ) . name } </ div >
178+ < a
179+ href = { `mailto:${ ( createdBy as TableCellUser ) . email } ` }
180+ className = "text-dark text-decoration-underline"
181+ >
182+ { ( createdBy as TableCellUser ) . email }
183+ </ a >
134184 </ Card >
135- </ Col >
136- < Col xs = { 12 } sm = { 8 } >
137- < Tabs variant = "pills" defaultActiveKey = "update" id = "project-detail-tabs" >
138- < Tab className = "pt-2" eventKey = "update" title = { t ( 'latest_news' ) } >
139- < div className = "h1 my-5 text-center text-muted" > { t ( 'no_news_yet' ) } </ div >
140- </ Tab >
141- < Tab eventKey = "teamWork" title = { t ( 'team_works' ) } className = "pt-2" >
142- { products && products . length > 0 ? (
143- < Row as = "ul" className = "list-unstyled g-3" xs = { 2 } >
144- { products . map ( product => (
145- < Col as = "li" key = { product . id as string } >
146- < ProductCard { ...product } />
147- </ Col >
148- ) ) }
149- </ Row >
150- ) : (
151- < div className = "text-center text-muted my-5" > { t ( 'no_news_yet' ) } </ div >
152- ) }
153- </ Tab >
154- </ Tabs >
155- </ Col >
156- </ Row >
157-
158- < Card className = "my-4" body >
159- < h3 className = "h5" > { t ( 'created_by' ) } </ h3 >
160- < div className = "mt-3" >
161- < div className = "fw-bold" > { ( createdBy as TableCellUser ) . name } </ div >
162- < a href = { `mailto:${ ( createdBy as TableCellUser ) . email } ` } className = "text-muted" >
163- { ( createdBy as TableCellUser ) . email }
164- </ a >
165- </ div >
166- </ Card >
167-
168- < CommentBox />
185+ </ section >
186+
187+ < CommentBox />
188+ </ Container >
169189
170190 < Modal size = "lg" centered show = { showScoreModal } onHide = { ( ) => setShowScoreModal ( false ) } >
171191 < Modal . Header closeButton >
@@ -181,7 +201,7 @@ const ProjectPage: FC<ProjectPageProps> = observer(({ activity, project, members
181201 </ Ratio >
182202 </ Modal . Body >
183203 </ Modal >
184- </ Container >
204+ </ >
185205 ) ;
186206} ) ;
187207
0 commit comments