Skip to content

Commit d630b8b

Browse files
committed
Implementated project creation feature
1 parent ef6cfde commit d630b8b

File tree

10 files changed

+278
-27
lines changed

10 files changed

+278
-27
lines changed

next.config.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
/** @type {import('next').NextConfig} */
22
const nextConfig = {
33
images: {
4-
domains: ['api.minimalavatars.com', 'media.graphassets.com'],
4+
domains: [
5+
'api.minimalavatars.com',
6+
'media.graphassets.com',
7+
'res.cloudinary.com',
8+
],
59
},
610
};
711

File renamed without changes.

src/components/project/Children/FundProject/FundProject.tsx

+17-10
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
FundItem,
1010
} from './FundProjectStyles';
1111
import { ProgressBar } from '@/components/global';
12+
import { secondsToDays } from '@/helpers/formatters';
13+
import { CURRENCY_SYMBOL } from '@/data/appInfo';
1214

1315
export const fundings: FundProjectTypes = {
1416
target: {
@@ -57,40 +59,43 @@ const FundProject = ({
5759
ProjectDetailContext
5860
) as ProjectDetailContextReturnTypes;
5961

62+
console.log(data?.project.amountRaised);
63+
6064
return (
6165
<FundingContainer>
6266
<ProgressWrapper>
63-
{data?.project.targetAmount && data?.project.amountRaised && (
67+
{data?.project && (
6468
<ProgressBar
65-
max={data.project.targetAmount}
66-
value={data.project.amountRaised}
69+
max={data.project.targetAmount || 0}
70+
value={data.project.amountRaised || 0}
6771
/>
6872
)}
6973
</ProgressWrapper>
7074
<div className="fund-item_container">
7175
<FundItem>
7276
<h3>
7377
{data?.project.targetAmount
74-
? `$
75-
${data?.project.targetAmount.toLocaleString()}`
78+
? `
79+
${data?.project.targetAmount.toLocaleString()} ${CURRENCY_SYMBOL}`
7680
: '--'}
7781
</h3>
7882
<p>{target.title}</p>
7983
</FundItem>
8084
<FundItem>
8185
<h3>
8286
{data?.project.amountRaised
83-
? `$
84-
${data?.project.amountRaised.toLocaleString()}`
87+
? `
88+
${data?.project.amountRaised.toLocaleString()} ${CURRENCY_SYMBOL}`
89+
: data?.project.amountRaised === 0
90+
? `0 ${CURRENCY_SYMBOL}`
8591
: '--'}
8692
</h3>
8793
<p>{raised.title}</p>
8894
</FundItem>
8995
<FundItem>
9096
<h3>
9197
{data?.project.minInvestment
92-
? `$
93-
${data?.project.minInvestment.toLocaleString()}`
98+
? `${data?.project.minInvestment.toLocaleString()} ${CURRENCY_SYMBOL}`
9499
: '--'}
95100
</h3>
96101
<p>{investment.title}</p>
@@ -99,14 +104,16 @@ const FundProject = ({
99104
<h3>
100105
{data?.project.noOfInvestors
101106
? `${data?.project.noOfInvestors.toLocaleString()}`
107+
: data?.project.noOfInvestors === 0
108+
? '0'
102109
: '--'}
103110
</h3>
104111
<p>{investors.title}</p>
105112
</FundItem>
106113
<FundItem>
107114
<h3>
108115
{data?.project.noOfDaysLeft
109-
? `${data?.project.noOfDaysLeft.toLocaleString()}`
116+
? `${secondsToDays(data?.project.noOfDaysLeft).toLocaleString()}`
110117
: '--'}
111118
</h3>
112119
<p>{deadline.title}</p>

src/components/project/ProjectCreation/Children/FormBodyTabs/ProjectCreatorTab.tsx

+66-13
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { useState, useContext } from 'react';
1+
import React, { useState, useContext, useEffect } from 'react';
2+
import { useRouter } from 'next/router';
23
import {
34
ProjectCreactionContext,
45
ProjectCreactionContextReturnTypes,
@@ -9,17 +10,28 @@ import {
910
ProjectCreatorForm,
1011
FormButtonContainer,
1112
} from './FormStyles';
13+
import usePostProject from '@/hooks/RequestHooks/POST/usePostProject';
14+
import { Notification } from '@/components/global';
15+
import { initialProjectFormData } from '@/components/project/ProjectCreation/ProjectCreationContext';
1216

1317
const ProjectCreatorTab = () => {
18+
const router = useRouter();
19+
20+
const [requestCompletionCount, setRequestCompletionCount] = useState(0);
21+
const [startProjectCreation, setStartProjectCreation] = useState(false);
22+
const [notificationMessage, setNotificationMessage] = useState('');
23+
const [showNotification, setShowNotification] = useState(false);
24+
1425
const { projectFormData, setProjectFormData, setActiveTab } = useContext(
1526
ProjectCreactionContext
1627
) as ProjectCreactionContextReturnTypes;
1728

18-
const [formData, setFormData] = useState({
19-
targetAmount: '',
20-
minInvestment: '',
21-
campaignEndDate: '',
22-
});
29+
const {
30+
createProject,
31+
projectCreationStatus,
32+
projectDetailCreationStatus,
33+
projectData,
34+
} = usePostProject({ data: projectFormData });
2335

2436
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
2537
const { name, value } = e.target;
@@ -28,14 +40,46 @@ const ProjectCreatorTab = () => {
2840
...prevState,
2941
main: {
3042
...prevState.main,
31-
[name]: value,
43+
[name]: name === 'noOfDaysLeft' ? value : Number(value),
3244
},
3345
}));
3446
};
3547

3648
// Get current date in format YYYY-MM-DD
3749
const currentDate = new Date().toISOString().split('T')[0];
3850

51+
useEffect(() => {
52+
if (projectCreationStatus === 2) {
53+
setRequestCompletionCount(1);
54+
}
55+
}, [projectCreationStatus]);
56+
57+
useEffect(() => {
58+
if (projectDetailCreationStatus === 2) {
59+
setRequestCompletionCount(2);
60+
setNotificationMessage(
61+
'Congratulations, Your project had been created successfully'
62+
);
63+
setStartProjectCreation(false);
64+
setTimeout(() => {
65+
router.push(`/project/${projectData?.projectId}`);
66+
setProjectFormData(initialProjectFormData);
67+
setActiveTab(0);
68+
}, 2000);
69+
}
70+
71+
if (projectDetailCreationStatus === 3) {
72+
setNotificationMessage('Project creation was not successful');
73+
setStartProjectCreation(false);
74+
}
75+
// eslint-disable-next-line react-hooks/exhaustive-deps
76+
}, [projectData?.projectId, projectDetailCreationStatus, router]);
77+
78+
const handleProjectCreation = () => {
79+
setStartProjectCreation(true);
80+
createProject();
81+
};
82+
3983
return (
4084
<ProjectCreatorContainer>
4185
<ProjectCreatorForm>
@@ -54,9 +98,9 @@ const ProjectCreatorTab = () => {
5498
type="number"
5599
step="1"
56100
min="0"
57-
pattern="^\d*(\.\d{0,2})?$"
101+
pattern="^\d*(\.\d{0,9})?$"
58102
name="targetAmount"
59-
value={projectFormData.main.targetAmount.toLocaleString()}
103+
value={projectFormData.main.targetAmount}
60104
onChange={handleInputChange}
61105
placeholder="Target Investment Amount (USD)"
62106
/>
@@ -67,9 +111,9 @@ const ProjectCreatorTab = () => {
67111
type="number"
68112
step="0.01"
69113
min="0"
70-
pattern="^\d*(\.\d{0,2})?$"
114+
pattern="^\d*(\.\d{0,9})?$"
71115
name="minInvestment"
72-
value={projectFormData.main.minInvestment.toLocaleString()}
116+
value={projectFormData.main.minInvestment}
73117
onChange={handleInputChange}
74118
placeholder="($) Minimum Investment Amount"
75119
/>
@@ -92,11 +136,20 @@ const ProjectCreatorTab = () => {
92136
buttonFunction={() => setActiveTab(7)}
93137
/>
94138
<Button
95-
buttonTitle="Get Funded"
139+
buttonTitle={
140+
startProjectCreation
141+
? `Get Funded (${requestCompletionCount}/2)`
142+
: `Get Funded`
143+
}
96144
buttonType="action"
97-
buttonFunction={() => {}}
145+
buttonFunction={handleProjectCreation}
98146
/>
99147
</FormButtonContainer>
148+
<Notification
149+
message={notificationMessage}
150+
state={showNotification}
151+
setState={setShowNotification}
152+
/>
100153
</ProjectCreatorForm>
101154
</ProjectCreatorContainer>
102155
);

src/components/project/ProjectCreation/ProjectCreationContext.tsx

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React, { ReactElement, ReactNode, useState, useEffect } from 'react';
22
import { ProjectFormType } from '@/types/projectTypes';
3+
import useWallet from '@/wallet/useWallet';
34

4-
const initialProjectFormData: ProjectFormType = {
5+
export const initialProjectFormData: ProjectFormType = {
56
main: {
67
categoryId: '',
78
projectName: '',
@@ -57,6 +58,7 @@ export const ProjectCreactionContext =
5758
React.createContext<ProjectCreactionContextReturnTypes | null>(null);
5859

5960
const ProjectCreactionProvider = ({ children }: PropTypes): ReactElement => {
61+
const { wallet } = useWallet();
6062
const [formCompleted, setFormCompleted] = useState(false);
6163

6264
const [activeTab, setActiveTab] = useState(() => {
@@ -82,6 +84,19 @@ const ProjectCreactionProvider = ({ children }: PropTypes): ReactElement => {
8284
localStorage.setItem('activeTab', activeTab.toString());
8385
}, [activeTab]);
8486

87+
// Set project wallet address
88+
useEffect(() => {
89+
if (wallet.walletAddress) {
90+
setProjectFormData((prevState) => ({
91+
...prevState,
92+
main: {
93+
...prevState.main,
94+
projectWalletAddress: wallet.walletAddress || '',
95+
},
96+
}));
97+
}
98+
}, [wallet.walletAddress]);
99+
85100
console.log(projectFormData);
86101

87102
return (

src/data/appInfo.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export const APP_NAME = 'CrowdLaunch';
22
export const APP_URL = 'https://crowdlaunch.vercel.app';
33
export const ETHERSCAN_URL = 'https://goerli.etherscan.io';
4+
export const CURRENCY_SYMBOL = 'ETH';

src/helpers/formatters.ts

+4
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ export const durationInSeconds = (endDate: string): number => {
1212

1313
return Math.floor(differenceInMillis / 1000);
1414
};
15+
16+
export const secondsToDays = (seconds: number) => {
17+
return Math.round(seconds / (24 * 60 * 60));
18+
};

0 commit comments

Comments
 (0)