diff --git a/apps/web/src/app/invitations/page.tsx b/apps/web/src/app/invitations/page.tsx new file mode 100644 index 00000000..24f6b1cb --- /dev/null +++ b/apps/web/src/app/invitations/page.tsx @@ -0,0 +1,79 @@ +'use client'; + +import { RightSidebar } from '@/components/layout/RightSidebar'; +import { Search } from 'lucide-react'; + +const InvitationsPage = () => { + return ( +
+
+
+

My invitations

+
+ +
+
+
+
+ + + + +
+ +
+
Rows per page
+
10
+
+
+ +
+
+
Property
+
Owner
+
Check-in
+
Check-out
+
Created
+
Status
+
Invitation
+
+ +
+ No invitations sent yet +
+
+ +
+
Total: 0 invitations
+
+ + +
+
+
+
+
+ + +
+ ); +}; + +export default InvitationsPage; diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index a7bfc400..91e20786 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -9,9 +9,7 @@ export default function Home() { return (
-
- StellaRent -
+
diff --git a/apps/web/src/services/api.ts b/apps/web/src/services/api.ts index 3d734f45..e2ff5770 100644 --- a/apps/web/src/services/api.ts +++ b/apps/web/src/services/api.ts @@ -48,18 +48,18 @@ interface ChallengeResponse { const _apiCall = async (endpoint: string, options: RequestInit = {}): Promise => { const url = `${API_BASE_URL}${endpoint}`; const token = localStorage.getItem('authToken'); - + const headers = new Headers({ 'Content-Type': 'application/json', - ...(token && { 'Authorization': `Bearer ${token}` }), - ...(options.headers as Record || {}) + ...(token && { Authorization: `Bearer ${token}` }), + ...((options.headers as Record) || {}), }); try { const response = await fetch(url, { ...options, headers, - credentials: 'include' + credentials: 'include', }); if (!response.ok) { @@ -77,29 +77,6 @@ const _apiCall = async (endpoint: string, options: RequestInit = {}): Promise console.error(`API call failed for ${endpoint}:`, error); throw error; } - - const config: RequestInit = { - headers: { - 'Content-Type': 'application/json', - ...(token && { Authorization: `Bearer ${token}` }), - ...options.headers, - }, - ...options, - }; - - try { - const response = await fetch(url, config); - - if (!response.ok) { - const errorData = await response.json().catch(() => ({})); - throw new Error(errorData.message || `HTTP error! status: ${response.status}`); - } - - return await response.json(); - } catch (error) { - console.error('API request failed:', error); - throw error; - } }; // Transform wallet user function @@ -289,6 +266,10 @@ export const propertyAPI = { return apiUtils.request(`/properties/${propertyId}/availability`, { method: 'PUT', body: JSON.stringify(availability), + }); + }, +}; + export const walletAPI = { getWalletBalance: async (userId: string) => { try { @@ -303,18 +284,18 @@ export const walletAPI = { return { success: false, data: { balance: 0, currency: 'USD' }, - message: 'Failed to load wallet balance' + message: 'Failed to load wallet balance', }; } }, - + getTransactionHistory: async (userId: string, filters?: Record) => { try { const params = new URLSearchParams({ userId }); if (filters) { - Object.entries(filters).forEach(([key, value]) => { + for (const [key, value] of Object.entries(filters)) { if (value) params.append(key, String(value)); - }); + } } const response = await fetch(`/api/wallets/${userId}/transactions?${params}`); if (!response.ok) { @@ -327,11 +308,11 @@ export const walletAPI = { return { success: false, data: [], - message: 'Failed to load transaction history' + message: 'Failed to load transaction history', }; } }, - + addFunds: async (userId: string, amount: number, paymentMethod: string) => { try { const response = await fetch(`/api/wallets/${userId}/deposit`, { @@ -348,8 +329,12 @@ export const walletAPI = { throw new Error('Failed to process deposit'); } }, - - withdrawFunds: async (userId: string, amount: number, accountDetails: Record) => { + + withdrawFunds: async ( + userId: string, + amount: number, + accountDetails: Record + ) => { try { const response = await fetch(`/api/wallets/${userId}/withdraw`, { method: 'POST', @@ -368,9 +353,9 @@ export const walletAPI = { }; export const notificationAPI = { - async getNotifications(userId: string, filters?: Record) { -{{ ... }} - }); + async getNotifications(_userId: string, _filters?: Record) { + // TODO: Implement notifications API + return Promise.resolve({ data: [], success: true }); }, }; @@ -391,13 +376,13 @@ export const dashboardAPI = { totalBookings: 0, totalEarnings: 0, activeListings: 0, - pendingRequests: 0 + pendingRequests: 0, }, - message: 'Failed to load dashboard stats' + message: 'Failed to load dashboard stats', }; } }, - + getRecentActivity: async (userId: string, userType: 'host' | 'tenant') => { try { const response = await fetch(`/api/activity/recent?userId=${userId}&userType=${userType}`); @@ -411,18 +396,18 @@ export const dashboardAPI = { return { success: false, data: [], - message: 'Failed to load recent activity' + message: 'Failed to load recent activity', }; } }, - + getEarningsAnalytics: async (userId: string, dateRange?: Record) => { try { const params = new URLSearchParams({ userId }); if (dateRange) { - Object.entries(dateRange).forEach(([key, value]) => { + for (const [key, value] of Object.entries(dateRange)) { if (value) params.append(key, String(value)); - }); + } } const response = await fetch(`/api/analytics/earnings?${params}`); if (!response.ok) { @@ -435,11 +420,11 @@ export const dashboardAPI = { return { success: false, data: [], - message: 'Failed to load earnings analytics' + message: 'Failed to load earnings analytics', }; } }, - + getBookingAnalytics: async ( userId: string, userType: 'host' | 'tenant', @@ -448,9 +433,9 @@ export const dashboardAPI = { try { const params = new URLSearchParams({ userId, userType }); if (dateRange) { - Object.entries(dateRange).forEach(([key, value]) => { + for (const [key, value] of Object.entries(dateRange)) { if (value) params.append(key, String(value)); - }); + } } const response = await fetch(`/api/analytics/bookings?${params}`); if (!response.ok) { @@ -463,7 +448,7 @@ export const dashboardAPI = { return { success: false, data: [], - message: 'Failed to load booking analytics' + message: 'Failed to load booking analytics', }; } }, @@ -471,7 +456,7 @@ export const dashboardAPI = { export const authAPI = { async login(email: string, password: string) { -{{ ... }} + return apiUtils.request('/auth/login', { method: 'POST', body: JSON.stringify({ email, password }), }); diff --git a/bun.lock b/bun.lock index ef8332ce..c4216ac7 100644 --- a/bun.lock +++ b/bun.lock @@ -61,6 +61,10 @@ "typescript": "^5.3.3", }, }, + "apps/stellar-contracts": { + "name": "stellar-rent-contracts", + "version": "1.0.0", + }, "apps/web": { "name": "web", "version": "0.1.0", @@ -2238,6 +2242,8 @@ "stellar-rent-backend": ["stellar-rent-backend@workspace:apps/backend"], + "stellar-rent-contracts": ["stellar-rent-contracts@workspace:apps/stellar-contracts"], + "stellar-sdk": ["stellar-sdk@13.3.0", "", { "dependencies": { "@stellar/stellar-base": "^13.1.0", "axios": "^1.8.4", "bignumber.js": "^9.3.0", "eventsource": "^2.0.2", "feaxios": "^0.0.23", "randombytes": "^2.1.0", "toml": "^3.0.0", "urijs": "^1.19.1" } }, "sha512-jAA3+U7oAUueldoS4kuEhcym+DigElWq9isPxt7tjMrE7kTJ2vvY29waavUb2FSfQIWwGbuwAJTYddy2BeyJsw=="], "stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="],