Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 60dd616

Browse files
committedJul 31, 2024·
added and tested update profile functions for both consumer, provider, and Service
1 parent 7bcc189 commit 60dd616

6 files changed

+244
-51
lines changed
 

‎components/CustomerAccountDetails.tsx

+74-40
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
11
import { useEffect, useState } from 'react';
22
import { databases} from '../lib/appwrite.config';
33
import * as sdk from 'node-appwrite';
4-
5-
// const CustomerAccountDetails = () => {
6-
// return (
7-
// <div>
8-
// <h2 className="text-2xl font-bold mb-4">Account Details</h2>
9-
// <p>This is a placeholder for the customer account details section.</p>
10-
// </div>
11-
// );
12-
// };
13-
14-
15-
16-
4+
import ChangePasswordForm from './UpdatePassword';
5+
import UpdateProfileForm from './UpdateProfileForm';
176

187
const CustomerAccountDetails: React.FC = () => {
19-
const [profile, setProfile] = useState<any>(null);
20-
const [message, setMessage] = useState('');
8+
const [profile, setProfile] = useState<any>(null);
9+
const [message, setMessage] = useState('');
10+
const [expandedSection, setExpandedSection] = useState<string | null>(null);
11+
const [activeSetting, setActiveSetting] = useState<string | null>(null);
2112

2213
useEffect(() => {
2314
const fetchProfile = async () => {
@@ -34,9 +25,7 @@ useEffect(() => {
3425
const response = await databases.listDocuments(
3526
process.env.DATABASE_ID!,
3627
process.env.CONSUMER_COLLECTION_ID!,
37-
[
38-
sdk.Query.equal('userId', session.userId)
39-
]
28+
[ sdk.Query.equal('userId', session.userId)]
4029
);
4130

4231
if (response.documents.length > 0) {
@@ -53,31 +42,76 @@ useEffect(() => {
5342
fetchProfile();
5443
}, []);
5544

45+
const toggleSection = (section: string) => {
46+
setExpandedSection(expandedSection === section ? null : section);
47+
setActiveSetting(null);
48+
};
49+
50+
const handleSettingClick = (setting: string) => {
51+
setActiveSetting(setting);
52+
};
53+
5654
return (
57-
<div>
58-
<h2 className="text-2xl font-bold mb-4">Account Details</h2>
59-
{message && <p>{message}</p>}
60-
{profile ? (
61-
<div>
62-
<div>
63-
<h2>{profile.name}</h2>
64-
<p>Email: {profile.email}</p>
65-
<p>Phone: {profile.phone}</p>
66-
<p>Address: {profile.address}</p>
67-
<p>City: {profile.city}</p>
68-
<p>State: {profile.state}</p>
69-
<p>Zipcode: {profile.zipcode}</p>
70-
<p>Create On: {profile.createon}</p>
71-
<p>User Type: {profile.userType}</p>
72-
<p>Profile Image: <img src={profile.profileImg} alt="Profile" /></p>
73-
<p>Bookings: {profile.bookings.join(', ')}</p>
74-
<p>User ID: {profile.userId}</p>
75-
{/* Add other profile fields as needed */}
55+
<div className="bg-gray-100 rounded-lg p-6">
56+
<div className="flex justify-between items-start mb-4 border-b border-gray-300 pb-4">
57+
<div className="flex items-center">
58+
<div className="w-40 h-40 flex items-center justify-center rounded-full">
59+
<img className="w-32 h-32 rounded-full" src={profile?.profileImg} alt={profile?.name} />
60+
</div>
61+
<div className="mx-6">
62+
<h2 className="font-bold text-lg">{profile?.name}</h2>
63+
<p>{profile?.city}, {profile?.state}</p>
64+
<p>Stars (Rating): {profile?.rating}</p>
65+
<p>Joined On: {profile?.createdAt?.substring(0, 10)}</p>
66+
<p>User Type: {profile?.userType}</p>
67+
</div>
68+
</div>
69+
<div className="w-5/12 items-center justify-center mt-10">
70+
<h3 className=""><span className="label mt-1">Phone:</span>{profile?.phone}</h3>
71+
<h3 className=""><span className="label">e-mail:</span>{profile?.email}</h3>
72+
<h3 className=""><span className="label">Address:</span>{profile?.address}</h3>
7673
</div>
74+
</div>
75+
<div className="flex">
76+
<div className="w-full p-4">
77+
<h3 className="my-4 cursor-pointer" onClick={() => toggleSection('accountSettings')}>
78+
Account Settings
79+
</h3>
80+
{expandedSection === 'accountSettings' && (
81+
<div className="p-4 bg-white rounded shadow">
82+
<p className="cursor-pointer my-2 font-bold" onClick={() => handleSettingClick('changePassword')}>Change Password</p>
83+
{activeSetting === 'changePassword' && profile && (
84+
<div className="mt-4">
85+
<ChangePasswordForm userId={profile.userId} />
86+
</div>
87+
)}
88+
<p className="cursor-pointer my-2 font-bold" onClick={() => handleSettingClick('updateAccountInfo')}>Update Account Info</p>
89+
{activeSetting === 'updateAccountInfo' && profile && (
90+
<div className="mt-4">
91+
<UpdateProfileForm profile={profile} />
92+
</div>
93+
)}
94+
{console.log(profile.$id)}
95+
</div>
96+
)}
97+
<h3 className="my-4 cursor-pointer" onClick={() => toggleSection('currentBookings')}>
98+
Current Bookings
99+
</h3>
100+
{expandedSection === 'currentBookings' && (
101+
<div className="p-4 bg-white rounded shadow">
102+
<p>Current bookings content...</p>
103+
</div>
104+
)}
105+
<h3 className="my-4 cursor-pointer" onClick={() => toggleSection('myReviews')}>
106+
My Reviews
107+
</h3>
108+
{expandedSection === 'myReviews' && (
109+
<div className="p-4 bg-white rounded shadow">
110+
<p>My reviews content...</p>
111+
</div>
112+
)}
77113
</div>
78-
) : (
79-
<p>Loading profile...</p>
80-
)}
114+
</div>
81115
</div>
82116
);
83117
};

‎components/CustomerRegisterForm.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { users, databases } from '../lib/appwrite.config';
1111

1212
const CustomerRegisterForm: React.FC = () => {
1313
const router = useRouter();
14+
const created = useState(new Date().toISOString());
1415
const [formData, setFormData] = useState({
1516
email: '',
1617
password: '',
@@ -36,6 +37,7 @@ const CustomerRegisterForm: React.FC = () => {
3637
try {
3738
const newUser = await users.create('unique()', formData.email, formData.phone, formData.password, formData.name);
3839
//await users.updatePhone(newUser.$id, formData.phone);
40+
await users.updateLabels(newUser.$id, ["Consumer"]);
3941

4042
await databases.createDocument(
4143
process.env.DATABASE_ID!,
@@ -51,7 +53,8 @@ const CustomerRegisterForm: React.FC = () => {
5153
state: formData.state,
5254
zipcode: formData.zipcode,
5355
profileImg: formData.profileImg,
54-
userType:"Consumer"
56+
userType:"Consumer",
57+
createon:created
5558
}
5659
);
5760

‎components/CustomerSearchServices.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ const CustomerSearchServices: React.FC = () => {
216216
providerID=''
217217
category={service.category}
218218
city={service.city}
219-
providerIcon={'../public/assets/InteriorDesignXL.jpg'}
219+
providerIcon={'https://cdn-icons-png.flaticon.com/512/3135/3135715.png'}
220220
rating={5}
221221
onClick={() => setSelectedService(service)} // Set the selected service on click
222222
onProviderClick={() => setSelectedProvider(service)} // Set the selected provider on click

‎components/ServiceCard.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ const ServiceCard: React.FC<ServiceCardProps> = ({ title, summary, description,
5151
<div className="mb-1 flex-grow" onClick={onClick}>
5252
<p className="text-gray-700 line-clamp-3">{summary}</p>
5353
</div>
54-
<div className="flex justify-between items-center mt-1"onClick={onClick}>
54+
<div className="flex justify-between items-center mt-1">
5555
<span className="text-gray-500 text-sm">{city}</span>
56-
<div className="flex items-center">
57-
<p className="text-gray-600 italic text-sm cursor-pointer" onClick={onProviderClick}>By: {providerName}</p>
56+
<div className="flex items-center" onClick={onProviderClick}>
57+
<p className="text-gray-600 italic text-sm cursor-pointer">By: {providerName}</p>
5858
<img src={providerIcon} alt={providerName} className="w-8 h-8 rounded-full mr-2" />
5959
</div>
6060
</div>

‎components/UpdateProfileForm.tsx

+32-6
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,33 @@ const UpdateProfileForm: React.FC<{ profile: any }> = ({ profile }) => {
99
const [city, setCity] = useState(profile.city);
1010
const [state, setState] = useState(profile.state);
1111
const [zipcode, setZipcode] = useState(profile.zipcode);
12+
const [profileImg, setProfileImg] = useState(profile.profileImg);
1213
const [message, setMessage] = useState('');
1314

1415
const handleSubmit = async (e: React.FormEvent) => {
1516
e.preventDefault();
1617
try {
17-
await users.updatePhone(profile.userId, phone);
18-
await users.updateEmail(profile.userId, email);
19-
await users.updateName(profile.userId, name);
20-
18+
if (phone !== profile.phone) {
19+
await users.updatePhone(profile.userId, phone);
20+
}
21+
if (email !== profile.email) {
22+
await users.updateEmail(profile.userId, email);
23+
}
24+
if (name !== profile.name) {
25+
await users.updateName(profile.userId, name);
26+
}
27+
var collectionID = "";
28+
if(profile.userType==="Consumer"){
29+
collectionID = process.env.CONSUMER_COLLECTION_ID!
30+
}
31+
else if(profile.userType==="Provider"){
32+
collectionID = process.env.SERVICEPROVIDER_COLLECTION_ID!
33+
}
2134
await databases.updateDocument(
2235
process.env.DATABASE_ID!,
23-
process.env.SERVICEPROVIDER_COLLECTION_ID!,
36+
collectionID,
2437
profile.$id,
25-
{ name, email, phone, address, city, state, zipcode }
38+
{ name, email, phone, address, city, state, zipcode, profileImg }
2639
);
2740
setMessage('Profile updated successfully');
2841
} catch (error) {
@@ -124,6 +137,19 @@ const UpdateProfileForm: React.FC<{ profile: any }> = ({ profile }) => {
124137
className="border border-gray-300 rounded p-1 mt-1"
125138
/>
126139
</div>
140+
<div className="flex flex-col">
141+
<label htmlFor="profileImg" className="font-semibold">
142+
Profile Image:
143+
</label>
144+
<input
145+
type="text"
146+
id="profileImg"
147+
value={profileImg}
148+
onChange={(e) => setProfileImg(e.target.value)}
149+
required
150+
className="border border-gray-300 rounded p-1 mt-1"
151+
/>
152+
</div>
127153
<button type="submit" className="bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600">
128154
Update Info
129155
</button>

‎components/UpdateServiceForm.tsx

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import React, { useState } from 'react';
2+
import { databases } from '../lib/appwrite.config';
3+
4+
const UpdateServiceForm: React.FC<{ service: any }> = ({ service }) => {
5+
const [title, setTitle] = useState(service.title);
6+
const [description, setDescription] = useState(service.description);
7+
const [price, setPrice] = useState(service.price);
8+
const [summary, setSummary] = useState(service.summary);
9+
const [category, setCategory] = useState(service.category);
10+
const [address, setAddress] = useState(service.address);
11+
const [zipcode, setZipcode] = useState(service.zipcode);
12+
const [message, setMessage] = useState('');
13+
14+
const handleSubmit = async (e: React.FormEvent) => {
15+
e.preventDefault();
16+
try {
17+
await databases.updateDocument(
18+
process.env.DATABASE_ID!,
19+
process.env.SERVICE_COLLECTION_ID!,
20+
service.$id,
21+
{ title, description, price, summary, category, address, zipcode }
22+
);
23+
setMessage('Service updated successfully');
24+
} catch (error) {
25+
console.error('Error updating service:', error);
26+
setMessage('Error updating service');
27+
}
28+
};
29+
30+
return (
31+
<form onSubmit={handleSubmit} className="space-y-4">
32+
<div className="flex flex-col">
33+
<label htmlFor="title" className="font-semibold">
34+
Title:
35+
</label>
36+
<input
37+
type="text"
38+
id="title"
39+
value={title}
40+
onChange={(e) => setTitle(e.target.value)}
41+
required
42+
className="border border-gray-300 rounded p-1 mt-1"
43+
/>
44+
</div>
45+
<div className="flex flex-col">
46+
<label htmlFor="summary" className="font-semibold">
47+
Summary:
48+
</label>
49+
<textarea
50+
id="summary"
51+
value={summary}
52+
onChange={(e) => setSummary(e.target.value)}
53+
required
54+
className="border border-gray-300 rounded p-1 mt-1 h-12"
55+
/>
56+
</div>
57+
<div className="flex flex-col">
58+
<label htmlFor="description" className="font-semibold">
59+
Description:
60+
</label>
61+
<textarea
62+
id="description"
63+
value={description}
64+
onChange={(e) => setDescription(e.target.value)}
65+
required
66+
className="border border-gray-300 rounded p-1 mt-1"
67+
/>
68+
</div>
69+
<div className="flex flex-col">
70+
<label htmlFor="price" className="font-semibold">
71+
Price:
72+
</label>
73+
<input
74+
type="number"
75+
id="price"
76+
value={price}
77+
onChange={(e) => setPrice(e.target.value)}
78+
required
79+
className="border border-gray-300 rounded p-1 mt-1"
80+
/>
81+
</div>
82+
83+
<div className="flex flex-col">
84+
<label htmlFor="category" className="font-semibold">
85+
Category:
86+
</label>
87+
<input
88+
type="text"
89+
id="category"
90+
value={category}
91+
onChange={(e) => setCategory(e.target.value)}
92+
required
93+
className="border border-gray-300 rounded p-1 mt-1"
94+
/>
95+
</div>
96+
<div className="flex flex-col">
97+
<label htmlFor="address" className="font-semibold">
98+
Address:
99+
</label>
100+
<input
101+
type="text"
102+
id="address"
103+
value={address}
104+
onChange={(e) => setAddress(e.target.value)}
105+
required
106+
className="border border-gray-300 rounded p-1 mt-1"
107+
/>
108+
</div>
109+
<div className="flex flex-col">
110+
<label htmlFor="zipcode" className="font-semibold">
111+
Zipcode:
112+
</label>
113+
<input
114+
type="text"
115+
id="zipcode"
116+
value={zipcode}
117+
onChange={(e) => setZipcode(e.target.value)}
118+
required
119+
className="border border-gray-300 rounded p-1 mt-1"
120+
/>
121+
</div>
122+
<button type="submit" className="bg-blue-500 text-white py-2 px-4 rounded hover:bg-blue-600">
123+
Update Service
124+
</button>
125+
{message && <p className="mt-2">{message}</p>}
126+
</form>
127+
);
128+
};
129+
130+
export default UpdateServiceForm;

0 commit comments

Comments
 (0)
Please sign in to comment.