"chore: update frontend dev script to include lint checks and add ESLint config file"

This commit is contained in:
louiscklaw
2025-06-04 02:35:32 +08:00
parent c0fad42f0a
commit 22fb620eef
48 changed files with 3315 additions and 97 deletions

View File

@@ -11,9 +11,7 @@ export const AppContext = createContext<AppContextState>({
dispatch: () => undefined,
});
export const AppContextProvider: React.FC<PropsWithChildren> = ({
children,
}) => {
export const AppContextProvider: React.FC<PropsWithChildren> = ({ children }) => {
const [store, dispatch] = useReducer(reducers, initialState);
return (

View File

@@ -1,4 +1,4 @@
import { Preferences as Storage } from '@capacitor/preferences';
import { GetResult, Preferences as Storage } from '@capacitor/preferences';
import { Schedule, Session } from '../models/Schedule';
import { Speaker } from '../models/Speaker';
import { Location } from '../models/Location';
@@ -13,6 +13,8 @@ const locationsUrl = '/assets/data/locations.json';
const HAS_LOGGED_IN = 'hasLoggedIn';
const HAS_SEEN_TUTORIAL = 'hasSeenTutorial';
const USERNAME = 'username';
const ACCESS_TOKEN = 'a_token';
const ACTIVE_SESSION = 'a_session';
export const getConfData = async () => {
const response = await Promise.all([
@@ -116,6 +118,18 @@ export const setUsernameData = async (username?: string) => {
}
};
export const setAccessTokenData = async (accessToken?: string) => {
if (!accessToken) {
await Storage.remove({ key: ACCESS_TOKEN });
} else {
await Storage.set({ key: ACCESS_TOKEN, value: accessToken });
}
};
export const getAccessTokenData = async (): Promise<GetResult> => {
return Storage.get({ key: ACCESS_TOKEN });
};
function parseSessions(schedule: Schedule) {
const sessions: Session[] = [];
schedule.groups.forEach((g) => {
@@ -123,3 +137,15 @@ function parseSessions(schedule: Schedule) {
});
return sessions;
}
export const setActiveSessionData = async (activeSession: any) => {
if (!activeSession) {
await Storage.remove({ key: ACTIVE_SESSION });
} else {
await Storage.set({ key: ACTIVE_SESSION, value: JSON.stringify(activeSession) });
}
};
export const getActiveSessionData = async (): Promise<GetResult> => {
return Storage.get({ key: JSON.parse(ACTIVE_SESSION) });
};

View File

@@ -28,6 +28,8 @@ export const initialState: AppState = {
darkMode: false,
isLoggedin: false,
loading: false,
//
isSessionValid: false,
},
locations: {
locations: [],

View File

@@ -3,9 +3,15 @@ import {
setIsLoggedInData,
setUsernameData,
setHasSeenTutorialData,
setAccessTokenData,
getAccessTokenData,
setActiveSessionData,
} from '../dataApi';
import { ActionType } from '../../util/types';
import { UserState } from './user.state';
import { isValidToken } from '../../context/jwt/utils';
import axios from 'axios';
import { endpoints } from '../../pages/MyLogin/endpoints';
export const loadUserData = () => async (dispatch: React.Dispatch<any>) => {
dispatch(setLoading(true));
@@ -15,10 +21,7 @@ export const loadUserData = () => async (dispatch: React.Dispatch<any>) => {
};
export const setLoading = (isLoading: boolean) =>
({
type: 'set-user-loading',
isLoading,
} as const);
({ type: 'set-user-loading', isLoading } as const);
export const setData = (data: Partial<UserState>) =>
({
@@ -47,6 +50,53 @@ export const setUsername = (username?: string) => async (dispatch: React.Dispatc
} as const;
};
export const setAccessToken = (token?: string) => async (dispatch: React.Dispatch<any>) => {
await setAccessTokenData(token);
return {
type: 'set-access-token',
token,
} as const;
};
export const setActiveSession = (session: any) => async (dispatch: React.Dispatch<any>) => {
await setActiveSessionData(session);
return {
type: 'set-active-session',
session,
} as const;
};
export const checkUserSession = () => async (dispatch: React.Dispatch<any>) => {
let accessToken = (await getAccessTokenData()).value;
console.log('check user session');
let sessionValid = false;
try {
if (accessToken && isValidToken(accessToken)) {
const res = await axios.get(endpoints.auth.me, {
headers: { Authorization: `Bearer ${accessToken}` },
});
const { user } = res.data;
setActiveSession({ user: { ...user, accessToken }, loading: false });
sessionValid = true;
console.log('session valid');
} else {
setActiveSession({ user: null, loading: false });
console.log('session not valid');
}
} catch (error) {
console.error(error);
setActiveSession({ user: null, loading: false });
}
return {
type: 'check-user-session',
sessionValid,
} as const;
};
export const setHasSeenTutorial =
(hasSeenTutorial: boolean) => async (dispatch: React.Dispatch<any>) => {
await setHasSeenTutorialData(hasSeenTutorial);
@@ -68,4 +118,7 @@ export type UserActions =
| ActionType<typeof setIsLoggedIn>
| ActionType<typeof setUsername>
| ActionType<typeof setHasSeenTutorial>
| ActionType<typeof setDarkMode>;
| ActionType<typeof setDarkMode>
| ActionType<typeof setAccessToken>
// | ActionType<typeof setSession>
| ActionType<typeof checkUserSession>;

View File

@@ -15,5 +15,11 @@ export function userReducer(state: UserState, action: UserActions): UserState {
return { ...state, darkMode: action.darkMode };
case 'set-is-loggedin':
return { ...state, isLoggedin: action.loggedIn };
case 'check-user-session':
return { ...state, isSessionValid: action.sessionValid };
// case 'set-active-session':
// return { ...state, session: action.session };
// case 'set-access-token':
// return { ...state, token: action.token };
}
}

View File

@@ -4,4 +4,7 @@ export interface UserState {
darkMode: boolean;
hasSeenTutorial: boolean;
loading: boolean;
isSessionValid: boolean;
session?: any;
token?: string;
}