Skip to content

Commit 91b7b61

Browse files
committed
Partial signup
Signed-off-by: Omkar Phansopkar <[email protected]>
1 parent 8f01529 commit 91b7b61

File tree

4 files changed

+276
-73
lines changed

4 files changed

+276
-73
lines changed

server/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ if (process.env.NODE_ENV !== "production") {
1111
const { MONGODB_SRV_STRING, PORT } = require("./constants/config");
1212
const newEntity = require('./routes/newEntity');
1313
const auth = require('./routes/auth');
14+
const sms = require('./routes/sms');
1415

1516
// Setting the MongoDB
1617
mongoose.set('strictQuery', true);
@@ -35,7 +36,7 @@ app.listen(PORT, () => console.log(`Server is running on ${PORT}`));
3536

3637

3738
// Preparing routers
38-
app.use(newEntity, auth);
39+
app.use(newEntity, auth, sms);
3940

4041

4142

server/routes/sms.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
const express = require('express');
2+
const router = express.Router();
3+
4+
const { sendOTP, verifyOTP } = require("../services/smsAPI");
5+
6+
// OTP routes
7+
router.post("/apis/sendOTP", (req, res) => {
8+
const phone = `+91${req.body.phone}`;
9+
10+
if (!phone)
11+
return res.status(400).send({
12+
message: "Wrong phone number :(",
13+
phone,
14+
success: false,
15+
data,
16+
});
17+
18+
sendOTP(phone)
19+
.then(() => {
20+
res.status(200).send({
21+
message: `OTP sent to ${phone}`
22+
})
23+
})
24+
.catch((err) => {
25+
console.log(err);
26+
console.log(`Some err sending OTP to ${phone}`);
27+
res.status(500).send({
28+
message: "Server error, contact administrator",
29+
phone,
30+
success: false,
31+
err,
32+
});
33+
});
34+
});
35+
36+
// Verify Endpoint
37+
router.post("/apis/verifyOTP", (req, res) => {
38+
const phone = `+91${req.body.phone}`;
39+
const code = req.body.code;
40+
41+
if (!phone || code.length != CODE_LENGTH)
42+
return res.status(400).send({
43+
message: "Invalid phone number or code :(",
44+
success: false,
45+
phone,
46+
code,
47+
});
48+
49+
verifyOTP(phone, code)
50+
.then((valid) => {
51+
if (valid) {
52+
console.log(`OTP approved for ${phone}`);
53+
return res.status(200).send({
54+
message: "OTP is Verified successfuly!!",
55+
success: true,
56+
});
57+
}
58+
return res.status(203).send({
59+
message: "Wrong code",
60+
success: false,
61+
});
62+
})
63+
.catch((error) => {
64+
console.log(error);
65+
console.log(
66+
`Some err verifying OTP ${code} for ${phone}, maybe it is already verified`
67+
);
68+
res.status(500).send({
69+
message: "Server error, contact administrator",
70+
phone,
71+
code,
72+
success: false,
73+
error,
74+
});
75+
});
76+
});
77+
78+
79+
module.exports = router;

server/services/smsAPI.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const TWILIO_ACCOUNT_SID = process.env.TWILIO_ACCOUNT_SID;
2+
const AUTH_TOKEN = process.env.AUTH_TOKEN;
3+
const SERVICE_ID = process.env.SERVICE_ID;
4+
5+
console.log("Twilio params", {
6+
TWILIO_ACCOUNT_SID,
7+
AUTH_TOKEN,
8+
SERVICE_ID
9+
});
10+
11+
const twilioClient = require('twilio')(TWILIO_ACCOUNT_SID, AUTH_TOKEN);
12+
13+
exports.sendOTP = (phone) => {
14+
console.log("Hello")
15+
return new Promise((resolve, reject) => {
16+
twilioClient.verify.v2.services(SERVICE_ID)
17+
.verifications
18+
.create({to: phone, channel: 'sms'})
19+
.then(resolve)
20+
.catch(reject)
21+
})
22+
}
23+
24+
exports.verifyOTP = (phone, code) => {
25+
return new Promise((resolve, reject) => {
26+
client.verify.v2.services(SERVICE_ID)
27+
.verificationChecks
28+
.create({to: phone, code: code})
29+
.then(resolve)
30+
.catch(reject);
31+
})
32+
}

src/pages/signup.jsx

Lines changed: 163 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,170 @@
1-
import OTPVerification from "@/components/otpVerification"
2-
import SignupForm from "@/components/signupForm"
1+
import OTPVerification from "@/components/otpVerification";
2+
import SignupForm from "@/components/signupForm";
3+
import {
4+
withAuthenticatedRoute,
5+
withoutAuthenticatedRoute,
6+
} from "../context/AuthContext";
37

4-
const { AppContext } = require("@/context/appContext")
5-
const { useContext, useState, useEffect } = require("react")
8+
const { AppContext } = require("@/context/appContext");
9+
const { useContext, useState, useEffect } = require("react");
610

711
const Signup = () => {
8-
const appContext = useContext(AppContext)
9-
const [state, setState] = useState(appContext.state)
10-
const [stage, setStage] = useState("createAccount") // createAccount || otpVerification || verified
11-
12-
useEffect(() => {
13-
setState(appContext.state)
14-
}, [appContext.state])
15-
16-
const createAccountHandler = (event) => {
17-
event.preventDefault()
18-
19-
const restuarantName = event.target.restuarantName.value
20-
const restuarantGSTIN = event.target.restuarantGSTIN.value
21-
const address = event.target.restuarantAddress.value
22-
const phoneNumber = event.target.phone.value
23-
const password = event.target.password.value
24-
25-
console.log(restuarantName, restuarantGSTIN, address, phoneNumber, password)
26-
setStage("otpVerification")
27-
}
28-
29-
return (
30-
<div className={`w-full min-h-[calc(100vh-60px)] h-auto font-inter flex flex-row ${state.darkMode && "text-white bg-dark2"}
12+
const appContext = useContext(AppContext);
13+
const [state, setState] = useState(appContext.state);
14+
const [stage, setStage] = useState("createAccount"); // createAccount || otpVerification || verified
15+
const [userInfo, setUserInfo] = useState(null);
16+
17+
useEffect(() => {
18+
setState(appContext.state);
19+
}, [appContext.state]);
20+
21+
const createAccountHandler = (event) => {
22+
event.preventDefault();
23+
24+
const restuarantName = event.target.restuarantName.value;
25+
const restuarantGSTIN = event.target.restuarantGSTIN.value;
26+
const address = event.target.restuarantAddress.value;
27+
const phoneNumber = event.target.phone.value;
28+
const password = event.target.password.value;
29+
30+
console.log("User info", {
31+
restuarantName,
32+
restuarantGSTIN,
33+
address,
34+
phoneNumber,
35+
password,
36+
});
37+
38+
setUserInfo({
39+
restuarantName,
40+
restuarantGSTIN,
41+
address,
42+
phoneNumber,
43+
password,
44+
})
45+
setStage("otpVerification");
46+
};
47+
48+
return (
49+
<div
50+
className={`w-full min-h-[calc(100vh-60px)] h-auto font-inter flex flex-row ${
51+
state.darkMode && "text-white bg-dark2"
52+
}
3153
sm:flex-col
32-
`}>
33-
{/* left container */}
34-
<div className={`w-[55%] h-full box-border ${state.darkMode && "text-white bg-dark2"}
54+
`}
55+
>
56+
{/* left container */}
57+
<div
58+
className={`w-[55%] h-full box-border ${
59+
state.darkMode && "text-white bg-dark2"
60+
}
3561
sm:w-full sm:min-h-[calc(100vh-60px)]
36-
`}>
37-
38-
</div>
39-
40-
{/* right container */}
41-
<div className={`flex flex-col w-[45%] px-[70px] py-[30px] min-h-full h-auto box-border border-l-[1px]
42-
${state.darkMode ? "text-white bg-dark3 border-bd" : "bg-[#F6F9FC] text-[#0E0B3D]"}
62+
`}
63+
></div>
64+
65+
{/* right container */}
66+
<div
67+
className={`flex flex-col w-[45%] px-[70px] py-[30px] min-h-full h-auto box-border border-l-[1px]
68+
${
69+
state.darkMode
70+
? "text-white bg-dark3 border-bd"
71+
: "bg-[#F6F9FC] text-[#0E0B3D]"
72+
}
4373
sm:w-full sm:px-[35px]
44-
`}>
45-
<div className="text-[22px] mb-[15px]">Let's create an account</div>
46-
47-
<div className="flex flex-row items-center justify-between text-[14px] font-[12px]">
48-
<div className="flex flex-row items-center text-blue-600 dark:text-blue-500">
49-
<svg aria-hidden="true" className="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd"></path></svg>
50-
Personal Info
51-
</div>
52-
<div className={`h-[1px] w-[30px] sm:w-[30px] ${(stage == 'verified' || stage == 'otpVerification') ? "bg-blue-600 dark:bg-blue-500" : "bg-gray-500 dark:bg-gray-200"}`}>
53-
54-
</div>
55-
<div className={`flex flex-row items-center ${(stage == 'verified' || stage == 'otpVerification') ? "text-blue-600 dark:text-blue-500" : "text-gray-500"}`}>
56-
<svg aria-hidden="true" className="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd"></path></svg>
57-
GSTIN Verification
58-
</div>
59-
<div className={`h-[1px] w-[30px] sm:w-[30px] ${stage == 'otpVerification' ? "bg-blue-600 dark:bg-blue-500" : "bg-gray-500 dark:bg-gray-200"}`}>
60-
61-
</div>
62-
<div className={`flex flex-row items-center ${stage == 'otpVerification' ? "text-blue-600 dark:text-blue-500" : "text-gray-500"}`}>
63-
<svg aria-hidden="true" className="w-4 h-4 mr-2" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd"></path></svg>
64-
OTP Verification
65-
</div>
66-
</div>
74+
`}
75+
>
76+
<div className="text-[22px] mb-[15px]">Let's create an account</div>
77+
78+
<div className="flex flex-row items-center justify-between text-[14px] font-[12px]">
79+
<div className="flex flex-row items-center text-blue-600 dark:text-blue-500">
80+
<svg
81+
aria-hidden="true"
82+
className="w-4 h-4 mr-2"
83+
fill="currentColor"
84+
viewBox="0 0 20 20"
85+
xmlns="http://www.w3.org/2000/svg"
86+
>
87+
<path
88+
fillRule="evenodd"
89+
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
90+
clipRule="evenodd"
91+
></path>
92+
</svg>
93+
Personal Info
94+
</div>
95+
<div
96+
className={`h-[1px] w-[30px] sm:w-[30px] ${
97+
stage == "verified" || stage == "otpVerification"
98+
? "bg-blue-600 dark:bg-blue-500"
99+
: "bg-gray-500 dark:bg-gray-200"
100+
}`}
101+
></div>
102+
<div
103+
className={`flex flex-row items-center ${
104+
stage == "verified" || stage == "otpVerification"
105+
? "text-blue-600 dark:text-blue-500"
106+
: "text-gray-500"
107+
}`}
108+
>
109+
<svg
110+
aria-hidden="true"
111+
className="w-4 h-4 mr-2"
112+
fill="currentColor"
113+
viewBox="0 0 20 20"
114+
xmlns="http://www.w3.org/2000/svg"
115+
>
116+
<path
117+
fillRule="evenodd"
118+
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
119+
clipRule="evenodd"
120+
></path>
121+
</svg>
122+
GSTIN Verification
123+
</div>
124+
<div
125+
className={`h-[1px] w-[30px] sm:w-[30px] ${
126+
stage == "otpVerification"
127+
? "bg-blue-600 dark:bg-blue-500"
128+
: "bg-gray-500 dark:bg-gray-200"
129+
}`}
130+
></div>
131+
<div
132+
className={`flex flex-row items-center ${
133+
stage == "otpVerification"
134+
? "text-blue-600 dark:text-blue-500"
135+
: "text-gray-500"
136+
}`}
137+
>
138+
<svg
139+
aria-hidden="true"
140+
className="w-4 h-4 mr-2"
141+
fill="currentColor"
142+
viewBox="0 0 20 20"
143+
xmlns="http://www.w3.org/2000/svg"
144+
>
145+
<path
146+
fillRule="evenodd"
147+
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
148+
clipRule="evenodd"
149+
></path>
150+
</svg>
151+
OTP Verification
152+
</div>
153+
</div>
67154

68-
{(stage == "createAccount" || stage == 'verified') ?
69-
<SignupForm createAccountHandler={createAccountHandler} stage={stage} setStage={setStage}/>
70-
:
71-
<OTPVerification/>
72-
}
155+
{stage == "createAccount" || stage == "verified" ? (
156+
<SignupForm
157+
createAccountHandler={createAccountHandler}
158+
stage={stage}
159+
setStage={setStage}
160+
/>
161+
) : (
162+
<OTPVerification />
163+
)}
73164

74-
{/* {stage == "otpVerification" && <OTPVerification/>} */}
165+
{/* {stage == "otpVerification" && <OTPVerification/>} */}
75166

76-
{/* <div className="flex flex-col mt-auto items-center justify-center">
167+
{/* <div className="flex flex-col mt-auto items-center justify-center">
77168
<div className="flex flex-row">
78169
<div className={` text-[#0E0B3D] ${state.darkMode && "text-white"}`}>Built at</div>
79170
</div>
@@ -87,9 +178,9 @@ const Signup = () => {
87178
<div className="mt-[20px] text-[14px]">
88179
<span className="text-[#AEAEAE]">By</span> Team Code Squad 🚀</div>
89180
</div> */}
90-
</div>
91-
</div>
92-
)
93-
}
181+
</div>
182+
</div>
183+
);
184+
};
94185

95-
export default Signup
186+
export default withoutAuthenticatedRoute(Signup);

0 commit comments

Comments
 (0)