This commit is contained in:
Iliyan Angelov
2025-11-17 18:26:30 +02:00
parent 48353cde9c
commit 0c59fe1173
2535 changed files with 278997 additions and 2480 deletions

View File

@@ -28,6 +28,7 @@ export interface AuthResponse {
email: string;
phone?: string;
avatar?: string;
currency?: string;
role: string;
createdAt?: string;
};
@@ -143,6 +144,7 @@ const authService = {
phone_number?: string;
password?: string;
currentPassword?: string;
currency?: string;
}
): Promise<AuthResponse> => {
const response = await apiClient.put<AuthResponse>(

View File

@@ -7,7 +7,7 @@ export interface BookingData {
check_out_date: string; // YYYY-MM-DD
guest_count: number;
notes?: string;
payment_method: 'cash' | 'bank_transfer';
payment_method: 'cash' | 'stripe';
total_price: number;
guest_info: {
full_name: string;
@@ -31,7 +31,7 @@ export interface Booking {
| 'cancelled'
| 'checked_in'
| 'checked_out';
payment_method: 'cash' | 'bank_transfer';
payment_method: 'cash' | 'stripe';
payment_status:
| 'unpaid'
| 'paid'

View File

@@ -20,6 +20,9 @@ export type * from './bookingService';
export { default as paymentService } from './paymentService';
export type * from './paymentService';
export { default as invoiceService } from './invoiceService';
export type * from './invoiceService';
export { default as userService } from './userService';
export type * from './userService';

View File

@@ -0,0 +1,175 @@
import apiClient from './apiClient';
export interface InvoiceItem {
id: number;
description: string;
quantity: number;
unit_price: number;
tax_rate: number;
discount_amount: number;
line_total: number;
room_id?: number;
service_id?: number;
}
export interface Invoice {
id: number;
invoice_number: string;
booking_id: number;
user_id: number;
issue_date: string;
due_date: string;
paid_date?: string;
subtotal: number;
tax_rate: number;
tax_amount: number;
discount_amount: number;
total_amount: number;
amount_paid: number;
balance_due: number;
status: 'draft' | 'sent' | 'paid' | 'overdue' | 'cancelled';
company_name?: string;
company_address?: string;
company_phone?: string;
company_email?: string;
company_tax_id?: string;
company_logo_url?: string;
customer_name: string;
customer_email: string;
customer_address?: string;
customer_phone?: string;
customer_tax_id?: string;
notes?: string;
terms_and_conditions?: string;
payment_instructions?: string;
items: InvoiceItem[];
created_at: string;
updated_at: string;
}
export interface InvoiceResponse {
status: string;
message?: string;
data: {
invoice?: Invoice;
invoices?: Invoice[];
total?: number;
page?: number;
limit?: number;
total_pages?: number;
};
}
export interface CreateInvoiceData {
booking_id: number;
tax_rate?: number;
discount_amount?: number;
due_days?: number;
company_name?: string;
company_address?: string;
company_phone?: string;
company_email?: string;
company_tax_id?: string;
company_logo_url?: string;
customer_tax_id?: string;
notes?: string;
terms_and_conditions?: string;
payment_instructions?: string;
}
export interface UpdateInvoiceData {
company_name?: string;
company_address?: string;
company_phone?: string;
company_email?: string;
company_tax_id?: string;
company_logo_url?: string;
notes?: string;
terms_and_conditions?: string;
payment_instructions?: string;
status?: string;
due_date?: string;
tax_rate?: number;
discount_amount?: number;
}
/**
* Get all invoices
* GET /api/invoices
*/
export const getInvoices = async (params?: {
booking_id?: number;
status?: string;
page?: number;
limit?: number;
}): Promise<InvoiceResponse> => {
const response = await apiClient.get<InvoiceResponse>('/invoices', { params });
return response.data;
};
/**
* Get invoice by ID
* GET /api/invoices/:id
*/
export const getInvoiceById = async (id: number): Promise<InvoiceResponse> => {
const response = await apiClient.get<InvoiceResponse>(`/invoices/${id}`);
return response.data;
};
/**
* Get invoices by booking ID
* GET /api/invoices/booking/:bookingId
*/
export const getInvoicesByBooking = async (bookingId: number): Promise<InvoiceResponse> => {
const response = await apiClient.get<InvoiceResponse>(`/invoices/booking/${bookingId}`);
return response.data;
};
/**
* Create invoice from booking
* POST /api/invoices
*/
export const createInvoice = async (data: CreateInvoiceData): Promise<InvoiceResponse> => {
const response = await apiClient.post<InvoiceResponse>('/invoices', data);
return response.data;
};
/**
* Update invoice
* PUT /api/invoices/:id
*/
export const updateInvoice = async (id: number, data: UpdateInvoiceData): Promise<InvoiceResponse> => {
const response = await apiClient.put<InvoiceResponse>(`/invoices/${id}`, data);
return response.data;
};
/**
* Mark invoice as paid
* POST /api/invoices/:id/mark-paid
*/
export const markInvoiceAsPaid = async (id: number, amount?: number): Promise<InvoiceResponse> => {
const response = await apiClient.post<InvoiceResponse>(`/invoices/${id}/mark-paid`, { amount });
return response.data;
};
/**
* Delete invoice
* DELETE /api/invoices/:id
*/
export const deleteInvoice = async (id: number): Promise<{ status: string; message: string }> => {
const response = await apiClient.delete<{ status: string; message: string }>(`/invoices/${id}`);
return response.data;
};
const invoiceService = {
getInvoices,
getInvoiceById,
getInvoicesByBooking,
createInvoice,
updateInvoice,
markInvoiceAsPaid,
deleteInvoice,
};
export default invoiceService;

View File

@@ -4,7 +4,7 @@ import apiClient from './apiClient';
export interface PaymentData {
booking_id: number;
amount: number;
payment_method: 'cash' | 'bank_transfer';
payment_method: 'cash' | 'bank_transfer' | 'stripe';
transaction_id?: string;
notes?: string;
}
@@ -13,7 +13,7 @@ export interface Payment {
id: number;
booking_id: number;
amount: number;
payment_method: 'cash' | 'bank_transfer' | 'credit_card' | 'debit_card' | 'e_wallet';
payment_method: 'cash' | 'bank_transfer' | 'credit_card' | 'debit_card' | 'e_wallet' | 'stripe';
payment_type: 'full' | 'deposit' | 'remaining';
deposit_percentage?: number;
payment_status: 'pending' | 'completed' | 'failed' | 'refunded';
@@ -159,6 +159,38 @@ export const notifyPaymentCompletion = async (
return response.data;
};
/**
* Get all payments (with optional filters)
* GET /api/payments
*/
export const getPayments = async (params?: {
booking_id?: number;
status?: string;
page?: number;
limit?: number;
}): Promise<{
success: boolean;
data: {
payments: Payment[];
pagination?: {
total: number;
page: number;
limit: number;
totalPages: number;
};
};
message?: string;
}> => {
const response = await apiClient.get('/payments', { params });
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
data: data.data || { payments: [] },
message: data.message,
};
};
/**
* Get payments for a booking
* GET /api/payments/booking/:bookingId
@@ -173,16 +205,94 @@ export const getPaymentsByBookingId = async (
const response = await apiClient.get(
`/payments/booking/${bookingId}`
);
return response.data;
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
data: data.data || { payments: [] },
message: data.message,
};
};
/**
* Create Stripe payment intent
* POST /api/payments/stripe/create-intent
*/
export const createStripePaymentIntent = async (
bookingId: number,
amount: number,
currency: string = 'usd'
): Promise<{
success: boolean;
data: {
client_secret: string;
payment_intent_id: string;
publishable_key: string;
};
message?: string;
}> => {
const response = await apiClient.post(
'/payments/stripe/create-intent',
{
booking_id: bookingId,
amount,
currency,
}
);
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
data: data.data || {},
message: data.message,
};
};
/**
* Confirm Stripe payment
* POST /api/payments/stripe/confirm
*/
export const confirmStripePayment = async (
paymentIntentId: string,
bookingId: number
): Promise<{
success: boolean;
data: {
payment: Payment;
booking: {
id: number;
booking_number: string;
status: string;
};
};
message?: string;
}> => {
const response = await apiClient.post(
'/payments/stripe/confirm',
{
payment_intent_id: paymentIntentId,
booking_id: bookingId,
}
);
// Map backend response format (status: "success") to frontend format (success: true)
const data = response.data;
return {
success: data.status === "success" || data.success === true,
data: data.data || {},
message: data.message,
};
};
export default {
createPayment,
getPayments,
getPaymentByBookingId,
confirmBankTransfer,
getBankTransferInfo,
confirmDepositPayment,
notifyPaymentCompletion,
getPaymentsByBookingId,
createStripePaymentIntent,
confirmStripePayment,
};

View File

@@ -11,6 +11,11 @@ export interface Room {
floor: number;
status: 'available' | 'occupied' | 'maintenance';
featured: boolean;
price?: number;
description?: string;
capacity?: number;
room_size?: string;
view?: string;
images?: string[];
amenities?: string[];
created_at: string;
@@ -86,12 +91,22 @@ export const getRooms = async (
};
/**
* Get room by ID
* Get room by ID (deprecated - use getRoomByNumber instead)
*/
export const getRoomById = async (
id: number
): Promise<{ success: boolean; data: { room: Room } }> => {
const response = await apiClient.get(`/rooms/${id}`);
const response = await apiClient.get(`/rooms/id/${id}`);
return response.data;
};
/**
* Get room by room number
*/
export const getRoomByNumber = async (
room_number: string
): Promise<{ success: boolean; data: { room: Room } }> => {
const response = await apiClient.get(`/rooms/${room_number}`);
return response.data;
};
@@ -137,6 +152,12 @@ export interface CreateRoomData {
room_type_id: number;
status: 'available' | 'occupied' | 'maintenance';
featured?: boolean;
price?: number;
description?: string;
capacity?: number;
room_size?: string;
view?: string;
amenities?: string[];
}
export const createRoom = async (
@@ -167,13 +188,25 @@ export const deleteRoom = async (
return response.data;
};
/**
* Bulk delete rooms
*/
export const bulkDeleteRooms = async (
ids: number[]
): Promise<{ success: boolean; message: string; data: { deleted_count: number; deleted_ids: number[] } }> => {
const response = await apiClient.post('/rooms/bulk-delete', { ids });
return response.data;
};
export default {
getFeaturedRooms,
getRooms,
getRoomById,
getRoomByNumber,
searchAvailableRooms,
getAmenities,
createRoom,
updateRoom,
deleteRoom,
bulkDeleteRooms,
};

View File

@@ -0,0 +1,88 @@
import apiClient from './apiClient';
export interface PlatformCurrencyResponse {
status: string;
data: {
currency: string;
updated_at: string | null;
updated_by: string | null;
};
}
export interface UpdateCurrencyRequest {
currency: string;
}
export interface StripeSettingsResponse {
status: string;
data: {
stripe_secret_key: string;
stripe_publishable_key: string;
stripe_webhook_secret: string;
stripe_secret_key_masked: string;
stripe_webhook_secret_masked: string;
has_secret_key: boolean;
has_publishable_key: boolean;
has_webhook_secret: boolean;
updated_at?: string | null;
updated_by?: string | null;
};
message?: string;
}
export interface UpdateStripeSettingsRequest {
stripe_secret_key?: string;
stripe_publishable_key?: string;
stripe_webhook_secret?: string;
}
const systemSettingsService = {
/**
* Get platform currency (public endpoint)
*/
getPlatformCurrency: async (): Promise<PlatformCurrencyResponse> => {
const response = await apiClient.get<PlatformCurrencyResponse>(
'/api/admin/system-settings/currency'
);
return response.data;
},
/**
* Update platform currency (Admin only)
*/
updatePlatformCurrency: async (
currency: string
): Promise<PlatformCurrencyResponse> => {
const response = await apiClient.put<PlatformCurrencyResponse>(
'/api/admin/system-settings/currency',
{ currency }
);
return response.data;
},
/**
* Get Stripe settings (Admin only)
*/
getStripeSettings: async (): Promise<StripeSettingsResponse> => {
const response = await apiClient.get<StripeSettingsResponse>(
'/api/admin/system-settings/stripe'
);
return response.data;
},
/**
* Update Stripe settings (Admin only)
*/
updateStripeSettings: async (
settings: UpdateStripeSettingsRequest
): Promise<StripeSettingsResponse> => {
const response = await apiClient.put<StripeSettingsResponse>(
'/api/admin/system-settings/stripe',
settings
);
return response.data;
},
};
export default systemSettingsService;