Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"@mui/icons-material": "^7.2.0",
"@mui/material": "^7.2.0",
"@tailwindcss/vite": "^4.1.12",
"axios": "^1.8.1",
"axios": "^1.12.2",
"firebase": "^11.4.0",
"framer-motion": "^12.4.7",
"jotai": "^2.13.1",
Expand All @@ -62,6 +62,6 @@
"globals": "^16.3.0",
"typescript": "~5.8.3",
"typescript-eslint": "^8.39.1",
"vite": "^7.1.2"
"vite": "^7.1.11"
}
}
85 changes: 70 additions & 15 deletions client/src/infra/rest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,71 @@ enum Methods {
PATCH = 'PATCH',
}

// ✅ NEW IMPLEMENTATION (internal)
const BASE_URL = 'https://code-a2z-server.vercel.app/api';

const makeNewRequest = async (url: string, options: any = {}) => {
const cleanUrl = url.startsWith('/') ? url.slice(1) : url;
const fullUrl = `${BASE_URL}/${cleanUrl}`;

console.log('🌐 API Request:', fullUrl);

const token = localStorage.getItem('token');

const config = {
url: fullUrl,
...options,
timeout: 15000,
headers: {
'Content-Type': 'application/json',
...(token && { Authorization: `Bearer ${token}` }),
...options.headers,
},
withCredentials: true,
};

try {
const response = await axios(config);
return response.data;
} catch (error: any) {
console.error('❌ API Error:', {
url: fullUrl,
status: error.response?.status,
data: error.response?.data,
message: error.message,
});
throw error;
}
};

// ✅ OLD API - MAINTAINED FOR COMPATIBILITY
export async function makeRequest<T, D = undefined>(
url: string,
method: Methods,
isAuthRequired: boolean,
_isAuthRequired: boolean,
data?: D,
hasFullURL?: boolean,
headers?: Record<string, string>
): Promise<T> {
let token: string | null = null;

if (isAuthRequired) {
token = localStorage.getItem('token');
}
if (!hasFullURL) {
url = VITE_SERVER_DOMAIN + url;
}

const response = await axios({
url,
// Convert old parameters to new format
const requestOptions: any = {
method,
data,
headers: {
Authorization: token ? `Bearer ${token}` : undefined,
...headers,
},
});
return response.data;
};

// Handle URL construction
let finalUrl = url;
if (!hasFullURL) {
finalUrl = VITE_SERVER_DOMAIN + url;
}

return makeNewRequest(finalUrl, requestOptions);
}

// ✅ OLD FUNCTIONS - MAINTAINED
export async function get<T, D = undefined>(
url: string,
isAuthRequired: boolean,
Expand Down Expand Up @@ -122,3 +158,22 @@ export async function del<T, D = undefined>(
headers
);
}

// ✅ NEW FUNCTIONS - ADDED FOR NEW CODE
export const newGet = (url: string, options?: any) =>
makeNewRequest(url, { method: 'GET', ...options });

export const newPost = (url: string, data: any, options?: any) =>
makeNewRequest(url, { method: 'POST', data, ...options });

export const newPut = (url: string, data: any, options?: any) =>
makeNewRequest(url, { method: 'PUT', data, ...options });

export const newPatch = (url: string, data: any, options?: any) =>
makeNewRequest(url, { method: 'PATCH', data, ...options });

export const newDel = (url: string, options?: any) =>
makeNewRequest(url, { method: 'DELETE', ...options });

// ✅ DEFAULT EXPORT FOR NEW CODE
export default makeNewRequest;
41 changes: 41 additions & 0 deletions client/src/modules/search/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// client/src/modules/search/api.ts
import { makeRequest } from '../../infra/rest';
import { AllProjectsData } from '../../shared/typings';
import { UserProfile } from './typings';

export const fetchProjects = async (
query?: string
): Promise<AllProjectsData> => {
// Use existing makeRequest function
// Replace with real endpoint if available
const response = await makeRequest('/projects', { method: 'GET' });
if (query) {
const searchTerm = query.toLowerCase();
response.results = response.results.filter(
(project: any) =>
project.title.toLowerCase().includes(searchTerm) ||
project.description.toLowerCase().includes(searchTerm) ||
project.tags.some((tag: string) =>
tag.toLowerCase().includes(searchTerm)
)
);
}
return response;
};

export const fetchUsers = async (query?: string): Promise<UserProfile[]> => {
// Replace with real endpoint if available
const response: UserProfile[] = [
// mockUsers array
];
if (query) {
const searchTerm = query.toLowerCase();
return response.filter(
user =>
user.personal_info.fullname.toLowerCase().includes(searchTerm) ||
user.personal_info.username.toLowerCase().includes(searchTerm) ||
user.personal_info.bio?.toLowerCase().includes(searchTerm)
);
}
return response;
};
Loading