Remove unused useUrlState hook and sallaService
Both were implemented but never imported by any component. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1 +0,0 @@
|
||||
export { useUrlState } from './useUrlState';
|
||||
@@ -1,58 +0,0 @@
|
||||
import { useEffect, useCallback } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
|
||||
/**
|
||||
* Sync state with URL search params
|
||||
* @param {Object} state - Current state object
|
||||
* @param {Function} setState - State setter function
|
||||
* @param {Object} defaultState - Default state values
|
||||
* @param {Array<string>} keys - Keys to sync with URL
|
||||
*/
|
||||
export function useUrlState(state, setState, defaultState, keys) {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
|
||||
// Initialize state from URL on mount
|
||||
useEffect(() => {
|
||||
const urlState = {};
|
||||
let hasUrlParams = false;
|
||||
|
||||
keys.forEach(key => {
|
||||
const value = searchParams.get(key);
|
||||
if (value !== null) {
|
||||
urlState[key] = value;
|
||||
hasUrlParams = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (hasUrlParams) {
|
||||
setState(prev => ({ ...prev, ...urlState }));
|
||||
}
|
||||
}, []); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
// Update URL when state changes
|
||||
const updateUrl = useCallback((newState) => {
|
||||
const params = new URLSearchParams();
|
||||
|
||||
keys.forEach(key => {
|
||||
const value = newState[key];
|
||||
if (value && value !== defaultState[key]) {
|
||||
params.set(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
setSearchParams(params, { replace: true });
|
||||
}, [keys, defaultState, setSearchParams]);
|
||||
|
||||
// Wrap setState to also update URL
|
||||
const setStateWithUrl = useCallback((updater) => {
|
||||
setState(prev => {
|
||||
const newState = typeof updater === 'function' ? updater(prev) : updater;
|
||||
updateUrl(newState);
|
||||
return newState;
|
||||
});
|
||||
}, [setState, updateUrl]);
|
||||
|
||||
return setStateWithUrl;
|
||||
}
|
||||
|
||||
export default useUrlState;
|
||||
@@ -1,161 +0,0 @@
|
||||
// Salla Integration Service
|
||||
// Connects to the local Salla backend server
|
||||
|
||||
const SALLA_SERVER_URL = import.meta.env.VITE_SALLA_SERVER_URL || 'http://localhost:3001';
|
||||
|
||||
export interface SallaAuthStatus {
|
||||
connected: boolean;
|
||||
hasRefreshToken: boolean;
|
||||
}
|
||||
|
||||
export interface SallaOrder {
|
||||
id: number;
|
||||
reference_id: string;
|
||||
status: {
|
||||
id: string;
|
||||
name: string;
|
||||
customized: { id: string; name: string };
|
||||
};
|
||||
amounts: {
|
||||
total: { amount: number; currency: string };
|
||||
sub_total: { amount: number; currency: string };
|
||||
};
|
||||
customer: {
|
||||
id: number;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
email: string;
|
||||
mobile: string;
|
||||
};
|
||||
items: Array<{
|
||||
id: number;
|
||||
name: string;
|
||||
quantity: number;
|
||||
amounts: { total: { amount: number } };
|
||||
}>;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface SallaProduct {
|
||||
id: number;
|
||||
name: string;
|
||||
sku: string;
|
||||
price: { amount: number; currency: string };
|
||||
quantity: number;
|
||||
status: string;
|
||||
sold_quantity: number;
|
||||
}
|
||||
|
||||
export interface SallaSummary {
|
||||
orders: { total: number; recent: number };
|
||||
products: { total: number };
|
||||
revenue: { total: number; average_order: number; currency: string };
|
||||
}
|
||||
|
||||
export interface SallaStore {
|
||||
id: number;
|
||||
name: string;
|
||||
description: string;
|
||||
domain: string;
|
||||
plan: string;
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// API Functions
|
||||
// ============================================
|
||||
|
||||
export async function checkSallaAuth(): Promise<SallaAuthStatus> {
|
||||
try {
|
||||
const response = await fetch(`${SALLA_SERVER_URL}/auth/status`);
|
||||
return response.json();
|
||||
} catch (err) {
|
||||
return { connected: false, hasRefreshToken: false };
|
||||
}
|
||||
}
|
||||
|
||||
export function getSallaLoginUrl(): string {
|
||||
return `${SALLA_SERVER_URL}/auth/login`;
|
||||
}
|
||||
|
||||
export async function getSallaStore(): Promise<SallaStore | null> {
|
||||
try {
|
||||
const response = await fetch(`${SALLA_SERVER_URL}/api/store`);
|
||||
if (!response.ok) throw new Error('Failed to fetch store');
|
||||
const data = await response.json();
|
||||
return data.data;
|
||||
} catch (err) {
|
||||
console.error('Error fetching store:', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSallaOrders(page = 1, perPage = 50): Promise<{ data: SallaOrder[]; pagination: any }> {
|
||||
try {
|
||||
const response = await fetch(`${SALLA_SERVER_URL}/api/orders?page=${page}&per_page=${perPage}`);
|
||||
if (!response.ok) throw new Error('Failed to fetch orders');
|
||||
return response.json();
|
||||
} catch (err) {
|
||||
console.error('Error fetching orders:', err);
|
||||
return { data: [], pagination: {} };
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSallaProducts(page = 1, perPage = 50): Promise<{ data: SallaProduct[]; pagination: any }> {
|
||||
try {
|
||||
const response = await fetch(`${SALLA_SERVER_URL}/api/products?page=${page}&per_page=${perPage}`);
|
||||
if (!response.ok) throw new Error('Failed to fetch products');
|
||||
return response.json();
|
||||
} catch (err) {
|
||||
console.error('Error fetching products:', err);
|
||||
return { data: [], pagination: {} };
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSallaSummary(): Promise<SallaSummary | null> {
|
||||
try {
|
||||
const response = await fetch(`${SALLA_SERVER_URL}/api/analytics/summary`);
|
||||
if (!response.ok) throw new Error('Failed to fetch summary');
|
||||
return response.json();
|
||||
} catch (err) {
|
||||
console.error('Error fetching summary:', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// Data Transformation for Dashboard
|
||||
// ============================================
|
||||
|
||||
export function transformOrdersForChart(orders: SallaOrder[]): {
|
||||
labels: string[];
|
||||
datasets: { label: string; data: number[] }[];
|
||||
} {
|
||||
// Group orders by date
|
||||
const byDate: Record<string, number> = {};
|
||||
|
||||
orders.forEach(order => {
|
||||
const date = order.created_at.split('T')[0];
|
||||
byDate[date] = (byDate[date] || 0) + (order.amounts?.total?.amount || 0);
|
||||
});
|
||||
|
||||
const sortedDates = Object.keys(byDate).sort();
|
||||
|
||||
return {
|
||||
labels: sortedDates,
|
||||
datasets: [{
|
||||
label: 'Daily Revenue (SAR)',
|
||||
data: sortedDates.map(d => byDate[d])
|
||||
}]
|
||||
};
|
||||
}
|
||||
|
||||
export function getOrderStatusSummary(orders: SallaOrder[]): Record<string, number> {
|
||||
const byStatus: Record<string, number> = {};
|
||||
|
||||
orders.forEach(order => {
|
||||
const status = order.status?.name || 'Unknown';
|
||||
byStatus[status] = (byStatus[status] || 0) + 1;
|
||||
});
|
||||
|
||||
return byStatus;
|
||||
}
|
||||
Reference in New Issue
Block a user