add workspace navbar status + creation modal

This commit is contained in:
2026-03-12 09:20:25 +08:00
parent bc099512db
commit 94489a7769
11 changed files with 648 additions and 16 deletions

View File

@@ -2,7 +2,6 @@ import { API_BASE_URL } from "../config/constants";
export const authFetch = async (endpoint: string, options: RequestInit = {}) => {
const token = localStorage.getItem("accessToken");
const isFormData = options.body instanceof FormData;
const headers: HeadersInit = {
@@ -11,7 +10,12 @@ export const authFetch = async (endpoint: string, options: RequestInit = {}) =>
...options.headers,
};
const response = await fetch(`${API_BASE_URL}${endpoint}`, {
// Safely join URLs preventing double slashes (e.g., "http://api.com//api/..." -> "http://api.com/api/...")
const cleanBaseUrl = API_BASE_URL.replace(/\/+$/, "");
const cleanEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
const url = `${cleanBaseUrl}${cleanEndpoint}`;
const response = await fetch(url, {
...options,
headers,
});

View File

@@ -78,3 +78,22 @@ export const removeProfilePicture = async () => {
body: formData,
});
};
export interface SearchedUser {
id: number | string;
first_name: string;
last_name: string;
mobile: string;
profile_picture: string | null;
}
export const searchUserByExactMobile = async (mobile: string): Promise<SearchedUser | null> => {
try {
const response = await authFetch(`/api/users/search/?mobile=${encodeURIComponent(mobile)}`);
if (!response.ok) return null; // Returns null on 404 or other errors
return await response.json();
} catch (error) {
return null;
}
};

42
src/api/workspaces.ts Normal file
View File

@@ -0,0 +1,42 @@
import { authFetch } from "./client"
export interface Workspace {
id: string
name: string
[key: string]: any
}
export const fetchWorkspaces = async (): Promise<Workspace[]> => {
const response = await authFetch("/api/workspaces/")
if (!response.ok) {
throw new Error("Failed to fetch workspaces")
}
const data = await response.json()
// Handles paginated responses if the API returns { count, next, previous, results: [...] }
return data.results || data
}
export const createWorkspace = async (data: { name: string; description: string; members?: any[] }) => {
// 1. Only send name and description to the workspaces endpoint
const payload = {
name: data.name,
description: data.description,
};
const response = await authFetch('/api/workspaces/', {
method: 'POST',
headers: {
'Content-Type': 'application/json', // CRITICAL for DRF to parse the string correctly
},
body: JSON.stringify(payload),
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || 'Failed to create workspace');
}
const newWorkspace = await response.json();
return newWorkspace;
};