update frontend ui chages

This commit is contained in:
2026-08-17 23:45:32 +05:30
parent 9a7852c8a2
commit ff841f8b86
278 changed files with 14841 additions and 14597 deletions

117
src/api/local/auth.js Normal file
View File

@@ -0,0 +1,117 @@
/**
* Local user — replaces the hosted login/session that used to gate the app.
*
* There is no sign-in step and no session to check: the app opens straight into
* the KROW UI as a single local operator. The user is a row in the local `User`
* collection, so profile edits (`updateMe`) and the User Management page write
* to the same place, and both survive a reload via localStorage.
*
* `logout()` stays because the menu item does — locally it resets the profile to
* its defaults and keeps the user in the app.
*/
import { entities } from './store';
import defaultAvatar from '@/assets/krow-logo.webp';
export const LOCAL_USER_ID = 'local-user';
/** The default operator profile: enough for every UI state that reads a user. */
export const DEFAULT_USER = {
id: LOCAL_USER_ID,
full_name: 'KROW Operator',
email: 'operator@krow.local',
// `role` is the platform-level flag the UI checks for admin-only affordances;
// `user_role` drives which navigation set the sidebar renders.
role: 'admin',
user_role: 'admin',
company_name: 'KROW',
phone: '(415) 555-0100',
profile_picture: null,
is_active: true,
};
/**
* Kept in sync with the User collection so anything reading the user
* synchronously (created_by stamping, for instance) sees current values.
*/
let currentUser = { ...DEFAULT_USER };
/**
* Memoised, not a boolean flag: several components ask for the user at once on
* first paint, and two concurrent hydrations would each miss the row and create
* a duplicate.
*/
let hydration = null;
function hydrate() {
if (!hydration) {
hydration = (async () => {
const rows = await entities.User.filter({ id: LOCAL_USER_ID });
let user = rows.length
? { ...DEFAULT_USER, ...rows[0] }
: await entities.User.create({ ...DEFAULT_USER });
if (user.profile_picture === defaultAvatar) {
user = await entities.User.update(LOCAL_USER_ID, { profile_picture: null });
}
currentUser = user;
return currentUser;
})();
}
return hydration;
}
export const getCurrentUser = () => currentUser;
/**
* Forget the cached profile — used after local data is reset, so the next read
* re-creates the operator row instead of writing to one that is gone.
*/
export function resetLocalUser() {
hydration = null;
currentUser = { ...DEFAULT_USER };
}
/** Write a patch to the profile row, re-creating it if it has been wiped. */
async function writeProfile(patch) {
await hydrate();
try {
currentUser = await entities.User.update(LOCAL_USER_ID, patch);
} catch {
currentUser = await entities.User.create({ ...DEFAULT_USER, ...patch, id: LOCAL_USER_ID });
}
return { ...currentUser };
}
export const auth = {
/** The current (local) user. Never throws and never hits the network. */
async me() {
return { ...(await hydrate()) };
},
/** Same value as `me()`, kept because some call sites use this name. */
async currentUser() {
return { ...(await hydrate()) };
},
/** Always true — the app has no unauthenticated state any more. */
async isAuthenticated() {
return true;
},
/** Patch the local profile. Persisted with the rest of the local data. */
async updateMe(data = {}) {
return writeProfile(data);
},
/**
* There is no session to end. Reset the profile back to its defaults and stay
* in the app, so the "Sign out" menu item does something honest instead of
* bouncing the user to an external login page.
*/
async logout() {
return writeProfile({ ...DEFAULT_USER });
},
};
export default auth;