Files
starr-philproperties/src/contexts/StaffUserContext.jsx
T
2026-07-07 13:40:07 +08:00

93 lines
3.0 KiB
React

import { createContext, useContext, useState, useCallback } from "react";
import api from "@/utils/api.util";
import { toast } from "sonner";
const StaffUserContext = createContext(null);
export const useStaffUsers = () => {
const ctx = useContext(StaffUserContext);
if (!ctx) throw new Error("useStaffUsers must be used inside StaffUserProvider");
return ctx;
};
const PAGINATION_INIT = {
page: 1,
limit: 10,
totalRecords: 0,
totalPages: 0,
hasPrevPage: false,
hasNextPage: false,
};
const BASE = "/staff";
export const StaffUserProvider = ({ children }) => {
const [users, setUsers] = useState([]);
const [user, setUser] = useState(null);
const [pagination, setPagination] = useState(PAGINATION_INIT);
const [attributes, setAttributes] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const request = useCallback(async (fn) => {
setLoading(true);
setError(null);
try {
return await fn();
} catch (err) {
const message = err?.response?.data?.message || err.message || "Something went wrong.";
setError(message);
toast(message);
return null;
} finally {
setLoading(false);
}
}, []);
// ─── GET /api/staff/users ─────────────────────────────────────────────────
// Returns users scoped to the logged-in staff member's groups.
// Optional query: group_id or group_code to filter to one group.
const fetchUsers = useCallback(
({ page = 1, limit = 10, group_id, group_code, filters = [], sort = [] } = {}) =>
request(async () => {
const { data } = await api.get(`${BASE}/users`, {
params: {
page, limit,
...(group_id && { group_id }),
...(group_code && { group_code }),
filters: filters.length ? JSON.stringify(filters) : undefined,
sort: sort.length ? JSON.stringify(sort) : undefined,
},
});
const final_data = data?.data;
setUsers(final_data?.data ?? []);
setPagination(final_data?.pagination ?? PAGINATION_INIT);
setAttributes(final_data?.attributes ?? []);
return data?.data;
}),
[request]
);
// ─── GET /api/staff/users/:user_id ───────────────────────────────────────
// Returns a single user profile — only if they share a group with the staff member.
const fetchUser = useCallback(
(userId) =>
request(async () => {
const res = await api.get(`${BASE}/users/${userId}`);
setUser(res.data?.data ?? null);
return res.data;
}),
[request]
);
return (
<StaffUserContext.Provider value={{
users, user, pagination, attributes, loading, error,
setPagination,
fetchUsers, fetchUser,
}}>
{children}
</StaffUserContext.Provider>
);
};