Skip to content

Commit 6b99efd

Browse files
authored
Merge pull request #21 from OzPol/dev-shawnw-appwrite
Dev shawnw appwrite
2 parents 37dfc43 + f2b7818 commit 6b99efd

29 files changed

+1626
-182
lines changed

app/layout.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Metadata } from "next";
22
import { Inter } from "next/font/google";
3-
import "./globals.css";
3+
import "../styles/globals.css";
44

55
const inter = Inter({ subsets: ["latin"] });
66

components/CustomerAccountDetails.tsx

+84-9
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,86 @@
1-
const CustomerAccountDetails = () => {
2-
return (
3-
<div>
4-
<h2 className="text-2xl font-bold mb-4">Account Details</h2>
5-
<p>This is a placeholder for the customer account details section.</p>
6-
</div>
7-
);
8-
};
1+
import { useEffect, useState } from 'react';
2+
import { databases, DATABASE_ID,CONSUMER_COLLECTION_ID} from '../lib/appwrite.config';
3+
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+
// };
913

10-
export default CustomerAccountDetails;
14+
15+
16+
17+
18+
const CustomerAccountDetails: React.FC = () => {
19+
const [profile, setProfile] = useState<any>(null);
20+
const [message, setMessage] = useState('');
21+
22+
useEffect(() => {
23+
const fetchProfile = async () => {
24+
try {
25+
// Retrieve the session information from local storage
26+
const session = JSON.parse(localStorage.getItem('appwriteSession') || '{}');
27+
28+
if (!session || !session.userId) {
29+
setMessage('No active session found. Please log in.');
30+
return;
31+
}
32+
33+
// Fetch user profile from the collection
34+
const response = await databases.listDocuments(
35+
process.env.DATABASE_ID!,
36+
process.env.CONSUMER_COLLECTION_ID!,
37+
[
38+
sdk.Query.equal('userId', session.userId)
39+
]
40+
);
41+
42+
if (response.documents.length > 0) {
43+
setProfile(response.documents[0]);
44+
} else {
45+
setMessage('Profile not found.');
46+
}
47+
} catch (error) {
48+
console.error('Error fetching profile:', error);
49+
setMessage('Error fetching profile.');
50+
}
51+
};
52+
53+
fetchProfile();
54+
}, []);
55+
56+
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 */}
76+
</div>
77+
</div>
78+
) : (
79+
<p>Loading profile...</p>
80+
)}
81+
</div>
82+
);
83+
};
84+
export default CustomerAccountDetails;
85+
1186

+73-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,73 @@
1-
const CustomerProfileOverview = () => {
2-
return (
3-
<div>
4-
<h2 className="text-2xl font-bold mb-4">Profile Overview</h2>
5-
<p>This is a placeholder for the customer profile overview section.</p>
6-
</div>
7-
);
8-
};
9-
10-
export default CustomerProfileOverview;
11-
1+
import { useEffect, useState } from 'react';
2+
import { databases, DATABASE_ID,CONSUMER_COLLECTION_ID} from '../lib/appwrite.config';
3+
import * as sdk from 'node-appwrite';
4+
5+
const CustomerProfileOverview: React.FC = () => {
6+
const [profile, setProfile] = useState<any>(null);
7+
const [message, setMessage] = useState('');
8+
9+
useEffect(() => {
10+
const fetchProfile = async () => {
11+
try {
12+
// Retrieve session info from local storage
13+
const session = JSON.parse(localStorage.getItem('appwriteSession') || '{}');
14+
15+
if (!session || !session.userId) {
16+
setMessage('No active session found. Please log in.');
17+
return;
18+
}
19+
20+
// Fetch user profile from user collection
21+
const response = await databases.listDocuments(
22+
process.env.DATABASE_ID!,
23+
process.env.CONSUMER_COLLECTION_ID!,
24+
[
25+
sdk.Query.equal('userId', session.userId)
26+
]
27+
);
28+
29+
if (response.documents.length > 0) {
30+
setProfile(response.documents[0]);
31+
} else {
32+
setMessage('Profile not found.');
33+
}
34+
} catch (error) {
35+
console.error('Error fetching profile:', error);
36+
setMessage('Error fetching profile.');
37+
}
38+
};
39+
40+
fetchProfile();
41+
}, []);
42+
43+
return (
44+
<div>
45+
<h2 className="text-2xl font-bold mb-4">Profile Overview</h2>
46+
{message && <p>{message}</p>}
47+
{profile ? (
48+
<div>
49+
<div>
50+
<h2>{profile.name}</h2>
51+
<p>User ID: {profile.userId}</p>
52+
<p>Email: {profile.email}</p>
53+
<p>Phone: {profile.phone}</p>
54+
{/* <p>Address: {profile.address}</p>
55+
<p>City: {profile.city}</p>
56+
<p>State: {profile.state}</p>
57+
<p>Zipcode: {profile.zipcode}</p>
58+
<p>Create On: {profile.createon}</p> */}
59+
<p>User Type: {profile.userType}</p>
60+
{/* <p>Profile Image: <img src={profile.profileImg} alt="Profile" /></p> */}
61+
<p>Bookings: {profile.bookings.join(', ')}</p>
62+
63+
{/* Add other profile fields as needed */}
64+
</div>
65+
</div>
66+
) : (
67+
<p>Loading profile...</p>
68+
)}
69+
</div>
70+
);
71+
};
72+
73+
export default CustomerProfileOverview;

