Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/(app)/(authorized)/(tabs)/example/user-session.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { UserSessionScreen } from '@baca/screens'

export default UserSessionScreen
Binary file modified assets/logo/logo-sygnet-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@
"expo-web-browser": "~12.8.2",
"i18next": "^23.7.20",
"jotai": "^2.4.3",
"jwt-decode": "^4.0.0",
"moti": "^0.25.3",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand Down
4 changes: 3 additions & 1 deletion src/api/axios/custom-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Axios, { AxiosError, AxiosRequestConfig } from 'axios'
import i18n from 'i18next'
import qs from 'qs'

import { injectTokenToRequest } from './interceptors'
import { injectTokenToRequest, signOutWhenNotAuthorized } from './interceptors'

type ApiErrorType = {
error: string
Expand Down Expand Up @@ -63,6 +63,8 @@ AXIOS_INSTANCE.interceptors.response.use(
return
}

await signOutWhenNotAuthorized(error)

// TODO: we should handle certain error type
if (errorMessage) {
showErrorToast({ description: errorMessage })
Expand Down
1 change: 1 addition & 0 deletions src/api/axios/interceptors/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './injectToken'
export * from './signOutWhenNotAuthorized'
4 changes: 2 additions & 2 deletions src/api/axios/interceptors/injectToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export const injectTokenToRequest = async (
): Promise<InternalAxiosRequestConfig<object>> => {
const token = await getToken()

if (token) {
config.headers['Authorization'] = `Bearer ${token}`
if (token?.accessToken) {
config.headers['Authorization'] = `Bearer ${token.accessToken}`
}

return config
Expand Down
45 changes: 45 additions & 0 deletions src/api/axios/interceptors/signOutWhenNotAuthorized.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
isForceUpdateNeededAtom,
isSignedInAtom,
logoutMessageShownAtom,
signOut,
store,
} from '@baca/store'
import { alert } from '@baca/utils'
import { AxiosError } from 'axios'
import { router } from 'expo-router'
import i18n from 'i18next'

export const signOutWhenNotAuthorized = async (error: AxiosError) => {
const isSignedIn = store.get(isSignedInAtom)

if (!isSignedIn) {
return
}

if (!error?.config?.headers?.Authorization && error.response?.status !== 401) {
return
}

const isTokenInvalid = error?.config?.baseURL && error.response?.status === 401

const isForceUpdateNeeded = store.get(isForceUpdateNeededAtom)

const logoutMessageShown = store.get(logoutMessageShownAtom)

if (!isForceUpdateNeeded && isTokenInvalid && !logoutMessageShown) {
store.set(logoutMessageShownAtom, true)
alert(i18n.t('alert.session_expired.title'), i18n.t('alert.session_expired.description'), [
{
text: 'Ok',
onPress: async () => {
await signOut()

router.replace('/sign-in')

store.set(logoutMessageShownAtom, false)
},
},
])
}
}
7 changes: 3 additions & 4 deletions src/components/LandingHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { lightBinarLogo, darkBinarLogo } from '@baca/constants'
import { useColorScheme } from '@baca/contexts'
import { Box, Button, Icon, Pressable, Spacer } from '@baca/design-system'
import { useCallback, useTranslation } from '@baca/hooks'
import { TabColorsStrings } from '@baca/navigation/tabNavigator/navigation-config'
import { useCallback, useTheme, useTranslation } from '@baca/hooks'
import { isSignedInAtom } from '@baca/store/auth'
import { useRouter } from 'expo-router'
import { useAtomValue } from 'jotai'
Expand All @@ -11,6 +10,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context'

export function LandingHeader() {
const { colorScheme } = useColorScheme()
const { colors } = useTheme()
const { top } = useSafeAreaInsets()
const { t } = useTranslation()
const { push, canGoBack, back } = useRouter()
Expand All @@ -25,7 +25,7 @@ export function LandingHeader() {
return (
<View
style={[
{ height, paddingTop: top },
{ borderBottomColor: colors.border.secondary, height, paddingTop: top },
jsStyles.appHeader,
Platform.select({ default: {}, web: { display: 'flex' } }),
]}
Expand Down Expand Up @@ -58,7 +58,6 @@ export function LandingHeader() {
const jsStyles = StyleSheet.create({
appHeader: {
alignItems: 'center',
borderBottomColor: TabColorsStrings.lightGray,
borderBottomWidth: 1,
flexDirection: 'row',
justifyContent: 'space-between',
Expand Down
1 change: 1 addition & 0 deletions src/constants/asyncStorageKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export const ASYNC_STORAGE_KEYS = {
NEXT_DEEP_LINK: '@navigation/next_deeplink',
PUSH_TOKEN: '@notification/push-token',
USER_LANGUAGE: '@language/user-language',
USER_REFRESH_TOKEN: 'user_refresh_token', // This value is used in `expo-secure-store` package and it can't include '@' and '/'
USER_TOKEN: 'user_token', // This value is used in `expo-secure-store` package and it can't include '@' and '/'
WAS_PUSH_TOKEN_SEND: '@notification/was-push-token-send',
} as const
6 changes: 5 additions & 1 deletion src/hooks/forms/useSignInForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ export const useSignInForm = () => {
hapticImpact()
},
onSuccess: async (response) => {
await setToken(response.accessToken)
const { user, ...token } = response
if (token) {
await setToken(token)
}

setIsSignedIn(true)

// Send push token to backend
Expand Down
28 changes: 12 additions & 16 deletions src/hooks/navigation/usePreventGoBack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,22 +40,18 @@ export const usePreventGoBack = (preventRemove = true) => {

e.preventDefault()

alert(
t('navigation.prevent_go_back_alert.title'),
t('navigation.prevent_go_back_alert.description'),
[
{
text: t('navigation.prevent_go_back_alert.do_not_leave'),
style: 'cancel',
onPress: () => undefined,
},
{
text: t('navigation.prevent_go_back_alert.discard'),
style: 'destructive',
onPress: () => navigation.dispatch(e?.data?.action),
},
]
)
alert(t('alert.prevent_go_back.title'), t('alert.prevent_go_back.description'), [
{
text: t('alert.prevent_go_back.do_not_leave'),
style: 'cancel',
onPress: () => undefined,
},
{
text: t('alert.prevent_go_back.discard'),
style: 'destructive',
onPress: () => navigation.dispatch(e?.data?.action),
},
])
})

React.useEffect(
Expand Down
19 changes: 13 additions & 6 deletions src/i18n/translations/en.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
{
"alert": {
"prevent_go_back": {
"description": "You have unsaved changes. Are you sure to discard them and leave the screen?",
"discard": "Discard",
"do_not_leave": "Don't leave",
"title": "Discard changes?"
},
"session_expired": {
"description": "Try to log in again",
"title": "Your current session expired"
}
},
"common": {
"add": "Add",
"back": "Back",
Expand Down Expand Up @@ -55,12 +67,6 @@
}
},
"navigation": {
"prevent_go_back_alert": {
"description": "You have unsaved changes. Are you sure to discard them and leave the screen?",
"discard": "Discard",
"do_not_leave": "Don't leave",
"title": "Discard changes?"
},
"screen_titles": {
"application_info": "ApplicationInfo",
"blog": "Blog",
Expand Down Expand Up @@ -175,6 +181,7 @@
"go_to_screen_with_BEdata": "Go to screen with data from BE",
"go_to_settings": "Go to Settings",
"go_to_typography": "Go to Typography",
"go_to_user_session": "Go to user session",
"header": "This is Example screen"
},
"forgot_password_screen": {
Expand Down
27 changes: 17 additions & 10 deletions src/i18n/translations/pl.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
{
"alert": {
"prevent_go_back": {
"description": "Masz niezapisane zmiany. Jesteś pewny, że chcesz je porzucić i wyjść?",
"discard": "Porzuć",
"do_not_leave": "Nie wychodź",
"title": "Anulować zmiany?"
},
"session_expired": {
"description": "Spróbuj zalogować się ponownie",
"title": "Twoja sesja wygasła"
}
},
"common": {
"add": "Dodaj",
"back": "Cofnij",
Expand Down Expand Up @@ -55,12 +67,6 @@
}
},
"navigation": {
"prevent_go_back_alert": {
"description": "Masz niezapisane zmiany. Jesteś pewny, że chcesz je porzucić i wyjść?",
"discard": "Porzuć",
"do_not_leave": "Nie wychodź",
"title": "Anulować zmiany?"
},
"screen_titles": {
"application_info": "ApplicationInfo",
"blog": "Blog",
Expand Down Expand Up @@ -166,15 +172,16 @@
"awesome": "Wspaniale 🎉"
},
"examples_screen": {
"header": "To jest przykładowy widok",
"go_to_application_info": "Idź do ApplicationInfo",
"go_to_colors": "Idź do Kolorów",
"go_to_components": "Idź do Komponentów",
"go_to_typography": "Idź do Typografii",
"go_to_home_stack_details": "Idź do HomeStackDetails",
"go_to_settings": "Idź do Ustawień",
"go_to_screen_test_form": "Idź do formularza testowego",
"go_to_screen_with_BEdata": "Idź do widoku z danymi z backend-u",
"go_to_screen_test_form": "Idź do formularza testowego"
"go_to_settings": "Idź do Ustawień",
"go_to_typography": "Idź do Typografii",
"go_to_user_session": "Idź do sesji użytkowania",
"header": "To jest przykładowy widok"
},
"forgot_password_screen": {
"back_to_login": "Wróć do logowania",
Expand Down
12 changes: 8 additions & 4 deletions src/navigation/tabNavigator/components/AppHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import { CompanyLogo } from '@baca/components'
import { isWeb } from '@baca/constants'
import { useTheme } from '@baca/hooks'
import { StyleSheet, View } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'

import { TabColorsStrings } from '../navigation-config'

export function AppHeader() {
const { colors } = useTheme()
const { top } = useSafeAreaInsets()

if (!isWeb) return null

const height = 60 + top

return (
<View style={[{ height, paddingTop: top }, jsStyles.appHeader]}>
<View
style={[
{ borderBottomColor: colors.border.secondary, height, paddingTop: top },
jsStyles.appHeader,
]}
>
<CompanyLogo height={60} width={150} />
</View>
)
Expand All @@ -22,7 +27,6 @@ export function AppHeader() {
const jsStyles = StyleSheet.create({
appHeader: {
alignItems: 'center',
borderBottomColor: TabColorsStrings.lightGray,
borderBottomWidth: 1,
display: 'flex',
flexDirection: 'row',
Expand Down
11 changes: 5 additions & 6 deletions src/navigation/tabNavigator/components/BottomBar.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { useColorScheme } from '@baca/contexts'
import { Icon } from '@baca/design-system'
import { useTheme } from '@baca/hooks'
import cssStyles from '@baca/styles'
import { Platform, StyleSheet, View } from 'react-native'
import { useSafeAreaInsets } from 'react-native-safe-area-context'

import { TabBarItemWrapper } from './TabBarItemWrapper'
import { bottomTabs, TabColors, TabColorsStrings } from '../navigation-config'
import { bottomTabs } from '../navigation-config'
import { cns } from '../utils'

export function BottomBar({ visible }: { visible: boolean }) {
const { colorScheme } = useColorScheme()
const { colors } = useTheme()
return (
<View
style={[
Expand All @@ -24,14 +24,14 @@ export function BottomBar({ visible }: { visible: boolean }) {
}),
]}
>
<View style={jsStyles.nav}>
<View style={[jsStyles.nav, { borderTopColor: colors.border.secondary }]}>
{bottomTabs.map((tab, i) => (
<TabBarItemWrapper key={i} name={tab.name} id={tab.id} params={tab.params}>
{({ focused, pressed, hovered }) => (
<Icon
name={focused ? tab.iconFocused : tab.icon}
size={40}
color={colorScheme === 'light' ? TabColors.tabIconDark : TabColors.tabIconLight}
color="nav.item.button.icon.fg"
style={[
jsStyles.tabIcon,
pressed && jsStyles.tabIconPressed,
Expand All @@ -54,7 +54,6 @@ export function BottomBar({ visible }: { visible: boolean }) {
const jsStyles = StyleSheet.create({
nav: {
alignItems: 'center',
borderTopColor: TabColorsStrings.lightGray,
borderTopWidth: 1,
flexDirection: 'row',
height: 49,
Expand Down
7 changes: 3 additions & 4 deletions src/navigation/tabNavigator/components/HeaderLogo.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { CompanyLogo } from '@baca/components'
import { useTheme } from '@baca/hooks'
import cssStyles from '@baca/styles'
import { Pressable } from '@bacons/react-views'
import { Link } from 'expo-router'
import { Platform, StyleSheet, View } from 'react-native'

import { useWidth } from '../hooks'
import { TabColorsStrings } from '../navigation-config'
import { cns } from '../utils'

export function HeaderLogo() {
const { colors } = useTheme()
const isLargeHorizontal = useWidth(1264)

return (
Expand All @@ -32,9 +33,7 @@ export function HeaderLogo() {
style={[
jsStyles.headerLogo,
{
backgroundColor: hovered
? TabColorsStrings.lightGray50
: TabColorsStrings.transparent,
backgroundColor: hovered ? colors.bg.tertiary : colors.Base.transparent,
},
]}
>
Expand Down
Loading