integrate the APIs for getting and editing user details
This commit is contained in:
@@ -2,12 +2,14 @@ import { configureStore } from "@reduxjs/toolkit";
|
||||
import { attractionsApi } from "./services/attractions.service";
|
||||
import { citiesApi } from "./services/cities.service";
|
||||
import { authApi } from "./services/auth.service";
|
||||
import { profileApi } from "./services/profile.service";
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: {
|
||||
[attractionsApi.reducerPath]: attractionsApi.reducer,
|
||||
[citiesApi.reducerPath]: citiesApi.reducer,
|
||||
[authApi.reducerPath]:authApi.reducer
|
||||
[authApi.reducerPath]: authApi.reducer,
|
||||
[profileApi.reducerPath]: profileApi.reducer
|
||||
|
||||
},
|
||||
|
||||
@@ -15,7 +17,8 @@ export const store = configureStore({
|
||||
getDefaultMiddleware().concat(
|
||||
attractionsApi.middleware,
|
||||
citiesApi.middleware,
|
||||
authApi.middleware
|
||||
authApi.middleware,
|
||||
profileApi.middleware
|
||||
),
|
||||
});
|
||||
export type RootState = ReturnType<typeof store.getState>;
|
||||
|
||||
33
src/Redux/services/profile.service.ts
Normal file
33
src/Redux/services/profile.service.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
|
||||
import { baseQuery } from "../baseQuery";
|
||||
|
||||
export const profileApi = createApi({
|
||||
reducerPath: "profileApi",
|
||||
baseQuery,
|
||||
|
||||
tagTypes: ["userDetails"],
|
||||
|
||||
endpoints: (builder) => ({
|
||||
|
||||
getUserProfileDetails: builder.query({
|
||||
query: (id) => `/website/user/${id}`,
|
||||
providesTags:["userDetails"]
|
||||
}),
|
||||
|
||||
updateUserProfileDetails: builder.mutation({
|
||||
query: ({ userDetails, userId }) => ({ // keep the name of the variables being passed here same as when calling the mutation hook
|
||||
url: `/website/user/${userId}`,
|
||||
method: "PUT",
|
||||
body: userDetails
|
||||
}),
|
||||
invalidatesTags:["userDetails"]
|
||||
})
|
||||
|
||||
})
|
||||
});
|
||||
|
||||
export const {
|
||||
useGetUserProfileDetailsQuery,
|
||||
useUpdateUserProfileDetailsMutation
|
||||
} = profileApi;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
import {
|
||||
ArrowLeft,
|
||||
@@ -26,6 +26,8 @@ import { Badge } from '../components/ui/badge';
|
||||
import Navbar from '../components/Navbar';
|
||||
import { Footer } from '../components/Footer';
|
||||
import { ImageWithFallback } from '../components/figma/ImageWithFallback';
|
||||
import { useGetUserProfileDetailsQuery, useUpdateUserProfileDetailsMutation } from '../Redux/services/profile.service';
|
||||
import { toast } from 'sonner';
|
||||
|
||||
interface ProfilePageProps {
|
||||
onBackClick: () => void;
|
||||
@@ -160,20 +162,70 @@ export function ProfilePage({
|
||||
currentPage
|
||||
}: ProfilePageProps) {
|
||||
const [activeTab, setActiveTab] = useState('profile');
|
||||
const [formData, setFormData] = useState(mockUserData);
|
||||
const [formData, setFormData] = useState({
|
||||
firstName: '',
|
||||
lastName: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
country: '',
|
||||
address1: '',
|
||||
address2: '',
|
||||
city: '',
|
||||
postalCode: ''
|
||||
});
|
||||
|
||||
const userId = localStorage.getItem("userId")
|
||||
const { data: userDetails, isLoading } = useGetUserProfileDetailsQuery(userId)
|
||||
|
||||
useEffect(() => {
|
||||
if (userDetails) {
|
||||
setFormData({
|
||||
firstName: userDetails?.firstName,
|
||||
lastName: userDetails?.lastName,
|
||||
email: userDetails?.emailAddress,
|
||||
phone: userDetails?.mobileNumber,
|
||||
country: userDetails?.country,
|
||||
address1: userDetails?.address1,
|
||||
address2: userDetails?.address2,
|
||||
city: userDetails?.cityName,
|
||||
postalCode: userDetails?.zipCode
|
||||
})
|
||||
}
|
||||
|
||||
}, [userDetails])
|
||||
|
||||
const [updateUserProfileDetails] = useUpdateUserProfileDetailsMutation();
|
||||
|
||||
const handleInputChange = (field: string, value: string) => {
|
||||
setFormData(prev => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const handleSaveProfile = () => {
|
||||
console.log('Saving profile...', formData);
|
||||
// Handle profile save
|
||||
const handleSaveProfile = async () => {
|
||||
try {
|
||||
console.log("Saving profile...", formData);
|
||||
const response = await updateUserProfileDetails({ userDetails: formData, userId });
|
||||
console.log(response)
|
||||
toast.success("Profile updated successfully!");
|
||||
} catch (error) {
|
||||
console.error("Error saving profile:", error);
|
||||
toast.error("Failed to update profile. Please try again.");
|
||||
}
|
||||
};
|
||||
|
||||
const activePasses = mockPasses.filter(pass => pass.status === 'active');
|
||||
const expiredPasses = mockPasses.filter(pass => pass.status === 'expired');
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-[#F95F62] mx-auto"></div>
|
||||
<p className="mt-4 text-gray-600">Loading...</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* Navbar */}
|
||||
@@ -312,7 +364,7 @@ export function ProfilePage({
|
||||
|
||||
<div>
|
||||
<Label htmlFor="country" className="font-poppins font-light">Country</Label>
|
||||
<Select value={formData.country} onValueChange={(value) => handleInputChange('country', value)}>
|
||||
{/* <Select value={formData.country} onValueChange={(value) => handleInputChange('country', value)}>
|
||||
<SelectTrigger className="mt-1">
|
||||
<SelectValue placeholder="Select country" />
|
||||
</SelectTrigger>
|
||||
@@ -326,15 +378,33 @@ export function ProfilePage({
|
||||
<SelectItem value="in">India</SelectItem>
|
||||
<SelectItem value="jp">Japan</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</Select> */}
|
||||
<Input
|
||||
id="country"
|
||||
value={formData.country}
|
||||
onChange={(e) => handleInputChange('country', e.target.value)}
|
||||
className="mt-1 font-poppins font-light"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<Label htmlFor="address" className="font-poppins font-light">Street Address</Label>
|
||||
<Label htmlFor="address1" className="font-poppins font-light">
|
||||
Address Line 1
|
||||
</Label>
|
||||
<Input
|
||||
id="address"
|
||||
value={formData.address}
|
||||
onChange={(e) => handleInputChange('address', e.target.value)}
|
||||
id="address1"
|
||||
value={formData.address1}
|
||||
onChange={(e) => handleInputChange('address1', e.target.value)}
|
||||
className="mt-1 font-poppins font-light mb-4"
|
||||
/>
|
||||
|
||||
<Label htmlFor="address2" className="font-poppins font-light">
|
||||
Address Line 2
|
||||
</Label>
|
||||
<Input
|
||||
id="address2"
|
||||
value={formData.address2}
|
||||
onChange={(e) => handleInputChange('address2', e.target.value)}
|
||||
className="mt-1 font-poppins font-light"
|
||||
/>
|
||||
</div>
|
||||
@@ -362,7 +432,7 @@ export function ProfilePage({
|
||||
|
||||
<Button
|
||||
onClick={handleSaveProfile}
|
||||
className="w-full bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90 text-white font-normal py-3 font-poppins"
|
||||
className="w-full bg-gradient-to-r from-primary to-secondary hover:from-primary/90 hover:to-secondary/90 text-white font-normal py-3 font-poppins cursor-pointer"
|
||||
>
|
||||
Save Changes
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user