feat(auth): implement multi-step registration process and enhance background services
- Updated RegisterScreen to support a multi-step registration flow with components for email input, verification, and profile setup. - Added new components: VerificationCodeInput, StepIndicator, and corresponding types for step management. - Enhanced background service to check authentication status before executing tasks, improving app reliability. - Updated TypeScript configuration to include module resolution and JSON module support. This update significantly improves the user registration experience and ensures background tasks are only executed for authenticated users.
This commit is contained in:
180
src/stores/registerStore.ts
Normal file
180
src/stores/registerStore.ts
Normal file
@@ -0,0 +1,180 @@
|
||||
/**
|
||||
* 注册流程状态管理
|
||||
* 使用 Zustand + AsyncStorage 实现步骤数据的持久化
|
||||
*/
|
||||
|
||||
import { create } from 'zustand';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
const STORAGE_KEY = 'register_form_data';
|
||||
|
||||
export type RegisterStep = 0 | 1 | 2;
|
||||
|
||||
export interface RegisterFormData {
|
||||
email: string;
|
||||
verificationCode: string;
|
||||
username: string;
|
||||
nickname: string;
|
||||
phone: string;
|
||||
password: string;
|
||||
confirmPassword: string;
|
||||
}
|
||||
|
||||
interface RegisterState {
|
||||
// 当前步骤: 0=邮箱, 1=验证码, 2=用户信息
|
||||
currentStep: RegisterStep;
|
||||
|
||||
// 表单数据
|
||||
formData: RegisterFormData;
|
||||
|
||||
// 倒计时(秒)
|
||||
countdown: number;
|
||||
|
||||
// 步骤完成状态
|
||||
completedSteps: Record<RegisterStep, boolean>;
|
||||
|
||||
// Actions
|
||||
setCurrentStep: (step: RegisterStep) => void;
|
||||
updateFormData: (data: Partial<RegisterFormData>) => void;
|
||||
setCountdown: (seconds: number) => void;
|
||||
decrementCountdown: () => void;
|
||||
markStepCompleted: (step: RegisterStep) => void;
|
||||
resetRegisterData: () => void;
|
||||
goToNextStep: () => void;
|
||||
goToPrevStep: () => void;
|
||||
// 持久化
|
||||
hydrate: () => Promise<void>;
|
||||
persistData: () => Promise<void>;
|
||||
}
|
||||
|
||||
const initialFormData: RegisterFormData = {
|
||||
email: '',
|
||||
verificationCode: '',
|
||||
username: '',
|
||||
nickname: '',
|
||||
phone: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
};
|
||||
|
||||
const initialCompletedSteps: Record<RegisterStep, boolean> = {
|
||||
0: false,
|
||||
1: false,
|
||||
2: false,
|
||||
};
|
||||
|
||||
export const useRegisterStore = create<RegisterState>((set, get) => ({
|
||||
currentStep: 0,
|
||||
formData: initialFormData,
|
||||
countdown: 0,
|
||||
completedSteps: initialCompletedSteps,
|
||||
|
||||
setCurrentStep: (step) => {
|
||||
set({ currentStep: step });
|
||||
get().persistData();
|
||||
},
|
||||
|
||||
updateFormData: (data) =>
|
||||
set((state) => {
|
||||
const newFormData = { ...state.formData, ...data };
|
||||
// 异步保存到 AsyncStorage
|
||||
AsyncStorage.setItem(
|
||||
STORAGE_KEY,
|
||||
JSON.stringify({
|
||||
currentStep: state.currentStep,
|
||||
formData: newFormData,
|
||||
completedSteps: state.completedSteps,
|
||||
})
|
||||
).catch(() => {});
|
||||
return { formData: newFormData };
|
||||
}),
|
||||
|
||||
setCountdown: (seconds) => set({ countdown: seconds }),
|
||||
|
||||
decrementCountdown: () =>
|
||||
set((state) => ({
|
||||
countdown: state.countdown > 0 ? state.countdown - 1 : 0,
|
||||
})),
|
||||
|
||||
markStepCompleted: (step) =>
|
||||
set((state) => {
|
||||
const newCompletedSteps = { ...state.completedSteps, [step]: true };
|
||||
// 异步保存到 AsyncStorage
|
||||
AsyncStorage.setItem(
|
||||
STORAGE_KEY,
|
||||
JSON.stringify({
|
||||
currentStep: state.currentStep,
|
||||
formData: state.formData,
|
||||
completedSteps: newCompletedSteps,
|
||||
})
|
||||
).catch(() => {});
|
||||
return { completedSteps: newCompletedSteps };
|
||||
}),
|
||||
|
||||
resetRegisterData: () => {
|
||||
set({
|
||||
currentStep: 0,
|
||||
formData: initialFormData,
|
||||
countdown: 0,
|
||||
completedSteps: initialCompletedSteps,
|
||||
});
|
||||
AsyncStorage.removeItem(STORAGE_KEY).catch(() => {});
|
||||
},
|
||||
|
||||
goToNextStep: () => {
|
||||
const { currentStep } = get();
|
||||
if (currentStep < 2) {
|
||||
const newStep = (currentStep + 1) as RegisterStep;
|
||||
set({ currentStep: newStep });
|
||||
get().persistData();
|
||||
}
|
||||
},
|
||||
|
||||
goToPrevStep: () => {
|
||||
const { currentStep } = get();
|
||||
if (currentStep > 0) {
|
||||
const newStep = (currentStep - 1) as RegisterStep;
|
||||
set({ currentStep: newStep });
|
||||
get().persistData();
|
||||
}
|
||||
},
|
||||
|
||||
// 从 AsyncStorage 恢复数据
|
||||
hydrate: async () => {
|
||||
try {
|
||||
const raw = await AsyncStorage.getItem(STORAGE_KEY);
|
||||
if (raw) {
|
||||
const data = JSON.parse(raw);
|
||||
set({
|
||||
currentStep: data.currentStep ?? 0,
|
||||
formData: { ...initialFormData, ...data.formData },
|
||||
completedSteps: { ...initialCompletedSteps, ...data.completedSteps },
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// 忽略错误
|
||||
}
|
||||
},
|
||||
|
||||
// 保存数据到 AsyncStorage
|
||||
persistData: async () => {
|
||||
const { currentStep, formData, completedSteps } = get();
|
||||
try {
|
||||
await AsyncStorage.setItem(
|
||||
STORAGE_KEY,
|
||||
JSON.stringify({
|
||||
currentStep,
|
||||
formData,
|
||||
completedSteps,
|
||||
})
|
||||
);
|
||||
} catch {
|
||||
// 忽略错误
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
// 导出便捷 hooks
|
||||
export const useRegisterStep = () => useRegisterStore((state) => state.currentStep);
|
||||
export const useRegisterFormData = () => useRegisterStore((state) => state.formData);
|
||||
export const useRegisterCountdown = () => useRegisterStore((state) => state.countdown);
|
||||
Reference in New Issue
Block a user