diff --git a/package-lock.json b/package-lock.json index a07e319..d478d09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,8 @@ "react-redux": "^9.1.0", "react-router-dom": "^6.21.2", "recharts": "^2.11.0", - "use-places-autocomplete": "^4.0.1" + "use-places-autocomplete": "^4.0.1", + "zustand": "^4.5.1" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.17.20", @@ -6434,6 +6435,33 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zustand": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.1.tgz", + "integrity": "sha512-XlauQmH64xXSC1qGYNv00ODaQ3B+tNPoy22jv2diYiP4eoDKr9LA+Bh5Bc3gplTrFdb6JVI+N4kc1DZ/tbtfPg==", + "dependencies": { + "use-sync-external-store": "1.2.0" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } } } } diff --git a/package.json b/package.json index 4d51618..b1a89b2 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "react-redux": "^9.1.0", "react-router-dom": "^6.21.2", "recharts": "^2.11.0", - "use-places-autocomplete": "^4.0.1" + "use-places-autocomplete": "^4.0.1", + "zustand": "^4.5.1" }, "devDependencies": { "@tanstack/eslint-plugin-query": "^5.17.20", diff --git a/src/App.tsx b/src/App.tsx index 5f440a5..8e7e441 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,7 @@ import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; import AppLayout from "./client/pages/AppLayout"; import Home from "./client/pages/Home"; import Contact from "./client/pages/Contact"; -import Register from "./client/pages/Register"; +// import Register from "./client/pages/Register"; import Blog from "./client/pages/Blog"; import About from "./client/pages/About"; import Download from "./client/pages/Download"; @@ -22,6 +22,10 @@ import { RepositoryProvider } from "./provider/RepositoryProvider"; import DriverInfo from "./admin/pages/DriverInfoPage"; import RidesHistory from "./admin/components/RidesHistory/RidesHistory"; import { RideInfo } from "./admin/components/Rides/RideInfo"; +import FormWithNumber from "./client/components/register/FormWithNumber"; +import OtpForm from "./client/components/register/OtpForm"; +import UserRegisterform from "./client/components/register/UserRegisterForm"; +// import BlogAdmin from "./admin/components/Blog/BlogAdmin"; function App() { return ( @@ -32,7 +36,9 @@ function App() { }> } /> } /> - } /> + } /> + } /> + } /> } /> } /> } /> @@ -42,7 +48,7 @@ function App() { } /> } /> } /> - } /> + } /> } /> } /> } /> @@ -51,28 +57,29 @@ function App() { } /> - } /> - - - + } /> + + + + ); diff --git a/src/Storemanagement/Store.ts b/src/Storemanagement/Store.ts new file mode 100644 index 0000000..18366c2 --- /dev/null +++ b/src/Storemanagement/Store.ts @@ -0,0 +1,10 @@ +import{ create} from 'zustand'; +interface PaginationState { + currentPage: number; + setCurrentPage: (page: number) => void; +} + +export const usePaginationStore = create((set) => ({ + currentPage: 1, + setCurrentPage: (page) => set({ currentPage: page }), +})); \ No newline at end of file diff --git a/src/admin/action/FetchOnlineDriverData.ts b/src/admin/action/FetchOnlineDriverData.ts new file mode 100644 index 0000000..435e367 --- /dev/null +++ b/src/admin/action/FetchOnlineDriverData.ts @@ -0,0 +1,29 @@ +import { useEffect, useState } from 'react'; +import { OnlineDriver } from '@/types/data'; +import _ from 'lodash'; +import { Repository } from '@/repositories/Repository'; + +export function useOnlineDrivers(repo: Repository): OnlineDriver[] | null { + const [onlineDrivers, setOnlineDrivers] = useState(null); + + useEffect(() => { + const fetchData = async () => { + try { + const data = await repo.getAllOnlineDriver(); + if (_.isArray(data)) { + setOnlineDrivers(data); + } else { + console.error('Data is not in the expected format:', data); + setOnlineDrivers(null); + } + } catch (error) { + console.error('Error fetching data:', error); + setOnlineDrivers(null); + } + }; + + fetchData(); + }, [repo]); + + return onlineDrivers; +} diff --git a/src/admin/components/Blog/BlogAdmin.tsx b/src/admin/components/Blog/BlogAdmin.tsx new file mode 100644 index 0000000..f023a06 --- /dev/null +++ b/src/admin/components/Blog/BlogAdmin.tsx @@ -0,0 +1,105 @@ +import { useRepository } from '@/hooks/CustomHook'; +import { BlogPostFormData } from '@/types/data'; +import React from 'react'; +import { SubmitHandler, useForm } from 'react-hook-form'; +import toast from 'react-hot-toast'; +import BlogSection from './BlogSection'; + +const BlogAdmin: React.FC = () => { + const { register, handleSubmit, formState: { errors } } = useForm(); + const repository = useRepository(); + + const onSubmit: SubmitHandler = async (data ) => { + const formData = new FormData(); + formData.append('title', data.title); + formData.append('content', data.content); + if (data.photo) { + formData.append('blogImage', data.photo[0]); + } + if (data.video) { + formData.append('blogVideo', data.video[0]); + } + + try { + const response = await repository.repo.createBlogPost(formData); + if (response) { + toast.success('Blog post submitted successfully!'); + console.log(data) + } else { + toast.error('Failed to submit blog post!'); + console.log(data) + } + } catch (error) { + console.error('Error submitting blog post:', error); + console.log(data) + toast.error('An error occurred while submitting blog post!'); + } + }; +return ( + <> +
+

Blog Section

