1
- import { useEffect , useMemo } from "react" ;
1
+ import { useCallback , useEffect , useMemo , useState } from "react" ;
2
2
import Wrapper from "@/components/sections/courses/Wrapper" ;
3
3
import Header from "@/components/sections/challenges/Header" ;
4
4
import { OverviewRewards as Rewards } from "@/components/sections/challenges/Rewards" ;
@@ -31,7 +31,8 @@ import Objectives from "@/components/sections/challenges/Objectives";
31
31
import { getTeamByChallenge , getUserInvitesByChallenge } from "@/store/services/teams.service" ;
32
32
import { fetchChallenge , fetchChallengeAuthenticated } from "@/store/services/communities/challenges" ;
33
33
import Loader from "@/components/ui/Loader" ;
34
- import { NotFoundError } from "@/utilities/errors/NotFoundError" ;
34
+ import { useRouter } from "next/router" ;
35
+ import Section from "@/components/ui/Section" ;
35
36
import Hint from "@/components/ui/Hint" ;
36
37
import Link from "next/link" ;
37
38
@@ -53,23 +54,12 @@ interface ChallengePageMultiSelector {
53
54
* @date 4/25/2023 - 8:12:39 PM
54
55
*
55
56
* @export
56
- * @param {{
57
- pageProps: {
58
- submission: Submission;
59
- challenge: Challenge;
60
- community: Community;
61
- };
62
- }} props
63
57
* @returns {ReactElement }
64
58
*/
65
- export default function ChallengePage ( props : {
66
- pageProps : {
67
- submission : Submission ;
68
- challenge : Challenge ;
69
- community : Community ;
70
- } ;
71
- } ) : ReactElement {
72
- const { challenge, community } = props . pageProps ;
59
+ export default function ChallengePage ( ) {
60
+ const [ challenge , setChallenge ] = useState < Challenge | null > ( null ) ;
61
+ const [ community , setCommunity ] = useState < Community | null > ( null ) ;
62
+ const [ loading , setLoading ] = useState ( true ) ;
73
63
const dispatch = useDispatch ( ) ;
74
64
const { t } = useTranslation ( ) ;
75
65
const { submission, isAuthenticated, isSubmissionLoading } = useMultiSelector < unknown , ChallengePageMultiSelector > ( {
@@ -80,10 +70,29 @@ export default function ChallengePage(props: {
80
70
const title = useMemo ( ( ) => getMetadataTitle ( t ( "communities.challenge.title" ) , challenge ?. name || "" ) , [ challenge ?. name , t ] ) ;
81
71
82
72
const navigation = useNavigation ( ) ;
73
+ const router = useRouter ( ) ;
74
+ const { challenge_id, slug, locale } = router . query ;
83
75
84
- useEffect ( ( ) => {
76
+ const initPage = useCallback ( async ( ) => {
77
+ const fetchPayload = {
78
+ slug : slug as string ,
79
+ locale : locale as string ,
80
+ } ;
81
+
82
+ setLoading ( true ) ;
83
+ const [ { data : community } , { data : challenge } ] = await Promise . all ( [
84
+ dispatch ( fetchCurrentCommunity ( fetchPayload ) ) as any ,
85
+ dispatch ( fetchChallenge ( { ...fetchPayload , id : challenge_id as string , relations : [ "rubric" , "courses" , "learning-modules" , "best-submissions" ] } ) ) as any ,
86
+ ] ) ;
87
+ setCommunity ( community ) ;
88
+ setChallenge ( challenge ) ;
85
89
dispatch ( initChallengeNavigationMenu ( navigation . community ) ) ;
86
- } , [ ] ) ;
90
+ setLoading ( false ) ;
91
+ } , [ challenge_id , slug ] ) ;
92
+
93
+ useEffect ( ( ) => {
94
+ initPage ( ) ;
95
+ } , [ initPage ] ) ;
87
96
88
97
useEffect ( ( ) => {
89
98
if ( challenge && isAuthenticated ) {
@@ -94,90 +103,78 @@ export default function ChallengePage(props: {
94
103
} , [ challenge , dispatch , isAuthenticated ] ) ;
95
104
96
105
const headerPaths = useMemo ( ( ) => [ t ( "communities.navigation.challenge" ) ] , [ t ] ) ;
97
- return (
98
- < >
99
- < Head >
100
- < title > { title } </ title >
101
- < MetaData description = { challenge ?. description } />
102
- </ Head >
103
- < Wrapper paths = { headerPaths } >
104
- < div className = "flex flex-col py-4 space-y-8 text-gray-700 divide-y divide-gray-200 divide-solid" >
105
- < Header />
106
- < Rewards />
107
- < Objectives />
108
- { challenge . isTeamChallenge && < TeamChallenge /> }
109
- < Learning courses = { challenge . courses } learningModules = { challenge . learningModules } community = { community } />
110
- < RatingRubric ratingCriteria = { challenge ?. ratingCriteria } selected = { [ ] } />
111
- < BestSubmissions />
112
106
113
- { isAuthenticated ? (
114
- < div >
115
- { isSubmissionLoading ? (
116
- < div className = "h-24 sm:h-48 grid place-items-center" >
117
- < Loader />
118
- </ div >
119
- ) : (
120
- < >
121
- { submission ? (
122
- < div className = "mt-8" >
123
- < h4 className = "my-8 text-.5xl font-medium" > { t ( "communities.challenge.your-submission" ) } </ h4 >
124
- < SubmissionCard submission = { submission } />
125
- </ div >
126
- ) : (
127
- < >
128
- { challenge . isTeamChallenge && < SetupTeamChallenge /> }
129
- < SubmissionForm />
130
- </ >
131
- ) }
132
- </ >
133
- ) }
134
- </ div >
135
- ) : (
136
- < div >
137
- < Hint className = "mt-6 flex flex-col md:flex-row" >
138
- < p > To be able to submit</ p >
139
- < Link className = "underline" href = "/login" >
140
- Login.
141
- </ Link >
142
- </ Hint >
143
- </ div >
144
- ) }
145
- </ div >
146
- </ Wrapper >
147
- </ >
148
- ) ;
107
+ if ( loading )
108
+ return (
109
+ < Section className = "h-[50vh] flex items-center justify-center" >
110
+ < Loader />
111
+ </ Section >
112
+ ) ;
113
+
114
+ if ( challenge && community )
115
+ return (
116
+ < >
117
+ < Head >
118
+ < title > { title } </ title >
119
+ < MetaData description = { challenge ?. description } />
120
+ </ Head >
121
+ < Wrapper paths = { headerPaths } >
122
+ < div className = "flex flex-col py-4 space-y-8 text-gray-700 divide-y divide-gray-200 divide-solid" >
123
+ < Header />
124
+ < Rewards />
125
+ < Objectives />
126
+ { challenge . isTeamChallenge && < TeamChallenge /> }
127
+ < Learning courses = { challenge . courses } learningModules = { challenge . learningModules } community = { community } />
128
+ < RatingRubric ratingCriteria = { challenge ?. ratingCriteria } selected = { [ ] } />
129
+ < BestSubmissions />
130
+
131
+ { isAuthenticated ? (
132
+ < div >
133
+ { isSubmissionLoading ? (
134
+ < div className = "h-24 sm:h-48 grid place-items-center" >
135
+ < Loader />
136
+ </ div >
137
+ ) : (
138
+ < >
139
+ { submission ? (
140
+ < div className = "mt-8" >
141
+ < h4 className = "my-8 text-.5xl font-medium" > { t ( "communities.challenge.your-submission" ) } </ h4 >
142
+ < SubmissionCard submission = { submission } />
143
+ </ div >
144
+ ) : (
145
+ < >
146
+ { challenge . isTeamChallenge && < SetupTeamChallenge /> }
147
+ < SubmissionForm />
148
+ </ >
149
+ ) }
150
+ </ >
151
+ ) }
152
+ </ div >
153
+ ) : (
154
+ < div >
155
+ < Hint className = "mt-6 flex flex-col md:flex-row" >
156
+ < p > To be able to submit</ p >
157
+ < Link className = "underline" href = "/login" >
158
+ Login.
159
+ </ Link >
160
+ </ Hint >
161
+ </ div >
162
+ ) }
163
+ </ div >
164
+ </ Wrapper >
165
+ </ >
166
+ ) ;
149
167
}
150
168
151
169
ChallengePage . getLayout = function ( page : ReactElement ) {
152
170
return < DefaultLayout footerBackgroundColor = { false } > { page } </ DefaultLayout > ;
153
171
} ;
154
172
155
- export const getServerSideProps : GetServerSideProps = wrapper . getServerSideProps ( ( store ) => async ( data ) => {
156
- const { query, locale } = data ;
157
- const { slug, challenge_id } = query ;
158
-
159
- const fetchPayload = {
160
- slug : slug as string ,
161
- locale : locale as string ,
173
+ export const getServerSideProps : GetServerSideProps = wrapper . getServerSideProps ( ( ) => async ( data ) => {
174
+ const { locale } = data ;
175
+ return {
176
+ props : {
177
+ ...( await serverSideTranslations ( locale as string ) ) ,
178
+ } ,
162
179
} ;
163
-
164
- try {
165
- const [ { data : community } , { data : challenge } , translations ] = await Promise . all ( [
166
- store . dispatch ( fetchCurrentCommunity ( fetchPayload ) ) ,
167
- store . dispatch ( fetchChallenge ( { ...fetchPayload , id : challenge_id as string , relations : [ "rubric" , "courses" , "learning-modules" , "best-submissions" ] } ) ) ,
168
- serverSideTranslations ( locale as string ) ,
169
- ] ) ;
170
- if ( ! community || ! challenge ) throw new NotFoundError ( ) ;
171
- return {
172
- props : {
173
- ...translations ,
174
- community,
175
- challenge,
176
- } ,
177
- } ;
178
- } catch ( e ) {
179
- return {
180
- notFound : true ,
181
- } ;
182
- }
183
180
} ) ;
0 commit comments