Add order page with real API calls
This commit is contained in:
@@ -25,6 +25,9 @@ class ApiClient {
|
||||
private tenantId: string | null = null;
|
||||
private refreshToken: string | null = null;
|
||||
private isRefreshing: boolean = false;
|
||||
private refreshAttempts: number = 0;
|
||||
private maxRefreshAttempts: number = 3;
|
||||
private lastRefreshAttempt: number = 0;
|
||||
private failedQueue: Array<{
|
||||
resolve: (value?: any) => void;
|
||||
reject: (error?: any) => void;
|
||||
@@ -72,6 +75,14 @@ class ApiClient {
|
||||
|
||||
// Check if error is 401 and we have a refresh token
|
||||
if (error.response?.status === 401 && this.refreshToken && !originalRequest._retry) {
|
||||
// Check if we've exceeded max refresh attempts in a short time
|
||||
const now = Date.now();
|
||||
if (this.refreshAttempts >= this.maxRefreshAttempts && (now - this.lastRefreshAttempt) < 30000) {
|
||||
console.log('Max refresh attempts exceeded, logging out');
|
||||
await this.handleAuthFailure();
|
||||
return Promise.reject(this.handleError(error));
|
||||
}
|
||||
|
||||
if (this.isRefreshing) {
|
||||
// If already refreshing, queue this request
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -81,8 +92,12 @@ class ApiClient {
|
||||
|
||||
originalRequest._retry = true;
|
||||
this.isRefreshing = true;
|
||||
this.refreshAttempts++;
|
||||
this.lastRefreshAttempt = now;
|
||||
|
||||
try {
|
||||
console.log(`Attempting token refresh (attempt ${this.refreshAttempts})...`);
|
||||
|
||||
// Attempt to refresh the token
|
||||
const response = await this.client.post('/auth/refresh', {
|
||||
refresh_token: this.refreshToken
|
||||
@@ -90,6 +105,11 @@ class ApiClient {
|
||||
|
||||
const { access_token, refresh_token } = response.data;
|
||||
|
||||
console.log('Token refresh successful');
|
||||
|
||||
// Reset refresh attempts on success
|
||||
this.refreshAttempts = 0;
|
||||
|
||||
// Update tokens
|
||||
this.setAuthToken(access_token);
|
||||
if (refresh_token) {
|
||||
@@ -107,6 +127,7 @@ class ApiClient {
|
||||
return this.client(originalRequest);
|
||||
|
||||
} catch (refreshError) {
|
||||
console.error(`Token refresh failed (attempt ${this.refreshAttempts}):`, refreshError);
|
||||
// Refresh failed, clear tokens and redirect to login
|
||||
this.processQueue(refreshError, null);
|
||||
await this.handleAuthFailure();
|
||||
@@ -165,13 +186,14 @@ class ApiClient {
|
||||
try {
|
||||
// Dynamically import to avoid circular dependency
|
||||
const { useAuthStore } = await import('../../stores/auth.store');
|
||||
const store = useAuthStore.getState();
|
||||
const setState = useAuthStore.setState;
|
||||
|
||||
// Update the store with new tokens
|
||||
store.token = accessToken;
|
||||
if (refreshToken) {
|
||||
store.refreshToken = refreshToken;
|
||||
}
|
||||
setState(state => ({
|
||||
...state,
|
||||
token: accessToken,
|
||||
refreshToken: refreshToken || state.refreshToken,
|
||||
}));
|
||||
} catch (error) {
|
||||
console.warn('Failed to update auth store:', error);
|
||||
}
|
||||
|
||||
@@ -3,18 +3,86 @@
|
||||
* Based on backend schemas in services/orders/app/schemas/order_schemas.py
|
||||
*/
|
||||
|
||||
export type CustomerType = 'individual' | 'business' | 'central_bakery';
|
||||
export type DeliveryMethod = 'delivery' | 'pickup';
|
||||
export type PaymentTerms = 'immediate' | 'net_30' | 'net_60';
|
||||
export type PaymentMethod = 'cash' | 'card' | 'bank_transfer' | 'account';
|
||||
export type PaymentStatus = 'pending' | 'partial' | 'paid' | 'failed' | 'refunded';
|
||||
export type CustomerSegment = 'vip' | 'regular' | 'wholesale';
|
||||
export type PriorityLevel = 'high' | 'normal' | 'low';
|
||||
export type OrderType = 'standard' | 'rush' | 'recurring' | 'special';
|
||||
export type OrderStatus = 'pending' | 'confirmed' | 'in_production' | 'ready' | 'out_for_delivery' | 'delivered' | 'cancelled' | 'failed';
|
||||
export type OrderSource = 'manual' | 'online' | 'phone' | 'app' | 'api';
|
||||
export type SalesChannel = 'direct' | 'wholesale' | 'retail';
|
||||
export type BusinessModel = 'individual_bakery' | 'central_bakery';
|
||||
export enum CustomerType {
|
||||
INDIVIDUAL = 'individual',
|
||||
BUSINESS = 'business',
|
||||
CENTRAL_BAKERY = 'central_bakery'
|
||||
}
|
||||
|
||||
export enum DeliveryMethod {
|
||||
DELIVERY = 'delivery',
|
||||
PICKUP = 'pickup'
|
||||
}
|
||||
|
||||
export enum PaymentTerms {
|
||||
IMMEDIATE = 'immediate',
|
||||
NET_30 = 'net_30',
|
||||
NET_60 = 'net_60'
|
||||
}
|
||||
|
||||
export enum PaymentMethod {
|
||||
CASH = 'cash',
|
||||
CARD = 'card',
|
||||
BANK_TRANSFER = 'bank_transfer',
|
||||
ACCOUNT = 'account'
|
||||
}
|
||||
|
||||
export enum PaymentStatus {
|
||||
PENDING = 'pending',
|
||||
PARTIAL = 'partial',
|
||||
PAID = 'paid',
|
||||
FAILED = 'failed',
|
||||
REFUNDED = 'refunded'
|
||||
}
|
||||
|
||||
export enum CustomerSegment {
|
||||
VIP = 'vip',
|
||||
REGULAR = 'regular',
|
||||
WHOLESALE = 'wholesale'
|
||||
}
|
||||
|
||||
export enum PriorityLevel {
|
||||
HIGH = 'high',
|
||||
NORMAL = 'normal',
|
||||
LOW = 'low'
|
||||
}
|
||||
|
||||
export enum OrderType {
|
||||
STANDARD = 'standard',
|
||||
RUSH = 'rush',
|
||||
RECURRING = 'recurring',
|
||||
SPECIAL = 'special'
|
||||
}
|
||||
|
||||
export enum OrderStatus {
|
||||
PENDING = 'pending',
|
||||
CONFIRMED = 'confirmed',
|
||||
IN_PRODUCTION = 'in_production',
|
||||
READY = 'ready',
|
||||
OUT_FOR_DELIVERY = 'out_for_delivery',
|
||||
DELIVERED = 'delivered',
|
||||
CANCELLED = 'cancelled',
|
||||
FAILED = 'failed'
|
||||
}
|
||||
|
||||
export enum OrderSource {
|
||||
MANUAL = 'manual',
|
||||
ONLINE = 'online',
|
||||
PHONE = 'phone',
|
||||
APP = 'app',
|
||||
API = 'api'
|
||||
}
|
||||
|
||||
export enum SalesChannel {
|
||||
DIRECT = 'direct',
|
||||
WHOLESALE = 'wholesale',
|
||||
RETAIL = 'retail'
|
||||
}
|
||||
|
||||
export enum BusinessModel {
|
||||
INDIVIDUAL_BAKERY = 'individual_bakery',
|
||||
CENTRAL_BAKERY = 'central_bakery'
|
||||
}
|
||||
|
||||
// ===== Customer Types =====
|
||||
|
||||
|
||||
Reference in New Issue
Block a user