+
+
+ + + {errors.title && Title is required} +
+
+ + + {errors.content && Content is required} +
+
+ + +
+
+ + +
+
+ +
+
+
+ + + ); +}; + +export default BlogAdmin; diff --git a/src/admin/components/Blog/BlogSection.tsx b/src/admin/components/Blog/BlogSection.tsx new file mode 100644 index 0000000..ec2149a --- /dev/null +++ b/src/admin/components/Blog/BlogSection.tsx @@ -0,0 +1,101 @@ +import React from 'react' + +function BlogSection() { + return ( + <> + + +
+
+

Blog Section

+
+ + + +
+ +
Noteworthy technology acquisitions 2021
+
+

Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.

+ + Read more + + +
+
+ +
+ +
+

Blog Section

+
+ + + +
+ +
Noteworthy technology acquisitions 2021
+
+

Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.

+ + Read more + + +
+
+ +
+ +
+

Blog Section

+
+ + + +
+ +
Noteworthy technology acquisitions 2021
+
+

Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.

+ + Read more + + +
+
+ +
+
+

Blog Section

+
+ + + +
+ +
Noteworthy technology acquisitions 2021
+
+

Here are the biggest enterprise technology acquisitions of 2021 so far, in reverse chronological order.

+ + Read more + + +
+
+ +
+ +
+ + ) +} + +export default BlogSection diff --git a/src/admin/components/OnlineDriver/OnlineDriverTable.tsx b/src/admin/components/OnlineDriver/OnlineDriverTable.tsx index c501ada..7f35a6a 100644 --- a/src/admin/components/OnlineDriver/OnlineDriverTable.tsx +++ b/src/admin/components/OnlineDriver/OnlineDriverTable.tsx @@ -2,9 +2,9 @@ import { useEffect, useState } from "react"; import { useRepository } from "@/hooks/CustomHook"; import { OnlineDriver } from "@/types/data"; import _ from "lodash"; -function OnlineDriverTable() { +export default function OnlineDriverTable() { const { repo } = useRepository(); - const [Onlinedrivers, setOnlineDrivers] = useState([]); + const [onlinedrivers, setOnlineDrivers] = useState([]); useEffect(() => { const fetchData = async () => { try { @@ -18,31 +18,31 @@ function OnlineDriverTable() { console.error("Error fetching data:", error); } }; - fetchData(); - // const intervalId = setInterval(fetchData, 1000); - // return () => clearInterval(intervalId); - }, [repo]); + const intervalId = setInterval(fetchData, 1000); + return () => clearInterval(intervalId); + }, []); return ( -
- - - - - - - - - - {Onlinedrivers.map((driver) => ( - - - - + <> +
+
NameStatusrating
{driver.name}{driver.Status}{driver.rating}
+ + + + + - ))} - -
NameStatusrating
-
+ + + {onlinedrivers.map((driver) => ( + + {driver.name} + {driver.Status} + {driver.rating} + + ))} + + + + ); -} -export default OnlineDriverTable; +} \ No newline at end of file diff --git a/src/admin/components/RidesHistory/RidesHistory.tsx b/src/admin/components/RidesHistory/RidesHistory.tsx index a864e1b..63be298 100644 --- a/src/admin/components/RidesHistory/RidesHistory.tsx +++ b/src/admin/components/RidesHistory/RidesHistory.tsx @@ -4,7 +4,7 @@ import { useLocation } from 'react-router-dom'; function RidesHistory() { - // const [filterValue, setFilterValue] = useState("all"); + const location = useLocation(); const userId = location.state?.userId; @@ -14,7 +14,7 @@ function RidesHistory() {

Rides History

setFilterValue(e.target.value)} > - + -
diff --git a/src/admin/pages/Logout.tsx b/src/admin/pages/Logout.tsx index de3181d..805bfdd 100644 --- a/src/admin/pages/Logout.tsx +++ b/src/admin/pages/Logout.tsx @@ -1,3 +1,42 @@ -export default function Logout() { - return
Logout
; -} + import React, { useState } from 'react'; + import { useNavigate } from 'react-router-dom'; + + const Logout: React.FC = () => { + const navigate = useNavigate(); + const [showConfirmation, setShowConfirmation] = useState(true); + + const handleLogout = () => { + + localStorage.removeItem('accessToken'); + + navigate('/login'); + }; + + return ( + <> + {showConfirmation && ( +
+
+

Are you sure you want to quit?

+
+ + +
+
+
+ )} + + ); + }; + + export default Logout; diff --git a/src/admin/pages/Passengers.tsx b/src/admin/pages/Passengers.tsx index b3b5064..af5aa2c 100644 --- a/src/admin/pages/Passengers.tsx +++ b/src/admin/pages/Passengers.tsx @@ -1,14 +1,23 @@ +import { useState } from "react"; import PassengerTable from "../components/passenger/PassengerTable"; function Passengers() { + const [filterValue, setFilterValue] = useState(""); return (
-
-

All Passengers

-

filter/sort

+
+

All Drivers

+
- +
); diff --git a/src/api/Api.ts b/src/api/Api.ts index 85e63f9..7ee032d 100644 --- a/src/api/Api.ts +++ b/src/api/Api.ts @@ -1,15 +1,16 @@ import { IStorageClient } from "@/storage/types"; import { IJsonApi, JsonAPIResp } from "./type"; +import { loginRequest } from "@/types/data"; export class API implements IJsonApi { private BASE_URL: string; private _localStorageClient: IStorageClient; + constructor(baseUrl: string, localStorageClient: IStorageClient) { this.BASE_URL = baseUrl; this._localStorageClient = localStorageClient; } - //building the headers private _buildHeaders(headers: Map): Headers { const _headers = new Headers(); headers.forEach((value, key) => { @@ -17,74 +18,78 @@ export class API implements IJsonApi { }); return _headers; } - private async _parseResponse(response: Response): Promise { - if (response.ok) { - if (response.status === 204) { - return undefined as T; - } + + private async _parseResponse(response: Response): Promise> { + const json = await response.json(); + console.log(json); + if (!response.ok) { + throw new Error(json.message || "Failed to fetch data"); } - return response.json() as T; + return json; } - // Makes an API call with provided request parameters + private async _request( path: string, method: string, isAuthorized: boolean, headers: Map, - body?: FormData | null + body?: loginRequest |null ): Promise> { - headers.set("Content-Type", "multipart/form-data"); + const _headers = this._buildHeaders(headers); - // Add authorization header if necessary if (isAuthorized) { const accessToken = await this._localStorageClient.getAccessToken(); _headers.append("Authorization", `Bearer ${accessToken}`); } - // Configure options for the request - const requestOption: RequestInit = { + // if(body){ + // console.log("at api body data: "); + // for (const [key, value] of body) { + // console.log(`${key}: ${value}\n`); + // } + // } + const requestOptions: RequestInit = { method: method, headers: _headers, + body: JSON.stringify(body), }; - // Add body to request options if it's not undefined - if (body !== undefined && body !== null) { - console.log("at api"); - for (const [key, value] of body) { - console.log(`${key}: ${value}\n`); - } - requestOption.body = body; - } - // Make the request to the API - const response = await fetch(`${this.BASE_URL}${path}`, requestOption); + + const url = `${this.BASE_URL}${path}`; + const response = await fetch(url, requestOptions); console.log(response); - const apiResponse = await this._parseResponse>(response); - return apiResponse; + + const res= this._parseResponse(response); + console.log("at api " +res); + return res; } - get( + async get( path: string, headers: Map = new Map(), isAuthorized: boolean = true ): Promise> { - return this._request(path, "GET", isAuthorized, headers); + return this._request(path, "GET", isAuthorized, headers); } - post( + + async post( path: string, - body?: FormData | null, + body?:loginRequest| null, headers: Map = new Map(), isAuthorized: boolean = true ): Promise> { return this._request(path, "POST", isAuthorized, headers, body); } - put( + + async put( path: string, - body?: FormData | null, + body?: loginRequest| null, headers: Map = new Map(), isAuthorized: boolean = true ): Promise> { return this._request(path, "PUT", isAuthorized, headers, body); } - delete( + + async delete( path: string, headers: Map = new Map(), isAuthorized: boolean = true diff --git a/src/api/type.d.ts b/src/api/type.d.ts index ba64965..d4c0234 100644 --- a/src/api/type.d.ts +++ b/src/api/type.d.ts @@ -1,4 +1,4 @@ -import { Pagination } from "@/types/data"; +import { Pagination, loginRequest } from "@/types/data"; export declare type JsonAPIObjectResp = { data: T; @@ -7,7 +7,7 @@ export declare type JsonAPIObjectResp = { declare type JsonAPIError = { status: string; title: string; - detail: string?; + detail?: string?; }; export declare type JsonAPIErrorResp = { errors?: JsonAPIError[]; @@ -24,15 +24,15 @@ declare interface IJsonApi { ): Promise>; post( - path: string, - body: FormData | null, + path: string, + body: loginRequest | null, headers: Map = new Map(), isAuthorized: boolean = true ): Promise>; put( - path: string, - body?: FormData | null, + path: string, + body?: loginRequest | null, headers: Map = new Map(), isAuthorized: boolean = true ): Promise>; diff --git a/src/client/components/DownloadLink.tsx b/src/client/components/DownloadLink.tsx index a7fda8d..5c91829 100644 --- a/src/client/components/DownloadLink.tsx +++ b/src/client/components/DownloadLink.tsx @@ -1,51 +1,61 @@ +import React from "react"; + function DownloadLink() { return ( -
-
-
-
-
-

Download the app

- -

- Download now & avail our service through the app -

-

- Download the app -

-
-
- -
-

Download on

-

- {" "} - Google Play Store{" "} -

-
+
+
+
+
+

+ Download the app +

+

+ Download now & avail our service through the app +

+

+ Download the app +

+
+
+ Google Play Store +
+

Download on

+

Google Play Store

-
- -
-

Download on

-

- {" "} - Apple Store{" "} -

-
+
+
+ Apple App Store +
+

Download on

+

Apple App Store

- -
-
-
+
+
+ {/* Optimize background image by specifying dimensions and loading it lazily */} +
diff --git a/src/client/components/about/About_uscompo.tsx b/src/client/components/about/About_uscompo.tsx index 8244bad..e6f671d 100644 --- a/src/client/components/about/About_uscompo.tsx +++ b/src/client/components/about/About_uscompo.tsx @@ -1,8 +1,12 @@ -import aboutUs from "@/utils/aboutus.json"; + +import HeroAbout from "./HeroAbout"; +import Qa from "./Qa"; + +// import aboutUs from "@/utils/aboutus.json"; function About_uscompo() { return ( -
-
+
+ {/*
@@ -29,7 +33,11 @@ function About_uscompo() {
-
+
*/} + + + +
); } diff --git a/src/client/components/about/HeroAbout.tsx b/src/client/components/about/HeroAbout.tsx new file mode 100644 index 0000000..e95f060 --- /dev/null +++ b/src/client/components/about/HeroAbout.tsx @@ -0,0 +1,44 @@ +import Button from "../shared/Button" + + +function Hero() { + return ( +
+
+ + +
+
+
+
+

Dhoka
your Ride

+ +

Dhoka is a transportation technology providing a full range of app-based services including ride-sharing, food delivery and free games.

+

+
+
+ +
+ Rickshaw +
+
+
+
+ + + +
+ ) +} + + +export default Hero diff --git a/src/client/components/about/Qa.tsx b/src/client/components/about/Qa.tsx new file mode 100644 index 0000000..9598d1a --- /dev/null +++ b/src/client/components/about/Qa.tsx @@ -0,0 +1,46 @@ +import TeamMember from "./TeamMember" + + +function Qa() { + return ( +
+ + + +
+
+
+

+ What is Dhoka? +

+ +

Dhoka is the biggest and most popular ride-hailing service provider in Hetauda, it is among the fastest-growing tech startups in Asia, dedicated to develop optimal solutions for daily transportation problems of the public. It was founded in 2024 in the Nepal and officially started on jaunary 24, 2024, in Hetauda.

+ + +
+ +
+

+ What Dhoka Does? +

+ +

Dhoka offers mobility solutions by providing economical ride-sharing along with a wide range of vehicles across tuktuk"Auto" . We also serve consumers with fast food deliveries ensuring a happy meal experience.

+ + +
+
+
+ + + + + + + + + +
+ ) +} + +export default Qa diff --git a/src/client/components/about/TeamMember.tsx b/src/client/components/about/TeamMember.tsx new file mode 100644 index 0000000..ddacb44 --- /dev/null +++ b/src/client/components/about/TeamMember.tsx @@ -0,0 +1,32 @@ + +import TeamMemberCard from "./TeamMemberCard"; + +function TeamMember() { + const teamMembers = [ + { imageSrc: "nikita.jpg", name: "Nikita baini", role: "drawing " }, + { imageSrc: "smriti.jpg", name: "smriti upriti", role: "Flutter " }, + { imageSrc: "kals.JPG", name: "Shraddha Regmi", role: "Flutter Developer" }, + { imageSrc: "logo.jpg", name: "Bikal Rumba", role: "Flutter Developer" }, + { imageSrc: "dai.jpg", name: "Rahul Dai", role: "React Developer" }, + { imageSrc: "puja.jpg", name: "Puja Lama", role: "Backend Developer" }, + { imageSrc: "logo.jpg", name: "Niruta baini", role: "Backend Developer" } + + + + + ]; + + return ( +
+

Our Executive Team

+

This is our team.

+
+ {teamMembers.map((member, index) => ( + + ))} +
+
+ ); +} + +export default TeamMember; diff --git a/src/client/components/about/TeamMemberCard.tsx b/src/client/components/about/TeamMemberCard.tsx new file mode 100644 index 0000000..7a83c89 --- /dev/null +++ b/src/client/components/about/TeamMemberCard.tsx @@ -0,0 +1,21 @@ +import React from "react"; + +interface TeamMemberCardProps { + imageSrc: string; + name: string; + role: string; +} + +const TeamMemberCard: React.FC = ({ imageSrc, name, role }) => { + return ( +
+
+ {name} +

{name}

+

{role}

+
+
+ ); +}; + +export default TeamMemberCard; diff --git a/src/client/components/home/Banner.tsx b/src/client/components/home/Banner.tsx index 6dbafb4..a38f8ab 100644 --- a/src/client/components/home/Banner.tsx +++ b/src/client/components/home/Banner.tsx @@ -1,19 +1,21 @@ -import React from 'react'; -function Banner() { - return ( -
-
- - -
-
- ); +function Banner() { + return ( +
+
+ {/* Optimize image by specifying dimensions and loading it lazily */} + +
+
+ ); } -export default Banner; \ No newline at end of file +export default Banner; diff --git a/src/client/components/home/Earn_With_us.tsx b/src/client/components/home/Earn_With_us.tsx index 77c3293..9f32c11 100644 --- a/src/client/components/home/Earn_With_us.tsx +++ b/src/client/components/home/Earn_With_us.tsx @@ -1,35 +1,37 @@ -import React from "react"; + import Button from "../shared/Button"; function Earn_With_us() { return (
- {/* image section */} -
+
+ Rickshaw
-

+

Earn with your Auto or Rickshaw

    -
  • Drive at anytime and on any day of the week
  • +
  • Drive at any time and on any day of the week
  • Scope to earn more with Dhoka
  • Get your payment on time with Dhoka
-
+
diff --git a/src/client/components/home/Hero.tsx b/src/client/components/home/Hero.tsx index cd99398..db7749c 100644 --- a/src/client/components/home/Hero.tsx +++ b/src/client/components/home/Hero.tsx @@ -3,41 +3,41 @@ import Button from "../shared/Button"; export default function Hero() { const navigate = useNavigate(); + return ( - //hero section - //first section
-

+

Platform for all auto services

- One app, all services at your finger + One app, all services at your fingertips

-
- {/* image section */}
+ {/* Optimize hero image by specifying dimensions and loading it lazily */} Rickshaw
diff --git a/src/client/components/layout/Footer.tsx b/src/client/components/layout/Footer.tsx index 34986cd..0fa0611 100644 --- a/src/client/components/layout/Footer.tsx +++ b/src/client/components/layout/Footer.tsx @@ -1,4 +1,4 @@ -import React from 'react' + function Footer() { return ( @@ -7,8 +7,8 @@ function Footer() {
-
-
+
+

Download our Auto App

Enjoy Service. All day, every day.

@@ -20,7 +20,7 @@ function Footer() {

Google Play Store

-
+

Download on

@@ -29,14 +29,17 @@ function Footer() {
-
-

© Dhoka, 2021.

-
- About us - Contact us - Privacy Policy -
-
+
+
+

© Dhoka, 2021.

+
+
+ About us + Contact us + Privacy Policy +
+
+
diff --git a/src/client/components/register/FormWithNumber.tsx b/src/client/components/register/FormWithNumber.tsx index 3f5177f..4e3c438 100644 --- a/src/client/components/register/FormWithNumber.tsx +++ b/src/client/components/register/FormWithNumber.tsx @@ -5,18 +5,15 @@ import "react-phone-input-2/lib/style.css"; import toast from "react-hot-toast"; import { useState } from "react"; import { useRepository } from "@/hooks/CustomHook"; -import { FormWithNumberProp } from "@/types/data"; -export default function FormWithNumber({ - phone, - setPhone, - setConfirmed, - setCurrentForm, -}: FormWithNumberProp) { +import { useNavigate } from "react-router"; + +export default function FormWithNumber() { const { repo } = useRepository(); const [disabled, setDisabled] = useState(false); - - //sending otp to the user's phone + const [phone, setPhone] = useState(""); + const navigate = useNavigate(); + async function handlePhoneSubmit() { const regex = /977((986)|(985)|(984)|(981)|(982)|(980)|(976)|(975)|(974)|(971)|(972))\d{6}/; @@ -25,7 +22,7 @@ export default function FormWithNumber({ if (phone && isValid) { const response = await repo.isPhoneExist(phone); console.log(response); - if (response === null) { + if (response) { // console.log(response); setDisabled(true); try { @@ -38,8 +35,10 @@ export default function FormWithNumber({ `+${phone}`, recaptcha ); - setConfirmed(confirmation); - setCurrentForm(2); + + navigate("/checkOtp", { + state: { confirmed: confirmation, phone: phone }, + }); // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (err: any) { if (err.code === "auth/invalid-phone-number") { diff --git a/src/client/components/register/OtpForm.tsx b/src/client/components/register/OtpForm.tsx index d71fd35..7cdc518 100644 --- a/src/client/components/register/OtpForm.tsx +++ b/src/client/components/register/OtpForm.tsx @@ -1,23 +1,22 @@ import { useForm } from "react-hook-form"; import toast from "react-hot-toast"; -import { otpFormData, otpFormProps } from "@/types/data"; +import { otpFormData } from "@/types/data"; +import { useLocation, useNavigate } from "react-router"; -export default function OtpForm({ - phone, - confirmed, - setToken, - setCurrentForm, -}: otpFormProps) { +export default function OtpForm() { const { register, handleSubmit } = useForm(); - + const location = useLocation(); + const confirmed = location.state?.confirmed; + const phone = location.state?.phone; + const navigate = useNavigate(); //verifying the otp async function verifyOtp(data: otpFormData) { try { if (confirmed) { const response = await confirmed.confirm(data.otp); const token = (await response.user.getIdToken()).toString(); - setToken(token); - setCurrentForm(3); + navigate("/register", { state: { token: token, phone: phone } }); + // setCurrentForm(3); toast.success("User is verified successfully"); } // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/src/client/components/register/RegisterContainer.tsx b/src/client/components/register/RegisterContainer.tsx index eb932fe..0fce12c 100644 --- a/src/client/components/register/RegisterContainer.tsx +++ b/src/client/components/register/RegisterContainer.tsx @@ -1,41 +1,42 @@ -import { useState } from "react"; -import FormWithNumber from "./FormWithNumber"; -import { ConfirmationResult } from "firebase/auth"; -import OtpForm from "./OtpForm"; -import SelectUser from "./SelectUser"; -import UserDetailsForm from "./RegisterForm"; +// import { useState } from "react"; +// import FormWithNumber from "./FormWithNumber"; +// import { ConfirmationResult } from "firebase/auth"; +// import OtpForm from "./OtpForm"; +// // import SelectUser from "./SelectUser"; +// // import UserDetailsForm from "./RegisterForm"; +// import UserRegisterform from "./UserRegisterForm"; -export default function RegisterContainer() { - const [phone, setPhone] = useState(""); - const [confirmed, setConfirmed] = useState(null); - const [currentForm, setCurrentForm] = useState(1); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [token, setToken] = useState(""); - const [user, setUser] = useState(""); - switch (currentForm) { - case 1: - return ( - - ); - case 2: - return ( - - ); - case 3: - return ; - case 4: - return ; - default: - break; - } -} +// export default function RegisterContainer() { +// const [phone, setPhone] = useState(""); +// const [confirmed, setConfirmed] = useState(null); +// const [currentForm, setCurrentForm] = useState(1); +// // eslint-disable-next-line @typescript-eslint/no-unused-vars +// const [token, setToken] = useState(""); +// // const [user, setUser] = useState(""); +// switch (currentForm) { +// case 1: +// return ( +// +// ); +// case 2: +// return ( +// +// ); +// // case 3: +// // return ; +// case 4: +// return ; +// default: +// break; +// } +// } diff --git a/src/client/components/register/UserRegisterForm.tsx b/src/client/components/register/UserRegisterForm.tsx index e89ff06..3dfd61d 100644 --- a/src/client/components/register/UserRegisterForm.tsx +++ b/src/client/components/register/UserRegisterForm.tsx @@ -1,44 +1,30 @@ import { useForm } from "react-hook-form"; import toast from "react-hot-toast"; -import { useNavigate } from "react-router-dom"; +import { useLocation, useNavigate } from "react-router-dom"; import { useRepository } from "@/hooks/CustomHook"; import { formValueData, userFormType } from "@/types/data"; import formData from "@/utils/RegisterInputFormData.json"; import _ from "lodash"; -type userDetailsFormProps = { - phoneNumber: string; - // token: string | undefined; - userRole: string; -}; - -export default function UserRegisterform({ - phoneNumber, - // token, - userRole, -}: userDetailsFormProps) { +export default function UserRegisterform() { const { register, handleSubmit } = useForm(); const navigate = useNavigate(); - const { repo } = useRepository(); + const location = useLocation(); + const phoneNumber = location.state?.phone; + const token = location.state?.token; async function handleUserDataSubmit(data: userFormType) { console.log("data", data); const formData = new FormData(); - const fields = [ - "firstName", - "lastName", - "address", - "password", - "userImage", - ]; + const fields = ["firstName", "lastName", "password", "userImage"]; fields.forEach((field) => { if (data[field]) { if (_.isArray(data[field])) { const fileList: FileList = data[field] as FileList; if (fileList.length > 0) { const file: File = fileList[0]; - formData.append(`${field}`, file); - formData.append(`${field}Name`, file.name); + formData.append(`${field}File`, file); + formData.append(`${field}`, file.name); } } else { formData.append(`${field}`, data[field] as string); @@ -46,7 +32,7 @@ export default function UserRegisterform({ } }); formData.append("phoneNumber", phoneNumber); - formData.append("userRole", userRole); + formData.append("firebaseToken", token); try { const response = await repo.registerUser(formData); console.log(response); @@ -70,9 +56,6 @@ export default function UserRegisterform({

Add your credentials

-
-

as a {userRole}

-
diff --git a/src/client/pages/Login.tsx b/src/client/pages/Login.tsx index 8b994e4..60aaf66 100644 --- a/src/client/pages/Login.tsx +++ b/src/client/pages/Login.tsx @@ -1,26 +1,50 @@ import { useForm } from "react-hook-form"; + import { useNavigate } from "react-router"; -import { useRepository } from "../../hooks/CustomHook"; -type loginForm = { + +type LoginForm = { phoneNumber: string; password: string; }; -function Login() { - const { repo } = useRepository(); - const { register, handleSubmit } = useForm(); +function Login() { + const { register, handleSubmit } = useForm(); const navigate = useNavigate(); - async function handleLogin(data: loginForm) { - const formData = new FormData(); - formData.append("phoneNumber", `977${data.phoneNumber}`); - formData.append("password", data.password); - const response = await repo.login(formData); - if (response) { - console.log(response); - navigate(""); + const base_url: string = import.meta.env.VITE_REACT_APP_LOGIN_ENDPOINT + + + async function handleLogin(data: LoginForm) { + const loginInfo = { + phoneNumber: `+977${data.phoneNumber}`, + password: data.password, + deviceToken: "abc", + }; + + try { + const response = await fetch(base_url, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(loginInfo), + }); + + if (response.ok) { + const responseData = await response.json(); + if (responseData.token) { + localStorage.setItem("accessToken", responseData.token); + navigate("/admin"); + } else { + console.error("Login failed:", responseData); + } + } else { + console.error("Login failed:", response.statusText); } + } catch (error) { + console.error("Login error:", error); } +} return ( <>
@@ -39,7 +63,7 @@ function Login() { @@ -53,7 +77,7 @@ function Login() { diff --git a/src/redux/slice/driverSlice.ts b/src/redux/slice/driverSlice.ts deleted file mode 100644 index b2d0255..0000000 --- a/src/redux/slice/driverSlice.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { AllDriver } from "@/types/data"; -import { createSlice } from "@reduxjs/toolkit"; -const initialState: AllDriver = []; -export const driverSlice = createSlice({ - name: "drivers", - initialState, - reducers: { - addDriver: (state, action) => { - state.push(action.payload); - }, - verifyDriver: (state, action) => { - const driver = state.find(action.payload); - if (driver) { - driver.accountVerifyStatus = true; - } - }, - }, -}); -export const { addDriver, verifyDriver } = driverSlice.actions; -export default driverSlice.reducer; diff --git a/src/redux/store.ts b/src/redux/store.ts deleted file mode 100644 index 475f57a..0000000 --- a/src/redux/store.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { configureStore } from "@reduxjs/toolkit"; -import driverReducer from "./slice/driverSlice"; -export const store = configureStore({ - reducer: { driverReducer }, -}); diff --git a/src/repositories/Repository.ts b/src/repositories/Repository.ts index 9999426..58dfb51 100644 --- a/src/repositories/Repository.ts +++ b/src/repositories/Repository.ts @@ -6,7 +6,12 @@ import { DriverVerifyResponse, OnlineDriverArray, Passenger, - RegisterResponse, + + loginRequest, + + // loginRequest, + + // RegisterResponse, loginResponse, } from "@/types/data"; import { IJsonApi, JsonAPIErrorResp, JsonAPIResp } from "@/api/type"; @@ -25,36 +30,36 @@ export class Repository implements IRepository { ? response : undefined; } - async registerUser( - userDetails: FormData | null - ): Promise { - const responseData = await this._api.post( - `users/register/passenger`, - userDetails, - undefined, - false - ); - console.log("at repository ", responseData); - return this._getResponse(responseData); - } + // async registerUser( + // userDetails: FormData | null + // ): Promise { + // const responseData = await this._api.post( + // `users/register/passenger`, + // userDetails, + // undefined, + // false + // ); + // console.log("at repository ", responseData); + // return this._getResponse(responseData); + // } - async registerDriver( - driverInfo: FormData | null - ): Promise { - const responseData = await this._api.post( - `users/register/driver`, - driverInfo, - undefined, - false - ); - console.log("at repository", responseData); - return this._getResponse(responseData); - } - async login( - loginInfo: FormData | null - ): Promise { + // async registerDriver( + // driverInfo: FormData | null + // ): Promise { + // const responseData = await this._api.post( + // `users/register/driver`, + // driverInfo, + // undefined, + // false + // ); + // console.log("at repository", responseData); + // return this._getResponse(responseData); + // } + async login( + loginInfo: loginRequest + ): Promise { const responseData = await this._api.post( - `users/login`, + `api/v1/users/login`, loginInfo, undefined, false @@ -65,20 +70,25 @@ export class Repository implements IRepository { phoneNumber: string ): Promise { const responseData = await this._api.get( - `users/checkPhone/${phoneNumber}` + `users/checkPhone/${phoneNumber}`, + undefined, + false ); + return this._getResponse(responseData); } async getAllDriver(): Promise { console.log("api", this._api); - const responseData = await this._api.get(`users/driver/get`); + const responseData = await this._api.get(`driverlist/`,undefined, + true); console.log(responseData); return this._getResponse(responseData); } async getDriverById( id: string ): Promise { - const responseData = await this._api.get(`users/driver/${id}`); + const responseData = await this._api.get(`users/driver/${id}`,undefined, + true); console.log("getDriverById:", responseData); return this._getResponse(responseData); } @@ -86,7 +96,8 @@ export class Repository implements IRepository { id: string ): Promise { const responseData = await this._api.get( - `users/verifyDriver/${id}` + `users/verifyDriver/${id}`,undefined, + true ); return this._getResponse(responseData); } @@ -94,27 +105,31 @@ export class Repository implements IRepository { JsonAPIErrorResp | AllPassenger | undefined > { const responseData = await this._api.get( - `users/passenger/get` - ); + `passengers/`,undefined, + true + );console.log(responseData) return this._getResponse(responseData); } async getPassengerById( id: string ): Promise { const responseData = await this._api.get( - `users/passenger/get/${id}` + `users/passenger/get/${id}`,undefined, + true ); return this._getResponse(responseData); } async getAllRides(): Promise { - const responseData = await this._api.get(`rides/getAll`); + const responseData = await this._api.get(`rides/getAll`,undefined, + true); return this._getResponse(responseData); } async getAllOnlineDriver(): Promise< JsonAPIErrorResp | OnlineDriverArray | undefined > { const responseData = await this._api.get( - `driver/onlineDriver/get` + `driver/onlineDriver/get`,undefined, + true ); return this._getResponse(responseData); } diff --git a/src/repositories/types.d.ts b/src/repositories/types.d.ts index 384acfe..17b548d 100644 --- a/src/repositories/types.d.ts +++ b/src/repositories/types.d.ts @@ -6,20 +6,23 @@ import { DriverVerifyResponse, OnlineDriverArray, Passenger, - RegisterResponse, + // loginRequest, + // RegisterResponse, loginResponse, } from "@/types/data"; import { JsonAPIErrorResp } from "../api/type"; + export interface IRepository { - registerUser( - userDetails: FormData | null - ): Promise; - registerDriver( - driverInfo: FormData | null - ): Promise; - login( - loginInfo: FormData - ): Promise; + // registerUser( + // userDetails: FormData | null + // ): Promise; + // registerDriver( + // driverInfo: FormData | null + // ): Promise; + + login( + loginInfo: loginRequest + ): Promise; isPhoneExist( phoneNumber: string ): Promise; diff --git a/src/storage/Storage.ts b/src/storage/Storage.ts index c5f840d..31da963 100644 --- a/src/storage/Storage.ts +++ b/src/storage/Storage.ts @@ -1,24 +1,16 @@ +// LocalStorageClient.ts import { IStorageClient } from "./types"; export class LocalStorageClient implements IStorageClient { - private storage: Storage; - - constructor(storage: Storage) { - this.storage = storage; - } async setAccessToken(accessToken: string): Promise { - this.storage.setItem("accessToken", accessToken); - } - async setRefreshToken(refreshToken: string): Promise { - this.storage.setItem("refreshToken", refreshToken); + localStorage.setItem("accessToken", accessToken); } + async getAccessToken(): Promise { - return this.storage.getItem("accessToken"); - } - async getRefreshToken(): Promise { - return this.storage.getItem("refreshToken"); + return localStorage.getItem("accessToken"); } + async clearTokens(): Promise { - this.storage.clear(); + localStorage.removeItem("accessToken"); } } diff --git a/src/storage/types.d.ts b/src/storage/types.d.ts index f22c709..7a41817 100644 --- a/src/storage/types.d.ts +++ b/src/storage/types.d.ts @@ -1,7 +1,5 @@ export declare interface IStorageClient { - getAccessToken(): Promise; - getRefreshToken(): Promise; + getAccessToken(): Promise; setAccessToken(accessToken: string): Promise; - setRefreshToken(refreshToken: string): Promise; clearTokens(): Promise; } diff --git a/src/types/data.d.ts b/src/types/data.d.ts index 00b9758..9c12fe2 100644 --- a/src/types/data.d.ts +++ b/src/types/data.d.ts @@ -6,14 +6,14 @@ type formValueData = { required: boolean; }; declare type UserRegisterRequest = { - userImage: File; + userImageFile: File; firstName: string; lastName: string; - address: string; + // address: string; phoneNumber: string; - userRole: string; + // userRole: string; password: string; - userImageName: string; + userImage: string; }; declare type DriverRegisterRequest = UserRegisterRequest & { @@ -31,7 +31,7 @@ declare type userFormType = { firstName: string; lastName: string; password: string; - address: string; + // address: string; userImage: FileList; [key: string]: string | FileList; }; @@ -61,77 +61,91 @@ declare type loginRequest = { phoneNumber: string; password: string; }; -declare type loginResponse = { - user: { - _id: string; - firstName: string; - lastName: string; - address: string; - status: boolean; - phoneNumber: string; - userRole: string; - userImage: string; - totalRide: number; - createdAt: DateTime; +declare type loginResponse= { + statusCode: number; + data: { + user: { + _id: string; + firstName: string; + lastName: string; + address: string; + status: boolean; + phoneNumber: string; + userRole: string; + userImage: string; + totalRide: number; + createdAt: string; + updatedAt: string; + __v: number; + }; + accessToken: string; + refreshToken: string; }; - accessToken: string; - refreshToken: string; -}; + message: string; + success: boolean; +} declare type Driver = { - _id: string; - liscenceNumber: string; - liscenceImage: string; + driverId: string; + licenseNumber: string; + licenseImage: string; accountVerifyStatus: boolean; availabilityStatus: boolean; - createdAt: string; - updatedAt: string; ratings: number; + totalRides: number; user: { - _id: string; + userId: string; firstName: string; lastName: string; address: string; status: boolean; phoneNumber: string; userImage: string; - totalRide: number; - userRole: string; + createdDate: string; + updatedDate: string; + role: number; }; vehicle: { - _id: string; - numberPlate: string; - color: string; + vehicleId: string; + vehicleNumber: string; + vehicleColor: string; vehicleImage: string; - billBookImage: string; + bluebookImage: string; }; }; -declare type AllDriver = { list: Driver[]; pagination: Pagination }; +declare type AllDriver = { list: Driver[]; meta: Pagination }; declare type DriverVerifyResponse = { _id: string; accountVerifyStatus: boolean; }; declare type Passenger = { - _id: string; + userId: string; + // _id: string; + firstName: string; lastName: string; address: string; status: boolean; phoneNumber: string; - userRole: boolean; - userImage: string; + userRole: number; + userImage: string| undefined; totalRide: number; - createdAt: string; - updatedAt: string; + createddate: string; + updateddate: string; }; declare type Pagination = { - totalPage: number; - totalItem: number; - previousPageNumber: number | null; - currentPageNumber: number; - nextPageNumber: number | null; + + totalPage: number; + totalItem: number; + previousPageNumber: number | null; + currentPageNumber: number; + nextPageNumber: number | null; + +}; +declare type AllPassenger = { + + list: Passenger[]; meta: Pagination }; -declare type AllPassenger = { list: Passenger[]; pagination: Pagination }; declare type Ride = { rideId: number; numberOfPassenger: number; @@ -151,7 +165,7 @@ declare type Ride = { }; declare type ALLRides = { list: Ride[]; - pagination: Pagination; + meta: Pagination; }; declare type OnlineDriver = { id: number; @@ -179,7 +193,7 @@ declare type DriverTableRowProp = { user: Driver; index: number; }; -declare type driverTableProp = { +declare type TableProp = { filterValue: string; }; declare interface OnlineDriver { diff --git a/src/utils/DriverRegisterFormValueData.json b/src/utils/DriverRegisterFormValueData.json new file mode 100644 index 0000000..7d4cd24 --- /dev/null +++ b/src/utils/DriverRegisterFormValueData.json @@ -0,0 +1,70 @@ +{ + "formValue": [ + { + "labelText": "First Name", + "id": "firstName", + "type": "text", + "required": true + }, + { + "labelText": "Last Name", + "id": "lastName", + "type": "text", + "required": true + }, + { + "labelText": "Password", + "id": "password", + "type": "text", + "required": true + }, + { + "labelText": "Address", + "id": "address", + "type": "text", + "required": true + }, + { + "labelText": "Driver Photo", + "id": "userImage", + "type": "file", + "required": true + }, + { + "labelText": "Liscence Number", + "id": "liscenceNumber", + "type": "text", + "required": true + }, + { + "labelText": "Liscence Image", + "id": "liscenceImage", + "type": "file", + "required": true + }, + { + "labelText": "BillBook Image", + "id": "billBookImage", + "type": "file", + "required": true + }, + { + "labelText": "Vehicle Number", + "id": "numberPlate", + "type": "text", + "required": true + }, + { + "labelText": "Vehicle Image", + "id": "vehicleImage", + "type": "file", + "required": true + }, + { + "labelText": "Vehicle Color", + "id": "color", + "type": "text", + "required": true + } + ] +} diff --git a/src/utils/RegisterInputFormData.json b/src/utils/RegisterInputFormData.json index 544fc88..0f6571d 100644 --- a/src/utils/RegisterInputFormData.json +++ b/src/utils/RegisterInputFormData.json @@ -86,12 +86,6 @@ "type": "text", "required": true }, - { - "labelText": "Address", - "id": "address", - "type": "text", - "required": true - }, { "labelText": "User Image", "id": "userImage", diff --git a/src/utils/RideTableData.json b/src/utils/RideTableData.json index 3e1a368..8a97af3 100644 --- a/src/utils/RideTableData.json +++ b/src/utils/RideTableData.json @@ -1,29 +1,36 @@ { - "data": [ - { - "rideId": 2, - "numberOfPassenger": 0, - "rideType": true, - "price": 0, - "message": "string", - "status": "Accepted", - "channelId": 944131329, - "driverId": "3fa85f64-5717-4562-b3fc-2c963f66afa7", - "driver": { - "firstName": "animesh", - "lastName": "dahal", - "userImage": "http://res.cloudinary.com/dvpbl8jew/image/upload/v1707460932/ndbwxojffarjqxffzcd3.jpg" - }, - "userId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", - "user": { - "firstName": "sagar", - "lastName": "adhikari", - "userImage": "http://res.cloudinary.com/dvpbl8jew/image/upload/v1707118010/pvmnfvaxdk5thb0evhrd.jpg" - }, - "pickupLocation_latitude": 27.429341, - "pickupLocation_longitude": 85.027136, - "dropLocation_latitude": 27.426872, - "dropLocation_longitude": 85.035022 + "data": { + "list": [ + { + "rideId": 2, + "numberOfPassenger": 0, + "rideType": true, + "price": 0, + "message": "string", + "status": "Accepted", + "driver": { + "firstName": "animesh", + "lastName": "dahal", + "userImage": "http://res.cloudinary.com/dvpbl8jew/image/upload/v1707460932/ndbwxojffarjqxffzcd3.jpg" + }, + "user": { + "firstName": "sagar", + "lastName": "adhikari", + "userImage": "http://res.cloudinary.com/dvpbl8jew/image/upload/v1707118010/pvmnfvaxdk5thb0evhrd.jpg" + }, + "pickupLocation_latitude": 27.429341, + "pickupLocation_longitude": 85.027136, + "dropLocation_latitude": 27.426872, + "dropLocation_longitude": 85.035022 + } + ], + "meta": { + "pageLimit": 10, + "totalPage": 1, + "totalItem": 2, + "previousPageNumber": null, + "currentPageNumber": 1, + "nextPageNumber": null } - ] + } } diff --git a/src/utils/UserRegisterFormValueData.json b/src/utils/UserRegisterFormValueData.json new file mode 100644 index 0000000..0c17938 --- /dev/null +++ b/src/utils/UserRegisterFormValueData.json @@ -0,0 +1,34 @@ +{ + "formValue": [ + { + " labelText": "First Name", + "id": "firstName", + "type": "text", + "required": true + }, + { + "labelText": "Last Name", + "id": "lastName", + "type": "text", + "required": true + }, + { + "labelText": "Password", + "id": "password", + "type": "text", + "required": true + }, + { + "labelText": "Address", + "id": "address", + "type": "text", + "required": true + }, + { + "labelText": "User Image", + "id": "userImage", + "type": "file", + "required": true + } +] +} diff --git a/src/utils/utilities.ts b/src/utils/utilities.ts index 4a8c4aa..e288047 100644 --- a/src/utils/utilities.ts +++ b/src/utils/utilities.ts @@ -4,7 +4,7 @@ export function capitalize(word: string) { } export const InitialStateData = { list: [], - pagination: { + meta: { totalPage: 0, totalItem: 0, previousPageNumber: null,