From 814340c645102f3fea5103463502cb7e02313e0a Mon Sep 17 00:00:00 2001 From: Prashant Varma Date: Thu, 17 Oct 2024 00:09:22 +0530 Subject: [PATCH 1/2] refactor code --- apps/client/app/(lobby)/auth/signin/page.tsx | 2 +- .../app/(lobby)/wallet/deposit/page.tsx | 10 ++++ apps/client/app/api/initiate/route.ts | 47 +++++++++++++++++++ .../client/app/api/status/[order_id]/route.ts | 24 ++++++++++ apps/client/app/components/Home.tsx | 6 +-- apps/client/app/globals.css | 3 ++ apps/client/app/layout.tsx | 2 +- apps/client/app/page.tsx | 14 ++---- apps/client/components/ToogleSections.tsx | 2 +- .../landing/{ => Appbar}/Appbar.tsx | 0 .../{ => landing/Appbar}/Navbar.tsx | 28 +++++------ .../landing/{ => Appbar}/Navmenu.tsx | 0 .../landing/{ => Appbar}/ProfileHeader.tsx | 2 +- .../components/landing/{ => Auth}/Singin.tsx | 0 .../components/landing/{ => Home}/FAQs.tsx | 0 .../{ => landing/Home}/Features.tsx | 0 .../components/landing/{ => Home}/Hero.tsx | 0 .../{ => landing/Home}/ProboCare.tsx | 0 .../landing/{ => Home}/TakesCare.tsx | 0 .../landing/{ => Orderbook}/Orderbook.tsx | 0 .../landing/{ => Portfolio}/Portfolio.tsx | 0 .../landing/{ => Recharge}/DepositForm.tsx | 0 packages/db/prisma/schema.prisma | 2 +- packages/zod/src/index.ts | 12 +++-- 24 files changed, 118 insertions(+), 36 deletions(-) create mode 100644 apps/client/app/api/initiate/route.ts create mode 100644 apps/client/app/api/status/[order_id]/route.ts rename apps/client/components/landing/{ => Appbar}/Appbar.tsx (100%) rename apps/client/components/{ => landing/Appbar}/Navbar.tsx (81%) rename apps/client/components/landing/{ => Appbar}/Navmenu.tsx (100%) rename apps/client/components/landing/{ => Appbar}/ProfileHeader.tsx (93%) rename apps/client/components/landing/{ => Auth}/Singin.tsx (100%) rename apps/client/components/landing/{ => Home}/FAQs.tsx (100%) rename apps/client/components/{ => landing/Home}/Features.tsx (100%) rename apps/client/components/landing/{ => Home}/Hero.tsx (100%) rename apps/client/components/{ => landing/Home}/ProboCare.tsx (100%) rename apps/client/components/landing/{ => Home}/TakesCare.tsx (100%) rename apps/client/components/landing/{ => Orderbook}/Orderbook.tsx (100%) rename apps/client/components/landing/{ => Portfolio}/Portfolio.tsx (100%) rename apps/client/components/landing/{ => Recharge}/DepositForm.tsx (100%) diff --git a/apps/client/app/(lobby)/auth/signin/page.tsx b/apps/client/app/(lobby)/auth/signin/page.tsx index b035326f..08df5ff9 100644 --- a/apps/client/app/(lobby)/auth/signin/page.tsx +++ b/apps/client/app/(lobby)/auth/signin/page.tsx @@ -1,6 +1,6 @@ "use client" import React from 'react'; -import { Login } from '../../../../components/landing/Singin'; +import { Login } from '../../../../components/landing/Auth/Singin'; const Page = () => { return ( diff --git a/apps/client/app/(lobby)/wallet/deposit/page.tsx b/apps/client/app/(lobby)/wallet/deposit/page.tsx index bdb9a8b7..b715cfee 100644 --- a/apps/client/app/(lobby)/wallet/deposit/page.tsx +++ b/apps/client/app/(lobby)/wallet/deposit/page.tsx @@ -1,11 +1,13 @@ "use client"; import React, { useState, useEffect } from "react"; +import axios from "axios"; const Page = () => { const [amount, setAmount] = useState(""); const [gst, setGst] = useState(0); const [showSummary, setShowSummary] = useState(false); + const [sessionId, setSession] = useState(""); useEffect(() => { const numAmount = parseFloat(amount); @@ -25,6 +27,13 @@ const Page = () => { setAmount(value.toString()); }; + async function handleRechange(){ + const result = await axios.post(process.env.NEXT_PUBLIC_BASE_URL + '/api/initiate', { + + }); + console.log(result); + } + return ( <>
@@ -70,6 +79,7 @@ const Page = () => { diff --git a/apps/client/app/api/initiate/route.ts b/apps/client/app/api/initiate/route.ts new file mode 100644 index 00000000..dbae59d2 --- /dev/null +++ b/apps/client/app/api/initiate/route.ts @@ -0,0 +1,47 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function POST(req: NextRequest) { + try { + const body = await req.json(); + + const response = await fetch(process.env.CASHFREE_URL!, { + method: "POST", + headers: { + accept: "application/json", + "content-type": "application/json", + "x-api-version": "2023-08-01", + "x-client-id": process.env.CASHFREE_CLIENT_ID as string, + "x-client-secret": process.env.CASHFREE_CLIENT_SECRET as string, + }, + body: JSON.stringify({ + customer_details: { + customer_id: body.customer_id, + customer_phone: body.customer_phone, + }, + order_id: body.order_id, + order_amount: body.order_amount, + order_currency: "INR", + order_meta: { + notify_url: process.env.CASHFREE_WEBHOOK_URL, // TODO: add a webhook + payment_methods: "cc,dc,upi", + }, + }), + }); + + const data = await response.json(); + + if (!response.ok) { + return NextResponse.json( + { message: data.message }, + { status: response.status } + ); + } + + return NextResponse.json(data, { status: 200 }); + } catch (error) { + return NextResponse.json( + { message: "Something went wrong", error }, + { status: 500 } + ); + } +} diff --git a/apps/client/app/api/status/[order_id]/route.ts b/apps/client/app/api/status/[order_id]/route.ts new file mode 100644 index 00000000..e507d062 --- /dev/null +++ b/apps/client/app/api/status/[order_id]/route.ts @@ -0,0 +1,24 @@ +import { NextRequest, NextResponse } from "next/server"; + +export async function GET( + req: NextRequest, + { params }: { params: { order_id: string } } +) { + const { order_id } = params; + const response = await fetch(process.env.CASHFREE_URL + order_id, { + method: "GET", + headers: { + accept: "application/json", + "content-type": "application/json", + "x-api-version": "2023-08-01", + "x-client-id": process.env.CASHFREE_CLIENT_ID as string, + "x-client-secret": process.env.CASHFREE_CLIENT_SECRET as string, + }, + }); + const data = await response.json(); + if (data.order_status === "PAID") { + return NextResponse.redirect(new URL("/", req.url)); + } else { + return NextResponse.redirect(new URL("/404", req.url)); + } +} diff --git a/apps/client/app/components/Home.tsx b/apps/client/app/components/Home.tsx index 97c4ca9b..c53db10a 100644 --- a/apps/client/app/components/Home.tsx +++ b/apps/client/app/components/Home.tsx @@ -1,7 +1,7 @@ import React from 'react' -import {Hero} from '../../components/landing/Hero' -import TakesCareWrapper from "../../components/landing/TakesCare" -import FAQS from "../../components/landing/FAQs" +import {Hero} from '../../components/landing/Home/Hero' +import TakesCareWrapper from "../../components/landing/Home/TakesCare" +import FAQS from "../../components/landing/Home/FAQs" export const HomeComponent = () => { return ( diff --git a/apps/client/app/globals.css b/apps/client/app/globals.css index 76c59a83..c7bba5cc 100644 --- a/apps/client/app/globals.css +++ b/apps/client/app/globals.css @@ -125,6 +125,9 @@ body { @tailwind base; @tailwind components; @tailwind utilities; +body{ + overflow-x: hidden; +} html { @apply bg-gray-100; diff --git a/apps/client/app/layout.tsx b/apps/client/app/layout.tsx index 5a7aab31..22bcaaa4 100644 --- a/apps/client/app/layout.tsx +++ b/apps/client/app/layout.tsx @@ -2,7 +2,7 @@ import type { Metadata } from "next"; import localFont from "next/font/local"; import "./globals.css"; import { SessionProviders } from "./_provider"; -import Navbar from "@/components/Navbar"; +import Navbar from "@/components/landing/Appbar/Navbar"; const geistSans = localFont({ src: "./fonts/GeistVF.woff", diff --git a/apps/client/app/page.tsx b/apps/client/app/page.tsx index 7ebd8583..ab0ba6fc 100644 --- a/apps/client/app/page.tsx +++ b/apps/client/app/page.tsx @@ -1,41 +1,33 @@ -import { Navbar } from "@/components/Navbar"; +import { Navbar } from "@/components/landing/Appbar/Navbar"; import { HeroComp } from "@/components/HeroComp"; import ToggleSections from "@/components/ToogleSections"; import { TradeComp } from "@/components/TradeComp"; import { DownloadBanner } from "@/components/DownloadBanner"; import TradingNewsComponent from "@/components/TradingNewsComponent"; -import FeatureComponent from "@/components/Features"; -import ProboCare from "@/components/ProboCare"; +import FeatureComponent from "@/components/landing/Home/Features"; +import ProboCare from "@/components/landing/Home/ProboCare"; export default function Page() { return (
- -
-
-
-
-
-
-
diff --git a/apps/client/components/ToogleSections.tsx b/apps/client/components/ToogleSections.tsx index a84fa5cb..e1194b13 100644 --- a/apps/client/components/ToogleSections.tsx +++ b/apps/client/components/ToogleSections.tsx @@ -26,7 +26,7 @@ const ToggleSections = () => { }; return ( -
+
{/* Toggle buttons */}
diff --git a/apps/client/components/landing/Appbar.tsx b/apps/client/components/landing/Appbar/Appbar.tsx similarity index 100% rename from apps/client/components/landing/Appbar.tsx rename to apps/client/components/landing/Appbar/Appbar.tsx diff --git a/apps/client/components/Navbar.tsx b/apps/client/components/landing/Appbar/Navbar.tsx similarity index 81% rename from apps/client/components/Navbar.tsx rename to apps/client/components/landing/Appbar/Navbar.tsx index f0a3917f..129b89c2 100644 --- a/apps/client/components/Navbar.tsx +++ b/apps/client/components/landing/Appbar/Navbar.tsx @@ -1,28 +1,27 @@ "use client"; - import { useState } from "react"; import { Menu, X } from "lucide-react"; +import Link from "next/link"; import { WhiteBtn } from "@/components/WhiteBtn"; import { BlackBtn } from "@/components/BlackBtn"; export const Navbar = () => { - const [isMenuOpen, setIsMenuOpen] = useState(false); + const [isMenuOpen, setIsMenuOpen] = useState(false); const toggleMenu = () => setIsMenuOpen(!isMenuOpen); const navItems = [ { name: "Events", path: "/events" }, { name: "Portfolio", path: "/portfolio" }, - { name: "Recharge", path: "/recharge" }, + { name: "Recharge", path: "/wallet/deposit" }, ]; - const NavButton = ({ children, onClick }: any) => ( - + const NavButton = ({ children, path }:any) => ( + + + ); return ( @@ -30,15 +29,17 @@ export const Navbar = () => {
{/* Logo */}
+ +
{/* Desktop Navigation */}
{navItems.map((item) => ( - {}}> + {item.name} ))} @@ -70,9 +71,8 @@ export const Navbar = () => { {navItems.map((item) => ( { - toggleMenu(); - }} + path={item.path} + onClick={toggleMenu} > {item.name} diff --git a/apps/client/components/landing/Navmenu.tsx b/apps/client/components/landing/Appbar/Navmenu.tsx similarity index 100% rename from apps/client/components/landing/Navmenu.tsx rename to apps/client/components/landing/Appbar/Navmenu.tsx diff --git a/apps/client/components/landing/ProfileHeader.tsx b/apps/client/components/landing/Appbar/ProfileHeader.tsx similarity index 93% rename from apps/client/components/landing/ProfileHeader.tsx rename to apps/client/components/landing/Appbar/ProfileHeader.tsx index d3901329..dbe4114d 100644 --- a/apps/client/components/landing/ProfileHeader.tsx +++ b/apps/client/components/landing/Appbar/ProfileHeader.tsx @@ -1,6 +1,6 @@ "use client"; import React from "react"; -import { Button } from "../ui/button"; +import { Button } from "../../ui/button"; import Link from "next/link"; import { useSession } from "next-auth/react"; diff --git a/apps/client/components/landing/Singin.tsx b/apps/client/components/landing/Auth/Singin.tsx similarity index 100% rename from apps/client/components/landing/Singin.tsx rename to apps/client/components/landing/Auth/Singin.tsx diff --git a/apps/client/components/landing/FAQs.tsx b/apps/client/components/landing/Home/FAQs.tsx similarity index 100% rename from apps/client/components/landing/FAQs.tsx rename to apps/client/components/landing/Home/FAQs.tsx diff --git a/apps/client/components/Features.tsx b/apps/client/components/landing/Home/Features.tsx similarity index 100% rename from apps/client/components/Features.tsx rename to apps/client/components/landing/Home/Features.tsx diff --git a/apps/client/components/landing/Hero.tsx b/apps/client/components/landing/Home/Hero.tsx similarity index 100% rename from apps/client/components/landing/Hero.tsx rename to apps/client/components/landing/Home/Hero.tsx diff --git a/apps/client/components/ProboCare.tsx b/apps/client/components/landing/Home/ProboCare.tsx similarity index 100% rename from apps/client/components/ProboCare.tsx rename to apps/client/components/landing/Home/ProboCare.tsx diff --git a/apps/client/components/landing/TakesCare.tsx b/apps/client/components/landing/Home/TakesCare.tsx similarity index 100% rename from apps/client/components/landing/TakesCare.tsx rename to apps/client/components/landing/Home/TakesCare.tsx diff --git a/apps/client/components/landing/Orderbook.tsx b/apps/client/components/landing/Orderbook/Orderbook.tsx similarity index 100% rename from apps/client/components/landing/Orderbook.tsx rename to apps/client/components/landing/Orderbook/Orderbook.tsx diff --git a/apps/client/components/landing/Portfolio.tsx b/apps/client/components/landing/Portfolio/Portfolio.tsx similarity index 100% rename from apps/client/components/landing/Portfolio.tsx rename to apps/client/components/landing/Portfolio/Portfolio.tsx diff --git a/apps/client/components/landing/DepositForm.tsx b/apps/client/components/landing/Recharge/DepositForm.tsx similarity index 100% rename from apps/client/components/landing/DepositForm.tsx rename to apps/client/components/landing/Recharge/DepositForm.tsx diff --git a/packages/db/prisma/schema.prisma b/packages/db/prisma/schema.prisma index 2f7f0717..ed1f3f0c 100644 --- a/packages/db/prisma/schema.prisma +++ b/packages/db/prisma/schema.prisma @@ -10,7 +10,7 @@ datasource db { model User { id String @id @default(cuid()) phoneNumber String @unique - balance Float @default(0.0) + balance Int @default(0) role UserRole createdAt DateTime @default(now()) updatedAt DateTime @default(now()) diff --git a/packages/zod/src/index.ts b/packages/zod/src/index.ts index ed816cc9..361a3e77 100644 --- a/packages/zod/src/index.ts +++ b/packages/zod/src/index.ts @@ -1,5 +1,11 @@ import z from "zod" -z.object({ - // -}) \ No newline at end of file +export const userZodSchema= z.object({ + phoneNumber: z.string().min(10), + blanace: z.number(), + role: z.string(), +}) + +export const orderbookZodSchema= z.object({ + +}) \ No newline at end of file From fa02a333b842fba21635335de230bcba9e8d155a Mon Sep 17 00:00:00 2001 From: Prashant Varma Date: Thu, 17 Oct 2024 02:10:44 +0530 Subject: [PATCH 2/2] [feat]: cashfree integration + FE code refactor --- .../app/(lobby)/wallet/deposit/page.tsx | 47 +++++++++++-------- .../app/(lobby)/wallet/withdraw/page.tsx | 16 ++----- .../app/api/{ => payment}/initiate/route.ts | 0 .../{ => payment}/status/[order_id]/route.ts | 0 apps/client/app/globals.css | 3 +- apps/client/app/layout.tsx | 5 +- .../components/ui/OtpVerificationForm.tsx | 3 +- apps/client/lib/cashfree.js | 4 ++ apps/client/package.json | 1 + 9 files changed, 41 insertions(+), 38 deletions(-) rename apps/client/app/api/{ => payment}/initiate/route.ts (100%) rename apps/client/app/api/{ => payment}/status/[order_id]/route.ts (100%) create mode 100644 apps/client/lib/cashfree.js diff --git a/apps/client/app/(lobby)/wallet/deposit/page.tsx b/apps/client/app/(lobby)/wallet/deposit/page.tsx index b715cfee..d1211793 100644 --- a/apps/client/app/(lobby)/wallet/deposit/page.tsx +++ b/apps/client/app/(lobby)/wallet/deposit/page.tsx @@ -1,14 +1,16 @@ "use client"; - import React, { useState, useEffect } from "react"; import axios from "axios"; +import { cashfree } from "@/lib/cashfree"; +import {toast} from "react-hot-toast" const Page = () => { const [amount, setAmount] = useState(""); const [gst, setGst] = useState(0); const [showSummary, setShowSummary] = useState(false); - const [sessionId, setSession] = useState(""); - + const paymentUrl = process.env.NEXT_PUBLIC_BASE_URL as string + + process.env.NEXT_PUBLIC_PAYMENT_INITIATE_URL_ENDPOINT as string; + useEffect(() => { const numAmount = parseFloat(amount); if (!isNaN(numAmount) && numAmount > 0) { @@ -19,19 +21,26 @@ const Page = () => { setShowSummary(!isNaN(numAmount) && numAmount >= 5); }, [amount]); - const handleAmountChange = (e: React.ChangeEvent) => { - setAmount(e.target.value); - }; - - const handleQuickAmount = (value: number) => { - setAmount(value.toString()); - }; - - async function handleRechange(){ - const result = await axios.post(process.env.NEXT_PUBLIC_BASE_URL + '/api/initiate', { + async function handleRechargeClick() { + const res = await axios.post(paymentUrl, { + order_id: "order_id_random" + Date.now(), + customer_id: "customer_id_random" + Date.now(), + customer_phone: "9876543210", + order_amount: amount, + }); + const checkoutOptions = { + paymentSessionId: res.data.payment_session_id, + returnUrl: process.env.BASE_URL, + }; + cashfree.checkout(checkoutOptions).then(function (result: { + error: string; + redirect: string; + }) { + if (result.error) { + toast.error("Error in depositing money! please try again") + } }); - console.log(result); } return ( @@ -46,7 +55,7 @@ const Page = () => { setAmount(e.target.value)} className="border border-blue-400 w-full rounded-md h-10 px-3" />
@@ -57,19 +66,19 @@ const Page = () => { )}
diff --git a/apps/client/app/(lobby)/wallet/withdraw/page.tsx b/apps/client/app/(lobby)/wallet/withdraw/page.tsx index 42927e20..867b5768 100644 --- a/apps/client/app/(lobby)/wallet/withdraw/page.tsx +++ b/apps/client/app/(lobby)/wallet/withdraw/page.tsx @@ -1,19 +1,9 @@ "use client"; - -import { useState, ChangeEvent } from "react"; +import { useState } from "react"; const Page = () => { const [amount, setAmount] = useState(0); const [account, setAccount] = useState(""); - - const handleAmountChange = (e: ChangeEvent) => { - setAmount(Number(e.target.value)); - }; - - const handleAccountChange = (e: ChangeEvent) => { - setAccount(e.target.value); - }; - return ( <>
@@ -31,7 +21,7 @@ const Page = () => { type="number" id="amount" value={amount} - onChange={handleAmountChange} + onChange={(e) => setAmount(Number(e.target.value))} className="border border-blue-400 w-full rounded-md h-10 px-3" />
@@ -54,7 +44,7 @@ const Page = () => { type="text" id="account" value={account} - onChange={handleAccountChange} + onChange={(e) => setAccount(e.target.value)} className="border w-full rounded-md h-10 px-3" />
diff --git a/apps/client/app/api/initiate/route.ts b/apps/client/app/api/payment/initiate/route.ts similarity index 100% rename from apps/client/app/api/initiate/route.ts rename to apps/client/app/api/payment/initiate/route.ts diff --git a/apps/client/app/api/status/[order_id]/route.ts b/apps/client/app/api/payment/status/[order_id]/route.ts similarity index 100% rename from apps/client/app/api/status/[order_id]/route.ts rename to apps/client/app/api/payment/status/[order_id]/route.ts diff --git a/apps/client/app/globals.css b/apps/client/app/globals.css index c7bba5cc..16c47d13 100644 --- a/apps/client/app/globals.css +++ b/apps/client/app/globals.css @@ -126,9 +126,8 @@ body { @tailwind components; @tailwind utilities; body{ - overflow-x: hidden; + overflow-x: hidden } - html { @apply bg-gray-100; } \ No newline at end of file diff --git a/apps/client/app/layout.tsx b/apps/client/app/layout.tsx index 22bcaaa4..a061e165 100644 --- a/apps/client/app/layout.tsx +++ b/apps/client/app/layout.tsx @@ -3,6 +3,7 @@ import localFont from "next/font/local"; import "./globals.css"; import { SessionProviders } from "./_provider"; import Navbar from "@/components/landing/Appbar/Navbar"; +import { Toaster } from "react-hot-toast"; const geistSans = localFont({ src: "./fonts/GeistVF.woff", @@ -25,14 +26,14 @@ export default function RootLayout({ }: Readonly<{ children: React.ReactNode; }>) { - return ( - + {children} + ); diff --git a/apps/client/components/ui/OtpVerificationForm.tsx b/apps/client/components/ui/OtpVerificationForm.tsx index 528049a8..76834f7a 100644 --- a/apps/client/components/ui/OtpVerificationForm.tsx +++ b/apps/client/components/ui/OtpVerificationForm.tsx @@ -17,7 +17,7 @@ import { } from "@/components/ui/input-otp"; import { verifySMSOTPAction } from "@/actions/OTP/validateOtp"; import { signIn } from "next-auth/react"; -import { Toaster, toast } from "react-hot-toast"; +import { toast } from "react-hot-toast"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { Loader2 } from "lucide-react"; @@ -93,7 +93,6 @@ export function InputOTPForm({ phoneNumber }: InputOTPFormProps) { {!isLoading ? "Submit" : } - ); } diff --git a/apps/client/lib/cashfree.js b/apps/client/lib/cashfree.js new file mode 100644 index 00000000..ea521493 --- /dev/null +++ b/apps/client/lib/cashfree.js @@ -0,0 +1,4 @@ +import {load} from '@cashfreepayments/cashfree-js'; +export const cashfree = await load({ + mode: "sandbox" //or production +}); \ No newline at end of file diff --git a/apps/client/package.json b/apps/client/package.json index 9f847b6c..bc113011 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "@cashfreepayments/cashfree-js": "^1.0.5", "@hookform/resolvers": "^3.9.0", "@next-auth/prisma-adapter": "^1.0.7", "@prisma/client": "^5.20.0",