Skip to content

Commit

Permalink
fix: alert that reflect standards
Browse files Browse the repository at this point in the history
  • Loading branch information
Ata Shaikh committed Mar 20, 2024
1 parent 1a49018 commit 7beb846
Show file tree
Hide file tree
Showing 14 changed files with 290 additions and 36 deletions.
10 changes: 5 additions & 5 deletions apps/expo/app/(app)/(drawer)/(tabs)/(stack)/profile/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,19 @@ import { useProfileId } from 'app/hooks/user';

const Profile = () => {
const { id } = useProfileId();

const metaTitle = id ? `${id}'s Profile` : "Profile"
return (
<>
{Platform.OS === 'web' && (
<Head>
<title>{`${id}'s Profile`}</title>
<meta name="description" content={`${id}'s Profile`} />
<title>{metaTitle}</title>
<meta name="description" content={metaTitle} />
</Head>
)}
<Stack.Screen
options={{
title: `${id}'s Profile`,
name: `${id}'s Profile`,
title: metaTitle,
name: metaTitle,
}}
/>
<ProfileContainer id={id} />
Expand Down
12 changes: 5 additions & 7 deletions packages/app/components/pack/PackDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,15 @@ export function PackDetails() {
if (isLoading) return <Text>Loading...</Text>;

const refetchData = () => {
setRefreshing(true);
refetchUserPacks();
refetchSinglePack();
};

const onRefresh = useCallback(() => {
setRefreshing(true);
setTimeout(() => {
refetchData();
setRefreshing(false);
}, 2000);
}, []);
const onRefresh = () => {
refetchData();
setRefreshing(false);
};

return (
<View
Expand Down
6 changes: 3 additions & 3 deletions packages/app/components/pack_table/DeletePackItemModal.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { MaterialIcons } from '@expo/vector-icons';
import { useDeletePackItem } from 'app/hooks/packs/useDeletePackItem';
import { BaseModal } from '@packrat/ui';
import { BaseAlert } from '@packrat/ui';
import { useDeleteItem } from 'app/hooks/items';

interface DeletePackItemModalProps {
Expand Down Expand Up @@ -46,7 +46,7 @@ export const DeletePackItemModal = ({
];

return (
<BaseModal
<BaseAlert
isOpen={isOpen}
toggle={toggle}
hideIcon={hideIcon}
Expand All @@ -55,6 +55,6 @@ export const DeletePackItemModal = ({
footerButtons={footerButtons}
>
Are you sure you want to delete this item?
</BaseModal>
</BaseAlert>
);
};
10 changes: 4 additions & 6 deletions packages/app/screens/feed/Feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,11 @@ const Feed = ({ feedType = 'public' }: FeedProps) => {
);
const user = useAuthUser();

const onRefresh = React.useCallback(() => {
const onRefresh = () => {
setRefreshing(true);
setTimeout(() => {
refetch();
setRefreshing(false);
}, 2000);
}, []);
refetch();
setRefreshing(false);
};

/**
* Renders the data for the feed based on the feed type and search query.
Expand Down
12 changes: 5 additions & 7 deletions packages/app/screens/items/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@ export default function Items() {
const styles = useCustomStyles(loadStyles);
const [refreshing, setRefreshing] = React.useState(false);

const onRefresh = React.useCallback(() => {
const onRefresh = () => {
setRefreshing(true);
setTimeout(() => {
refetch();
setRefreshing(false);
}, 2000);
}, []);
refetch();
setRefreshing(false);
};

const { enableDarkMode, enableLightMode, isDark, isLight, currentTheme } =
useTheme();
Expand All @@ -45,7 +43,7 @@ export default function Items() {
<BaseModal
title="Add a global Item"
trigger="Add Item"
// triggerComponent={<ModalTriggerButton />}
// triggerComponent={<ModalTriggerButton />}
>
<AddItemGlobal />
</BaseModal>
Expand Down
2 changes: 1 addition & 1 deletion packages/app/screens/trip/TripDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function TripDetails() {
// }, [dispatch, tripId]);

if (isLoading) return <RText>Loading...</RText>;

console.log("isError", isError)
if (isError) return <RText>There was an error</RText>;

return (
Expand Down
10 changes: 4 additions & 6 deletions packages/app/screens/user/ProfileContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,11 @@ export default function ProfileContainer({ id = null }) {
refetch: refetchProfile,
} = useProfile(id);

const onRefresh = React.useCallback(() => {
const onRefresh = () => {
setRefreshing(true);
setTimeout(() => {
refetchProfile();
setRefreshing(false);
}, 2000);
}, []);
refetchProfile();
setRefreshing(false);
};

return (
<View>
Expand Down
64 changes: 64 additions & 0 deletions packages/ui/src/alert/AlertDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useState } from 'react';

import { Adapt, Button, AlertDialog, Sheet } from 'tamagui';

export const Alert = ({ title, description, trigger, children }) => {
const [open, setOpen] = useState(false);

return (
<AlertDialog
modal
onOpenChange={(open) => {
setOpen(open);
}}
>
<AlertDialog.Trigger asChild>
<Button>{trigger}</Button>
</AlertDialog.Trigger>
<Adapt when="sm" platform="touch">
<Sheet zIndex={200000} modal dismissOnSnapToBottom>
<Sheet.Frame padding="$4" gap>
<Adapt.Contents />
</Sheet.Frame>

<Sheet.Overlay
animation="lazy"
enterStyle={{ opacity: 0 }}
exitStyle={{ opacity: 0 }}
/>
</Sheet>
</Adapt>
<AlertDialog.Portal>
<AlertDialog.Overlay
key="overlay"
animation="quick"
opacity={0.5}
enterStyle={{ opacity: 0 }}
exitStyle={{ opacity: 0 }}
/>
<AlertDialog.Content
bordered
elevate
key="content"
animateOnly={['transform', 'opacity']}
animation={[
'quick',
{
opacity: {
overshootClamping: true,
},
},
]}
enterStyle={{ x: 0, y: -20, opacity: 0, scale: 0.9 }}
exitStyle={{ x: 0, y: 10, opacity: 0, scale: 0.95 }}
gap
>
<AlertDialog.Title>{title}</AlertDialog.Title>

<AlertDialog.Description>{description}</AlertDialog.Description>
{children}
</AlertDialog.Content>
</AlertDialog.Portal>
</AlertDialog>
);
};
168 changes: 168 additions & 0 deletions packages/ui/src/alert/BaseAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import React, { useEffect, useMemo, useState } from 'react';
import { Button, AlertDialog } from 'tamagui';
import { X } from '@tamagui/lucide-icons';
import RButton from '@packrat/ui/src/RButton';
import RStack from '@packrat/ui/src/RStack';
import { useAlert, AlertProvider } from './provider';

export interface BaseAlertProps {
id?: string;
title: string;
trigger?: string;
children: React.ReactNode;
buttonColor?: string;
footerButtons?: any[];
triggerComponent?: React.DetailedReactHTMLElement<any, HTMLElement>;
footerComponent: React.DetailedReactHTMLElement<any, HTMLElement>;
hideIcon?: boolean;
isOpen?: boolean | undefined;
toggle?: any;
}

export const BaseAlert = ({
triggerComponent,
title,
trigger,
footerButtons,
footerComponent,
children,
hideIcon = false,
isOpen = undefined,
toggle,
}: BaseAlertProps) => {
const [isAlertOpen, setIsAlertOpen] = useState(false);

useEffect(() => {
if(isOpen !== undefined) {
setIsAlertOpen(isOpen)
}
}, [isOpen])

const triggerElement = useMemo(() => {
return triggerComponent ? (
<RButton
onPress={() => setIsAlertOpen(true)}
style={{ backgroundColor: 'transparent' }}
backgroundColor={'transparent'}
>
{React.cloneElement(triggerComponent, { setIsAlertOpen })}
</RButton>
) : (
<RButton
top={5}
alignSelf={'center'}
onPress={() => setIsAlertOpen(true)}
>
{trigger}
</RButton>
);
}, [triggerComponent]);

const memoFooterButtons = useMemo(() => {
if (!Array.isArray(footerButtons)) return null;

return footerButtons.map(({ color, label, onClick, ...button }, index) => (
<RButton
key={index}
onPress={withAlertCloseHandler(onClick, () => {
setIsAlertOpen(false)
if(toggle) {
toggle()
}
})}
backgroundColor={color}
disabled={button.disabled}
color="white"
{...button}
>
{label}
</RButton>
));
}, [footerButtons]);

const footerElement = useMemo(() => {
return (
footerComponent && React.cloneElement(footerComponent, { setIsAlertOpen })
);
}, [footerComponent]);

return (
<AlertDialog
modal
open={isAlertOpen}
onOpenChange={(open) => {
setIsAlertOpen(open);
}}
>
{!hideIcon && <AlertDialog.Trigger asChild>{triggerElement}</AlertDialog.Trigger>}
<AlertDialog.Portal>
<AlertDialog.Overlay
key="overlay"
animation="quick"
opacity={0.5}
enterStyle={{ opacity: 0 }}
exitStyle={{ opacity: 0 }}
minWidth={400}
/>

<AlertDialog.Content
bordered
elevate
key="content"
animateOnly={['transform', 'opacity']}
animation={[
'quick',
{
opacity: {
overshootClamping: true,
},
},
]}
enterStyle={{ x: 0, y: -20, opacity: 0, scale: 0.9 }}
exitStyle={{ x: 0, y: 10, opacity: 0, scale: 0.95 }}
gap="$4"
>
<AlertDialog.Title>{title}</AlertDialog.Title>
<AlertDialog.Description>
<AlertProvider
isAlertOpen={isAlertOpen}
setIsAlertOpen={setIsAlertOpen}
>
{children}
</AlertProvider>
</AlertDialog.Description>

<RStack
style={{ alignSelf: 'flex-end', flexDirection: 'row' }}
gap="$4"
>
{memoFooterButtons}
</RStack>
{footerElement}
<AlertDialog.Cancel asChild>
<Button
onPress={() => {
setIsAlertOpen(false);
if(toggle) {
toggle()
}
}}
position="absolute"
backgroundColor="transparent"
top="$3"
right="$3"
size="$2"
circular
icon={X}
/>
</AlertDialog.Cancel>
</AlertDialog.Content>
</AlertDialog.Portal>
</AlertDialog>
);
};

const withAlertCloseHandler =
(fn, closeHandler) =>
(...args) =>
fn?.(...args, closeHandler.bind(null, false));
2 changes: 2 additions & 0 deletions packages/ui/src/alert/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { BaseAlert } from './BaseAlert';
export { useAlert, AlertProvider } from './provider';
Loading

0 comments on commit 7beb846

Please sign in to comment.