update frontend ui chages
This commit is contained in:
117
src/api/local/auth.js
Normal file
117
src/api/local/auth.js
Normal 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;
|
||||
Reference in New Issue
Block a user