components/CustomerSearchServices.tsx

+43-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,51 @@
1-
const CustomerSearchServices = () => {
1+
import React, { useEffect, useState } from 'react';
2+
import ServiceCard from './ServiceCard';
3+
import { Service } from '../types/appwrite.type';
4+
import { fetchAllServices } from './DataServiceConsumer';
5+
6+
const CustomerSearchServices: React.FC = () => {
7+
const [services, setServices] = useState<Service[]>([]);
8+
const [filter, setFilter] = useState('');
9+
10+
useEffect(() => {
11+
const fetchServices = async () => {
12+
const fetchedServices = await fetchAllServices();
13+
setServices(fetchedServices);
14+
};
15+
16+
fetchServices();
17+
}, []);
18+
19+
const handleFilterChange = (e: React.ChangeEvent<HTMLInputElement>) => {
20+
setFilter(e.target.value);
21+
};
22+
23+
const filteredServices = services.filter(service =>
24+
service.name.toLowerCase().includes(filter.toLowerCase())
25+
);
26+
227
return (
328
<div>
4-
<h2 className="text-2xl font-bold mb-4">Search Services</h2>
29+
<h2 className="text-2xl font-bold mb-4">My Services</h2>
30+
{/* <p>This is a placeholder for the service providers to see their services.</p> */}
531
<input
632
type="text"
7-
placeholder="Search for services..."
8-
className="w-full p-2 border rounded mb-4"
33+
placeholder="🔍Filter services"
34+
value={filter}
35+
onChange={handleFilterChange}
36+
className="mb-4 p-2 border rounded"
937
/>
10-
<p>This is a placeholder for the customer search services section.</p>
38+
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
39+
{filteredServices.map(service => (
40+
<ServiceCard
41+
key={service.$id}
42+
name={service.name}
43+
description={service.description}
44+
price={service.price}
45+
providerName={service.providerName}
46+
/>
47+
))}
48+
</div>
1149
</div>
1250
);
1351
};

components/DataServiceConsumer.tsx

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { databases } from '../lib/appwrite.config';
2+
import { Service } from '../types/appwrite.type';
3+
4+
5+
export const fetchAllServices = async (): Promise<Service[]> => {
6+
const session = localStorage.getItem('appwriteSession');
7+
let services: Service[] = [];
8+
9+
if (session) {
10+
const sessionData = JSON.parse(session);
11+
const userId = sessionData.userId;
12+
13+
try {
14+
// Fetch documents from Appwrite collection
15+
const response = await databases.listDocuments(
16+
process.env.DATABASE_ID!,
17+
process.env.SERVICE_COLLECTION_ID!
18+
);//DB Coll
19+
const allServices = response.documents;
20+
21+
// Filter services based on providerId
22+
services = allServices
23+
.map((doc: any) => ({
24+
$id: doc.$id,
25+
name: doc.title,
26+
description: doc.description,
27+
price: doc.price,
28+
providerId: doc.providerId,
29+
providerName: doc.serviceProvider,
30+
}));
31+
} catch (error) {
32+
console.error('Error fetching services:', error);
33+
}
34+
}
35+
36+
return services;
37+
};

components/DataServiceProvider.tsx

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { databases } from '../lib/appwrite.config';
2+
import { Service } from '../types/appwrite.type';
3+
4+
5+
export const fetchAndFilterServices = async (): Promise<Service[]> => {
6+
const session = localStorage.getItem('appwriteSession');
7+
let services: Service[] = [];
8+
9+
if (session) {
10+
const sessionData = JSON.parse(session);
11+
const userId = sessionData.userId;
12+
13+
try {
14+
// Fetch documents from Appwrite collection
15+
const response = await databases.listDocuments(
16+
process.env.DATABASE_ID!,
17+
process.env.SERVICE_COLLECTION_ID!
18+
);//DB Coll
19+
const allServices = response.documents;
20+
21+
// Filter services based on providerId
22+
services = allServices
23+
.filter((doc: any) => doc.providerId === userId)
24+
.map((doc: any) => ({
25+
$id: doc.$id,
26+
name: doc.title,
27+
description: doc.description,
28+
price: doc.price,
29+
providerId: doc.providerId,
30+
providerName: doc.serviceProvider,
31+
}));
32+
} catch (error) {
33+
console.error('Error fetching services:', error);
34+
}
35+
}
36+
37+
return services;
38+
};

components/LoginForm.tsx

+31-5
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,48 @@
1-
'use client'
1+
'use client';
22

33
import { useState, ChangeEvent, FormEvent } from 'react';
4-
4+
import { account } from '../lib/appwrite.config';
5+
import { useRouter } from 'next/router';
56
interface LoginFormProps {
67
onSwitchToRegister: () => void;
78
}
89

910
const LoginForm: React.FC<LoginFormProps> = ({ onSwitchToRegister }) => {
11+
const router = useRouter();
1012
const [formData, setFormData] = useState({ email: '', password: '' });
13+
const [message, setMessage] = useState('');
1114

1215
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
1316
const { name, value } = e.target;
1417
setFormData((prevData) => ({ ...prevData, [name]: value }));
1518
};
1619

17-
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
20+
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
1821
e.preventDefault();
19-
// Handle login logic
20-
console.log('Login Form Data:', formData);
22+
setMessage(''); // Clear previous message
23+
24+
try {
25+
//delete existing session
26+
const currentSession = localStorage.getItem('appwriteSession');
27+
//console.log(currentSession);
28+
if (currentSession) {
29+
//console.log('true');
30+
const session = JSON.parse(currentSession);
31+
//await account.deleteSession(session.$id);
32+
localStorage.removeItem('appwriteSession');
33+
}
34+
// Logging in
35+
const session = await account.createEmailPasswordSession(formData.email, formData.password);
36+
//console.log('Login successful:', session);
37+
setMessage('Login successful');
38+
localStorage.setItem('appwriteSession', JSON.stringify(session));
39+
//window.location.href = '/customerProfile';
40+
router.push('/customerProfile');
41+
} catch (error:any) {
42+
console.error('Error logging in:', error);
43+
console.log(error.code+":"+error.type);
44+
setMessage('Error logging in. Please check your credentials and try again.');
45+
}
2146
};
2247

2348
return (
@@ -45,6 +70,7 @@ const LoginForm: React.FC<LoginFormProps> = ({ onSwitchToRegister }) => {
4570
<button type="submit" className="w-full bg-blue-500 text-white py-2 rounded hover:bg-blue-600">
4671
Log In
4772
</button>
73+
{message && <p className="mt-2 text-red-500">{message}</p>}
4874
<button
4975
type="button"
5076
className="w-full mt-2 text-blue-500 underline"

0 commit comments

Comments
 (0)