Skip to content

Commit e5aed83

Browse files
committed
feat(errors): prefer error icon instead of chip
1 parent 6b7eec5 commit e5aed83

File tree

15 files changed

+178
-143
lines changed

15 files changed

+178
-143
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [unreleased]
99

10+
### Changed
11+
12+
- Prefer error icon instead of chip on most screens.
13+
1014
### Fixed
1115

1216
- Refresh last fetch date on attendance screen when focused.

src/app/(public)/(settings)/account.tsx

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import { View } from 'react-native';
88
import tw, { useDeviceContext } from 'twrnc';
99
import AppText from '@/components/AppText';
1010
import AppTouchable from '@/components/AppTouchable';
11+
import ErrorBadge from '@/components/ErrorBagde';
1112
import ErrorChip from '@/components/ErrorChip';
13+
import SectionTitle from '@/components/Layout/SectionTitle';
1214
import ServiceLayout from '@/components/Layout/ServiceLayout';
1315
import ServiceRow from '@/components/Layout/ServiceRow';
1416
import ZoomableImage from '@/components/ZoomableImage';
@@ -69,26 +71,17 @@ const Advanced = () => {
6971
</View>
7072
</View>
7173

72-
<View style={tw`flex flex-row gap-2 min-h-6 mt-8 px-6`}>
73-
<AppText style={tw`text-sm font-normal uppercase text-slate-500`}>
74-
{t('account.profile.label')}
75-
</AppText>
76-
74+
<SectionTitle style={tw`mx-6 mt-8`} title={t('account.profile.title')}>
75+
{profileError && !isSilentError(profileError) ? (
76+
<ErrorBadge error={profileError} title={t('account.profile.onFetch.fail')} />
77+
) : null}
7778
<Link asChild href={`${WORDPRESS_BASE_URL}/mon-compte/modifier-compte/`}>
7879
<AppText
7980
style={tw`ml-auto text-base font-normal leading-5 text-right text-amber-500 min-w-5`}>
8081
{t('actions.edit')}
8182
</AppText>
8283
</Link>
83-
</View>
84-
85-
{profileError && !isSilentError(profileError) ? (
86-
<ErrorChip
87-
error={profileError}
88-
label={t('account.profile.onFetch.fail')}
89-
style={tw`mx-6 mt-2 self-start`}
90-
/>
91-
) : null}
84+
</SectionTitle>
9285

9386
<ServiceRow
9487
withBottomDivider

src/app/(public)/(settings)/settings.tsx

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
2424
import tw, { useDeviceContext } from 'twrnc';
2525
import AppBlurView from '@/components/AppBlurView';
2626
import AppText from '@/components/AppText';
27+
import ErrorBadge from '@/components/ErrorBagde';
2728
import ErrorChip from '@/components/ErrorChip';
2829
import ProfilePicture from '@/components/Home/ProfilePicture';
30+
import SectionTitle from '@/components/Layout/SectionTitle';
2931
import ServiceRow from '@/components/Layout/ServiceRow';
3032
import AppFooter from '@/components/Settings/AppFooter';
3133
import PresenceGraph from '@/components/Settings/PresenceGraph';
@@ -293,10 +295,16 @@ const Settings = ({ style, from }: { from?: string; style?: StyleProp<ViewStyle>
293295
paddingRight: insets.right,
294296
},
295297
]}>
296-
<View style={tw`flex flex-row gap-2 items-center min-h-6 mx-6`}>
297-
<AppText style={tw`text-sm font-normal uppercase text-slate-500`}>
298-
{t('settings.profile.presence.title')}
299-
</AppText>
298+
<SectionTitle style={tw`mx-6`} title={t('settings.profile.presence.title')}>
299+
{activityError && !isSilentError(activityError) ? (
300+
<ErrorBadge
301+
error={activityError}
302+
title={t('settings.profile.presence.onFetch.fail')}
303+
/>
304+
) : profileError && !isSilentError(profileError) ? (
305+
<ErrorBadge error={profileError} title={t('home.profile.onFetch.fail')} />
306+
) : null}
307+
300308
{profile?.balance && profile.balance < 0 ? (
301309
<Animated.View
302310
entering={FadeInRight.duration(600).delay(500)}
@@ -314,21 +322,7 @@ const Settings = ({ style, from }: { from?: string; style?: StyleProp<ViewStyle>
314322
</AppText>
315323
</Animated.View>
316324
) : null}
317-
</View>
318-
319-
{activityError && !isSilentError(activityError) ? (
320-
<ErrorChip
321-
error={activityError}
322-
label={t('settings.profile.presence.onFetch.fail')}
323-
style={tw`mx-6 mt-2 self-start`}
324-
/>
325-
) : profileError && !isSilentError(profileError) ? (
326-
<ErrorChip
327-
error={profileError}
328-
label={t('home.profile.onFetch.fail')}
329-
style={tw`mx-6 mt-2 self-start`}
330-
/>
331-
) : null}
325+
</SectionTitle>
332326

333327
<PresenceGraph
334328
activity={activity}
@@ -342,9 +336,7 @@ const Settings = ({ style, from }: { from?: string; style?: StyleProp<ViewStyle>
342336
onDateSelect={onDateSelect}
343337
/>
344338

345-
<AppText style={tw`text-sm font-normal uppercase text-slate-500 mx-6 mt-6`}>
346-
{t('settings.general.title')}
347-
</AppText>
339+
<SectionTitle style={tw`mx-6 mt-6`} title={t('settings.general.title')} />
348340

349341
<Link asChild href="/advanced/">
350342
<ServiceRow
@@ -404,9 +396,7 @@ const Settings = ({ style, from }: { from?: string; style?: StyleProp<ViewStyle>
404396
</ServiceRow>
405397
<ThemePicker style={tw`px-3 mx-3`} onPress={selectTheme} />
406398

407-
<AppText style={tw`text-sm font-normal uppercase text-slate-500 mx-6 mt-6`}>
408-
{t('settings.support.title')}
409-
</AppText>
399+
<SectionTitle style={tw`mx-6 mt-6`} title={t('settings.support.title')} />
410400
{authStore.user && (
411401
<Link asChild href={`${WORDPRESS_BASE_URL}/la-boutique/`}>
412402
<ServiceRow

src/app/(public)/attendance.tsx

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import EmptyOfficeAnimation from '@/components/Animations/EmptyOfficeAnimation';
1212
import AppText from '@/components/AppText';
1313
import MemberBottomSheet from '@/components/Attendance/MemberBottomSheet';
1414
import MemberCard from '@/components/Attendance/MemberCard';
15-
import ErrorChip from '@/components/ErrorChip';
15+
import ErrorBadge from '@/components/ErrorBagde';
16+
import SectionTitle from '@/components/Layout/SectionTitle';
1617
import ServiceLayout from '@/components/Layout/ServiceLayout';
1718
import LoadingSkeleton from '@/components/LoadingSkeleton';
1819
import useAppState from '@/helpers/app-state';
@@ -104,10 +105,7 @@ const Attendance = () => {
104105
description={t('attendance.description')}
105106
title={t('attendance.title', { count: currentMembers?.length })}
106107
onRefresh={refetchCurrentMembers}>
107-
<View style={tw`flex flex-col items-start gap-2 min-h-6 px-6`}>
108-
{currentMembersError && !isSilentError(currentMembersError) ? (
109-
<ErrorChip error={currentMembersError} label={t('attendance.onFetch.fail')} />
110-
) : null}
108+
<View style={tw`flex flex-row items-center gap-2 min-h-6 px-6`}>
111109
{!isNil(durationSinceLastFetch) ? (
112110
<AppText
113111
entering={FadeInLeft.duration(300)}
@@ -121,6 +119,9 @@ const Attendance = () => {
121119
)}
122120
</AppText>
123121
) : null}
122+
{currentMembersError && !isSilentError(currentMembersError) ? (
123+
<ErrorBadge error={currentMembersError} title={t('attendance.onFetch.fail')} />
124+
) : null}
124125
</View>
125126

126127
<View style={tw`flex flex-col gap-12`}>
@@ -142,19 +143,14 @@ const Attendance = () => {
142143
) : groupedMembersByLocation.length ? (
143144
groupedMembersByLocation.map((group) => (
144145
<View key={group.location} style={tw`flex flex-col gap-2 px-4`}>
145-
<Animated.View
146+
<SectionTitle
147+
count={group.members.length}
146148
entering={FadeInLeft.duration(500)}
147149
exiting={FadeOutLeft.duration(500)}
148-
style={tw`flex flex-row items-center w-full gap-1`}>
149-
<AppText style={tw`text-sm font-normal uppercase text-slate-500 px-2`}>
150-
{t(`onPremise.location.${group.location || 'unknown'}`)}
151-
</AppText>
152-
<View style={tw`bg-gray-400/25 dark:bg-gray-700/50 py-1 px-2 rounded-full`}>
153-
<AppText style={tw`text-xs text-slate-900 dark:text-gray-200 font-medium`}>
154-
{group.members.length}
155-
</AppText>
156-
</View>
157-
</Animated.View>
150+
style={tw`px-2`}
151+
title={t(`onPremise.location.${group.location || 'unknown'}`)}
152+
/>
153+
158154
<View style={tw`flex flex-row flex-wrap gap-2 w-full`}>
159155
{group.members.map((member, index) => (
160156
<Animated.View

src/app/(public)/home.tsx

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@ import Animated, {
1616
FadeOutDown,
1717
StretchInY,
1818
} from 'react-native-reanimated';
19-
import { toast } from 'sonner-native';
20-
import tw, { useDeviceContext } from 'twrnc';
2119
import AppText from '@/components/AppText';
2220
import AppTouchable from '@/components/AppTouchable';
23-
import ErrorChip from '@/components/ErrorChip';
21+
import ErrorBadge from '@/components/ErrorBagde';
2422
import { type PeriodType } from '@/components/Events/PeriodBottomSheet';
2523
import AppointmentCard from '@/components/Home/AppointmentCard';
2624
import AttendanceCount from '@/components/Home/AttendanceCount';
@@ -42,6 +40,7 @@ import SubscriptionBottomSheet from '@/components/Home/SubscriptionBottomSheet';
4240
import SubscriptionCard from '@/components/Home/SubscriptionCard';
4341
import UnauthenticatedState from '@/components/Home/UnauthenticatedState';
4442
import UnlockGateCard from '@/components/Home/UnlockGateCard';
43+
import SectionTitle from '@/components/Layout/SectionTitle';
4544
import { useAppContact } from '@/context/contact';
4645
import useAppState from '@/helpers/app-state';
4746
import { isSilentError } from '@/helpers/error';
@@ -57,6 +56,8 @@ import {
5756
import useAuthStore from '@/stores/auth';
5857
import useSettingsStore from '@/stores/settings';
5958
import useToastStore from '@/stores/toast';
59+
import { toast } from 'sonner-native';
60+
import tw, { useDeviceContext } from 'twrnc';
6061

6162
const MAX_WIDTH = 672; // tw`max-w-2xl`
6263

@@ -333,19 +334,14 @@ export default function HomeScreen() {
333334
isWide && tw`mx-auto w-full max-w-2xl`,
334335
]}>
335336
<AttendanceCount
337+
error={
338+
currentMembersError && !isSilentError(currentMembersError) ? currentMembersError : null
339+
}
336340
loading={isLoadingCurrentMembers}
337341
members={currentMembers}
338342
style={tw`mt-4`}
339343
total={40}
340344
/>
341-
342-
{currentMembersError && !isSilentError(currentMembersError) ? (
343-
<ErrorChip
344-
error={currentMembersError}
345-
label={t('home.people.onFetch.fail')}
346-
style={tw`self-start`}
347-
/>
348-
) : null}
349345
</Animated.View>
350346

351347
{authStore.user?.onboarding && (
@@ -357,19 +353,13 @@ export default function HomeScreen() {
357353
)}
358354

359355
<Animated.View entering={FadeInLeft.duration(750).delay(400)} style={tw`flex self-stretch`}>
360-
<View
361-
style={[
362-
tw`flex flex-col items-start gap-2 mt-6 px-6`,
363-
isWide && tw`mx-auto w-full max-w-2xl`,
364-
]}>
365-
<AppText style={tw`text-sm font-normal uppercase text-slate-500`}>
366-
{t('home.profile.label')}
367-
</AppText>
368-
356+
<SectionTitle
357+
style={[tw`w-full mt-6 px-6`, isWide && tw`mx-auto max-w-2xl`]}
358+
title={t('home.profile.label')}>
369359
{profileError && !isSilentError(profileError) ? (
370-
<ErrorChip error={profileError} label={t('home.profile.onFetch.fail')} />
360+
<ErrorBadge error={profileError} title={t('home.profile.onFetch.fail')} />
371361
) : null}
372-
</View>
362+
</SectionTitle>
373363

374364
<ScrollView
375365
contentContainerStyle={[
@@ -435,36 +425,22 @@ export default function HomeScreen() {
435425
</ScrollView>
436426
</Animated.View>
437427

438-
<Animated.View
428+
<SectionTitle
429+
count={nextCalendarEvents.length > 2 ? nextCalendarEvents.length : null}
439430
entering={FadeInRight.duration(750).delay(600)}
440-
style={[
441-
tw`flex flex-row items-center w-full gap-2 mt-12 px-6`,
442-
isWide && tw`mx-auto w-full max-w-2xl`,
443-
]}>
444-
<AppText style={tw`text-sm font-normal uppercase text-slate-500`}>
445-
{t('home.calendar.label')}
446-
</AppText>
447-
{nextCalendarEvents.length > 2 && (
448-
<View style={tw`bg-gray-400/25 dark:bg-gray-700/50 py-1 px-2 rounded-full`}>
449-
<AppText style={tw`text-xs text-slate-900 dark:text-gray-200 font-medium`}>
450-
{nextCalendarEvents.length}
451-
</AppText>
452-
</View>
453-
)}
431+
style={[tw`w-full mt-6 px-6`, isWide && tw`mx-auto max-w-2xl`]}
432+
title={t('home.calendar.label')}>
433+
{calendarEventsError && !isSilentError(calendarEventsError) ? (
434+
<ErrorBadge error={calendarEventsError} title={t('home.calendar.onFetch.fail')} />
435+
) : null}
436+
454437
<Link asChild href="/events">
455438
<AppText
456439
style={tw`ml-auto text-base font-normal leading-5 text-right text-amber-500 min-w-5`}>
457440
{t('home.calendar.browse')}
458441
</AppText>
459442
</Link>
460-
</Animated.View>
461-
462-
{calendarEventsError && !isSilentError(calendarEventsError) ? (
463-
<View
464-
style={[tw`flex flex-col items-start mt-2 px-6`, isWide && tw`mx-auto w-full max-w-2xl`]}>
465-
<ErrorChip error={calendarEventsError} label={t('home.calendar.onFetch.fail')} />
466-
</View>
467-
) : null}
443+
</SectionTitle>
468444

469445
<Animated.View entering={FadeInRight.duration(750).delay(600)} style={tw`flex w-full`}>
470446
<ScrollView
@@ -524,11 +500,11 @@ export default function HomeScreen() {
524500
tw`flex flex-col w-full px-4 gap-4 mt-9 mb-3`,
525501
isWide && tw`mx-auto w-full max-w-2xl`,
526502
]}>
527-
<AppText
503+
<SectionTitle
528504
entering={FadeInUp.duration(500).delay(600)}
529-
style={tw`mx-2 text-sm font-normal uppercase text-slate-500`}>
530-
{t('home.services.label')}
531-
</AppText>
505+
style={tw`mx-2`}
506+
title={t('home.services.label')}
507+
/>
532508

533509
<View style={tw`flex flex-row items-stretch gap-4 min-h-40`}>
534510
<Animated.View

src/app/(public)/on-premise.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ import ServiceLayout from '@/components/Layout/ServiceLayout';
1818
import CarbonDioxideBottomSheet from '@/components/OnPremise/CarbonDioxideBottomSheet';
1919
import DeckKeyBoxBottomSheet from '@/components/OnPremise/DeckKeyBoxBottomSheet';
2020
import FlexDeskBottomSheet from '@/components/OnPremise/FlexDeskBottomSheet';
21-
import PoulaillerKeyBoxBottomSheet from '@/components/OnPremise/PoulaillerKeyBoxBottomSheet';
2221
import PhoneBoothBottomSheet from '@/components/OnPremise/PhoneBoothBottomSheet';
22+
import PoulaillerKeyBoxBottomSheet from '@/components/OnPremise/PoulaillerKeyBoxBottomSheet';
2323
import PoulaillerPlan from '@/components/OnPremise/PoulaillerPlan';
2424
import PtiPoulaillerClimateBottomSheet from '@/components/OnPremise/PtiPoulaillerClimateBottomSheet';
25+
import PtiPoulaillerKeyBoxBottomSheet from '@/components/OnPremise/PtiPoulaillerKeyBoxBottomSheet';
2526
import PtiPoulaillerPlan from '@/components/OnPremise/PtiPoulaillerPlan';
2627
import UnlockDeckDoorBottomSheet from '@/components/OnPremise/UnlockDeckDoorBottomSheet';
2728
import { SelectableChip } from '@/components/SelectableChip';
2829
import { isSilentError } from '@/helpers/error';
2930
import useAppScreen from '@/helpers/screen';
3031
import { getOnPremiseState, OnPremiseFlexDesk } from '@/services/api/services';
31-
import PtiPoulaillerKeyBoxBottomSheet from '@/components/OnPremise/PtiPoulaillerKeyBoxBottomSheet';
3232

3333
const SUPPORTED_LOCATIONS = ['poulailler', 'pti-poulailler'];
3434
type SupportedLocation = (typeof SUPPORTED_LOCATIONS)[number];
@@ -99,7 +99,7 @@ const OnPremise = () => {
9999

100100
<View style={tw`mb-4`}>
101101
<ScrollView
102-
contentContainerStyle={tw`flex flex-row items-center gap-4 px-4`}
102+
contentContainerStyle={tw`flex flex-row items-center gap-4 px-6`}
103103
horizontal={true}
104104
scrollEventThrottle={16}
105105
showsHorizontalScrollIndicator={false}
@@ -138,8 +138,8 @@ const OnPremise = () => {
138138
onCarbonDioxideSelected={() => setCarbonDioxideSelected(true)}
139139
onDeckDoorSelected={() => setDeckDoorSelected(true)}
140140
onDeckKeyBoxSelected={() => setDeckKeyBoxSelected(true)}
141-
onPoulaillerKeyBoxSelected={() => setPoulaillerKeyBoxSelected(true)}
142141
onPhoneBoothSelected={() => setPhoneBoothSelected(true)}
142+
onPoulaillerKeyBoxSelected={() => setPoulaillerKeyBoxSelected(true)}
143143
onPremiseState={onPremiseState}
144144
/>
145145
</Animated.View>
@@ -154,8 +154,8 @@ const OnPremise = () => {
154154
loading={isFetchingOnPremiseState}
155155
onClimateSelected={() => setPtiPoulaillerClimateSelected(true)}
156156
onFlexDeskSelected={(d) => setSelectedFlexDesk(d ?? null)}
157-
onPtiPoulaillerKeyBoxSelected={() => setPtiPoulaillerKeyBoxSelected(true)}
158157
onPremiseState={onPremiseState}
158+
onPtiPoulaillerKeyBoxSelected={() => setPtiPoulaillerKeyBoxSelected(true)}
159159
/>
160160
</Animated.View>
161161
)}

src/components/Attendance/MemberCard.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
type StyleProp,
1010
type ViewStyle,
1111
} from 'react-native';
12-
import Animated, { BounceIn, BounceOut, FadeInLeft, FadeOutDown } from 'react-native-reanimated';
12+
import Animated, { BounceOut, FadeInLeft, FadeOutDown } from 'react-native-reanimated';
1313
import tw from 'twrnc';
1414
import AppText from '@/components/AppText';
1515
import ProfilePicture from '@/components/Home/ProfilePicture';
@@ -52,7 +52,6 @@ const MemberCard: ForwardRefRenderFunction<typeof TouchableHighlight, MemberCard
5252
url={member.picture}>
5353
{member.attending && (
5454
<Animated.View
55-
entering={BounceIn.duration(1000).delay(300)}
5655
exiting={BounceOut.duration(1000)}
5756
style={tw`z-10 h-5 w-5 bg-gray-50 dark:bg-zinc-900 rounded-full absolute flex items-center justify-center -bottom-0.5 -right-0.5`}>
5857
<View style={tw`h-3 w-3 bg-emerald-600 dark:bg-emerald-700 rounded-full`} />

0 commit comments

Comments
 (0)