11import { ProjectLayout } from '@/components/project-details/project-layout' ;
22import { ProjectLoading } from '@/components/project-details/project-loading' ;
33import { notFound } from 'next/navigation' ;
4- import { getCrowdfundingProject , getProjectDetails } from '@/lib/api/project' ;
5- import { CrowdfundingProject , CrowdfundData } from '@/lib/api/types' ;
4+ import { getCrowdfundingProject } from '@/lib/api/project' ;
5+ import type { CrowdfundingProject , CrowdfundData } from '@/lib/api/types' ;
66import { Suspense } from 'react' ;
7+
78interface ProjectPageProps {
89 params : Promise < {
910 id : string ;
1011 } > ;
1112}
1213
13- // Transform crowdfunding project data to match ProjectLayout interface
1414function transformCrowdfundingProject (
1515 project : CrowdfundingProject ,
1616 crowdfund : CrowdfundData
@@ -19,11 +19,12 @@ function transformCrowdfundingProject(
1919 ? `${ project . creator . profile . firstName } ${ project . creator . profile . lastName } `
2020 : 'Unknown Creator' ;
2121
22- const daysToDeadline = project . funding ?. endDate
22+ const deadlineDate = crowdfund . voteDeadline || project . funding ?. endDate ;
23+ const daysToDeadline = deadlineDate
2324 ? Math . max (
2425 0 ,
2526 Math . ceil (
26- ( new Date ( project . funding . endDate ) . getTime ( ) - new Date ( ) . getTime ( ) ) /
27+ ( new Date ( deadlineDate ) . getTime ( ) - new Date ( ) . getTime ( ) ) /
2728 ( 1000 * 60 * 60 * 24 )
2829 )
2930 )
@@ -32,12 +33,11 @@ function transformCrowdfundingProject(
3233 return {
3334 project : {
3435 ...project ,
35- daysToDeadline : Math . max ( 0 , daysToDeadline ) ,
36- // Add additional fields without overriding the original creator
36+ daysToDeadline,
3737 additionalCreator : {
3838 name : creatorName ,
3939 role : 'OWNER' ,
40- avatar : '/user.png' , // Default avatar, could be enhanced with actual user avatar
40+ avatar : '/user.png' ,
4141 } ,
4242 links : [
4343 ...( project . githubUrl
@@ -55,6 +55,7 @@ function transformCrowdfundingProject(
5555 icon : link . platform . toLowerCase ( ) ,
5656 } ) ) || [ ] ) ,
5757 ] ,
58+ votes : crowdfund . totalVotes || 0 ,
5859 } ,
5960 crowdfund,
6061 } ;
@@ -65,144 +66,18 @@ async function ProjectContent({ id }: { id: string }) {
6566 let error : string | null = null ;
6667
6768 try {
68- // Try to fetch as crowdfunding project first
69- try {
70- const response = await getCrowdfundingProject ( id ) ;
71-
72- if ( response . success && response . data ) {
73- projectData = transformCrowdfundingProject (
74- response . data . project ,
75- response . data . crowdfund
76- ) ;
77- } else {
78- throw new Error ( 'Failed to fetch crowdfunding project' ) ;
79- }
80- } catch {
81- // If crowdfunding project fails, try regular project
82- try {
83- const regularProject = await getProjectDetails ( id ) ;
84-
85- // Transform regular project data if needed
86- // For regular projects, we need to create a mock CrowdfundingProject structure
87- const mockProject : CrowdfundingProject = {
88- _id : regularProject . id || regularProject . _id ,
89- title : regularProject . title ,
90- description : regularProject . description ,
91- category : regularProject . category ,
92- owner : {
93- type : 'individual' ,
94- } ,
95- vision : regularProject . description ,
96- githubUrl : regularProject . githubUrl ,
97- projectWebsite : regularProject . projectWebsite ,
98- demoVideo : regularProject . demoVideo ,
99- socialLinks : regularProject . socialLinks ,
100- status : regularProject . status ,
101- creator : {
102- _id : 'unknown' ,
103- profile : {
104- firstName : regularProject . ownerName ?. split ( ' ' ) [ 0 ] || 'Unknown' ,
105- lastName : regularProject . ownerName ?. split ( ' ' ) [ 1 ] || 'Unknown' ,
106- username : regularProject . ownerUsername || 'unknown' ,
107- } ,
108- } ,
109- contact : {
110- primary : '' ,
111- backup : '' ,
112- } ,
113- createdAt : regularProject . createdAt ,
114- updatedAt : regularProject . updatedAt || regularProject . createdAt ,
115- funding : {
116- goal : 0 ,
117- raised : 0 ,
118- currency : 'USD' ,
119- endDate : new Date (
120- Date . now ( ) + 30 * 24 * 60 * 60 * 1000
121- ) . toISOString ( ) ,
122- contributors : [ ] ,
123- } ,
124- voting : {
125- startDate : new Date ( ) . toISOString ( ) ,
126- endDate : new Date (
127- Date . now ( ) + 30 * 24 * 60 * 60 * 1000
128- ) . toISOString ( ) ,
129- totalVotes : 0 ,
130- positiveVotes : 0 ,
131- negativeVotes : 0 ,
132- voters : [ ] ,
133- } ,
134- milestones : [ ] ,
135- team : [ ] ,
136- media : {
137- banner : regularProject . image ,
138- logo : regularProject . image ,
139- thumbnail : regularProject . image ,
140- } ,
141- documents : {
142- whitepaper : '' ,
143- pitchDeck : '' ,
144- } ,
145- tags : [ ] ,
146- grant : {
147- isGrant : false ,
148- totalBudget : 0 ,
149- totalDisbursed : 0 ,
150- proposalsReceived : 0 ,
151- proposalsApproved : 0 ,
152- status : 'pending' ,
153- applications : [ ] ,
154- } ,
155- summary : regularProject . description ,
156- type : 'crowdfund' ,
157- votes : 0 ,
158- stakeholders : {
159- serviceProvider : '' ,
160- approver : '' ,
161- releaseSigner : '' ,
162- disputeResolver : '' ,
163- receiver : '' ,
164- platformAddress : '' ,
165- } ,
166- trustlessWorkStatus : 'pending' ,
167- escrowType : 'pending' ,
168- __v : 0 ,
169- } ;
69+ const response = await getCrowdfundingProject ( id ) ;
17070
171- const mockCrowdfund : CrowdfundData = {
172- _id : 'mock-crowdfund' ,
173- projectId : regularProject . id || regularProject . _id ,
174- thresholdVotes : 0 ,
175- voteDeadline : new Date (
176- Date . now ( ) + 30 * 24 * 60 * 60 * 1000
177- ) . toISOString ( ) ,
178- totalVotes : 0 ,
179- voteProgress : 0 ,
180- status : regularProject . status ,
181- createdAt : regularProject . createdAt ,
182- updatedAt : regularProject . updatedAt || regularProject . createdAt ,
183- __v : 0 ,
184- isVotingActive : false ,
185- id : 'mock-crowdfund' ,
186- } ;
187-
188- projectData = {
189- project : {
190- ...mockProject ,
191- daysToDeadline : 30 ,
192- additionalCreator : {
193- name : regularProject . ownerName || 'Unknown Creator' ,
194- role : 'OWNER' ,
195- avatar : regularProject . ownerAvatar || '/user.png' ,
196- } ,
197- links : [ ] ,
198- } ,
199- crowdfund : mockCrowdfund ,
200- } ;
201- } catch {
202- error = 'Project not found' ;
203- }
71+ if ( response . success && response . data ) {
72+ projectData = transformCrowdfundingProject (
73+ response . data . project ,
74+ response . data . crowdfund
75+ ) ;
76+ } else {
77+ throw new Error ( response . message || 'Failed to fetch project' ) ;
20478 }
205- } catch {
79+ } catch ( err ) {
80+ console . error ( 'Error fetching project:' , err ) ;
20681 error = 'Failed to fetch project data' ;
20782 }
20883
@@ -212,32 +87,6 @@ async function ProjectContent({ id }: { id: string }) {
21287
21388 return (
21489 < div className = 'mx-auto flex min-h-screen max-w-[1440px] flex-col space-y-[60px] overflow-x-hidden bg-[#030303] px-5 py-5 md:space-y-[80px] md:px-[50px] lg:px-[100px]' >
215- { /* <header className='sticky top-0 z-50 border-b border-gray-800 bg-[#030303]'>
216- <div className='w-full px-4 sm:px-6'>
217- <div className='mx-auto flex max-w-[1400px] items-center justify-between py-3'>
218- <Link href='/projects' passHref>
219- <Button
220- variant='outline'
221- className='h-9 gap-2 border border-gray-700 bg-transparent px-3 text-white transition-colors hover:border-gray-600'
222- >
223- <ArrowLeft className='h-4 w-4' />
224- <span className='hidden sm:inline'>Back</span>
225- </Button>
226- </Link>
227-
228- <Link href={projectUrl} passHref target='_blank'>
229- <Button
230- variant='outline'
231- className='h-9 gap-2 border border-gray-700 bg-transparent px-3 text-white transition-colors hover:border-gray-600'
232- >
233- <span className='hidden sm:inline'>Open</span>
234- <ExternalLink className='h-4 w-4' />
235- </Button>
236- </Link>
237- </div>
238- </div>
239- </header> */ }
240-
24190 < div className = 'flex-1' >
24291 < ProjectLayout
24392 project = { projectData . project }
0 commit comments