Hi every body,
I have been developing PWA application which has tabs (6 tabs) and 2 of tabs are only for users that logged in. I am trying to show login/signup page when they head over those 2 tabs. My login/signup components wrapped around <IonPage>
and when every thing seems working fine but when I try to navigate to a nested route inside a tab (like Profile) when I press back button, everything breaks and I see other Tab content instead of Profile tab content. If I refresh the browser, everything works as expected but after login, everything breaks
Questions:
- what am I suppose to do if some part of application is public and some part is private ? how should I set up my Routes and Tabs structure ?
- Where should I put login/Signup page route, Login/Signup is not part of any tab ?
- Do I need a specific route for login/signup ? or I should return a simple component ?
App Component
export default function App() {
return (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route path="/tabs" render={() => <Tabs />} />
<Route exact path="/">
<Redirect to="/tabs" />
</Route>
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
)
}
Tabs Component
export default function Tabs() {
return (
<IonPage>
<IonContent>
<IonTabs>
<IonRouterOutlet>
<Redirect exact path="/tabs" to="/tabs/home"/>
<Route exact path={routes.home} component={HomeTab}/>
<Route exact path={routes.shoppingCart} component={ShoppingCartTab}/>
<Route exact path={routes.calendar} component={CalendarTab}/>
<Route exact path={routes.myPrograms} component={MyProgramTab}/>
<Route exact path={routes.etiquette} component={EtiquettesTab}/>
<Route path={routes.profile} component={ProfileTab}/>
<Route exact path={routes.myWorkoutProgram} component={MyWorkoutProgram}/>
<Route exact path={routes.myDietPlan} component={MyDietPlan}/>
<Route exact path={routes.myDailyWorkout} component={MyDailyWorkout}/>
<Route exact path={routes.myDailyDietPlan} component={MyDailyDietPlan}/>
<Route exact path={routes.confirmOtp} component={Otp}/>
<Route exact path={routes.editUserInfo} component={EditUserInfo}/>
<Route exact path={routes.editUserBodyInfo} component={UserBodyInfo}/>
<Route exact path={routes.changePassword} component={PasswordChange}/>
<Route exact path={routes.checkout} component={Checkout}/>
<Route exact path={routes.subscriptionPlans} component={SubscriptionPlan}/>
<Route exact path={routes.recommendation} component={Recommendation}/>
<Route exact path={routes.complain} component={Complain}/>
<Route exact path={routes.addWorkoutProgram} component={AddWorkoutProgram}/>
<Route exact path={routes.addDietPlan} component={AddWorkoutProgram}/>
<Route exact path={routes.workoutDays} component={WorkoutDays}/>
<Route exact path={routes.addSets} component={AddSets}/>
<Route exact path={routes.dietPlanDays} component={dietPlanDays}/>
<Route exact path={routes.addMeals} component={AddMeals}/>
<Route exact path={routes.notFound} component={NotFound}/>
<Route exact path={routes.rules} component={GymRules}/>
<Route exact path="/tabs">
<Redirect to={routes.home}/>
</Route>
<Redirect exact path="/" to="/tabs/home"/>
<Route component={NotFound}/>
</IonRouterOutlet>
<IonTabBar slot="bottom">
<IonTabButton tab="profile" href={routes.profile}>
<IonIcon aria-hidden="true" icon={personSharp} size='small'/>
<IonLabel>Profile</IonLabel>
</IonTabButton>
<IonTabButton tab="etiquette" href={routes.etiquette}>
<IonIcon aria-hidden="true" icon={readerSharp} size='small'/>
<IonLabel>Etiquette</IonLabel>
</IonTabButton>
<IonTabButton tab="my-program" href={routes.myPrograms}>
<IonIcon aria-hidden="true" icon={barbellSharp} size='small'/>
<IonLabel>My Programs</IonLabel>
</IonTabButton>
<IonTabButton tab="calendar" href={routes.calendar}>
<IonIcon aria-hidden="true" icon={calendarSharp} size='small'/>
<IonLabel>Calendar</IonLabel>
</IonTabButton>
<IonTabButton tab="cart" href={routes.shoppingCart}>
<IonIcon aria-hidden="true" icon={bagHandle} size='small'/>
<IonLabel>shopping Cart</IonLabel>
</IonTabButton>
<IonTabButton tab="home" href={routes.home}>
<IonIcon aria-hidden="true" icon={homeSharp} size='small'/>
<IonLabel>Home</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>
</IonContent>
</IonPage>
)
}
Routes File
export const routes = {
myDietPlan: "/tabs/my-programs/my-diet-plan",
myWorkoutProgram: "/tabs/my-programs/my-workout-program",
myDailyDietPlan: "/tabs/my-programs/my-daily-diet",
myDailyWorkout: "/tabs/my-programs/my-daily-workout",
default: "/",
home: "/tabs/home",
calendar: "/tabs/calendar",
shoppingCart: "/tabs/shopping-cart",
myPrograms: "/tabs/my-programs",
etiquette: "/tabs/etiquette",
profile: "/tabs/profile",
editUserInfo: "/tabs/profile/edit-user-info",
editUserBodyInfo: "/tabs/profile/edit-user-physical-info",
logout: "/tabs/profile/logout",
confirmOtp: "/tabs/profile/confirm-otp",
changePassword: "/tabs/profile/change-password",
checkout: "/tabs/shopping-cart/checkout",
subscriptionPlans: "/tabs/home/subscription-plans",
recommendation: "/tabs/profile/recommendation",
complain: "/tabs/profile/complain",
rules: "/tabs/profile/rules",
addWorkoutProgram: "/tabs/profile/add-workout-program",
addSets: "/tabs/profile/add-workout-program/add-sets",
workoutDays: "/tabs/profile/add-workout-program/workout-days",
addDietPlan: "/tabs/profile/add-diet-plan",
addMeals: "/tabs/profile/add-diet-plan/add-meals",
dietPlanDays: "/tabs/profile/add-diet-plan/diet-days",
notFound: "/not-found",
}
Login Component
export default function Login() {
const {register, handleSubmit, formState: {errors}} = useForm()
const [login, {status, isLoading, error, data}] = useLoginMutation()
const onSubmit = (data: any) => {
login({
phoneNumber: data.phoneNumber,
password: data.password,
deviceName: "iphone 13 pro max"
})
}
if (isLoading) {
return <Spinner/>
}
if (status === "rejected") {
console.log(error)
console.log("failed and you must show the error in the form")
}
return (
<IonPage>
<IonContent fullscreen>
<div className='authWrapper'>
<div className="signInContent">
<h2 style={{color: "white"}}>Sign In</h2>
<IonCard className="signInCard">
<IonCardContent>
<form onSubmit={handleSubmit(onSubmit)} className="signupCardForm">
<IonGrid>
<IonRow>
<IonCol className="inputCol">
<IonInput
label="Phone Number"
labelPlacement="floating"
fill="outline"
placeholder="Phone Number"
{...register("phoneNumber", {required: true})}
></IonInput>
</IonCol>
</IonRow>
<IonRow>
<IonCol>
<IonInput
label="password"
labelPlacement="floating"
fill="outline"
placeholder="password"
{...register("password", {required: true})}
></IonInput>
</IonCol>
</IonRow>
</IonGrid>
<IonButton type="submit" expand="block" className="loginBtn">
{isLoading ? <IonSpinner/> : 'ورود'}
</IonButton>
</form>
</IonCardContent>
</IonCard>
</div>
</div>
</IonContent>
</IonPage>
)
}