Skip to content

Commit

Permalink
Merge pull request #1256 from andrew-bierman/enhance-profile-cards
Browse files Browse the repository at this point in the history
change cards in profile page
  • Loading branch information
taronaleksanian authored Sep 26, 2024
2 parents 25d641d + 83c0a27 commit c7cde00
Show file tree
Hide file tree
Showing 13 changed files with 368 additions and 266 deletions.
2 changes: 1 addition & 1 deletion packages/app/modules/feed/components/FeedSearchFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export const FeedSearchFilter = ({
}, []);

useEffect(() => {
if (!sortOptions.includes(queryString)) {
if (!sortOptions.includes(queryString) && handleSortChange) {
handleSortChange(sortOptions[0]);
}
}, [sortOptions, queryString]);
Expand Down
1 change: 1 addition & 0 deletions packages/app/modules/feed/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export type FeedItem = PackFeedItem | TripFeedItem;
export interface FeedCardProps<Details> {
id: string;
title: string;
is_public: boolean;
cardType: CardType;
createdAt: string;
details: Details;
Expand Down
285 changes: 44 additions & 241 deletions packages/app/modules/user/components/UserDataCard.tsx
Original file line number Diff line number Diff line change
@@ -1,259 +1,62 @@
import React from 'react';
import { AntDesign } from '@expo/vector-icons';
import { formatDistanceToNow } from 'date-fns';
import { View, TouchableOpacity } from 'react-native';
import {
RH2,
RText as OriginalRText,
RStack,
RSwitch,
RLink,
RSkeleton,
} from '@packrat/ui';
import { truncateString } from 'app/utils/truncateString';
import { useEditPack } from 'app/modules/pack';
import { Platform } from 'react-native';
import { useEditTrips } from 'app/hooks/trips';
import React, { type FC } from 'react';
import { type UserData, type UserDataResource } from './model';
import { UserDataPackCardConverter, UserDataTripCardConverter } from './utils';
import { type CardType } from '@packrat/ui';
import { useAddFavorite } from 'app/modules/feed';
import useTheme from 'app/hooks/useTheme';
import { useAuthUser } from 'app/modules/auth';
import { UserTripCard } from './UserTripCard';
import { UserPackCard } from './UserPackCard';
import { View, Text } from 'react-native';

const convertersByType = {
pack: UserDataPackCardConverter,
trip: UserDataTripCardConverter,
};

const RText: any = OriginalRText;
const cardComponentsByType = {
pack: UserPackCard,
trip: UserTripCard,
};

interface UserDataCardProps {
type: 'pack' | 'trip';
destination: string;
id: string;
name: string;
total_weight?: number;
is_public: boolean;
currentUserId?: number;
favorites_count: number;
createdAt: string;
index: number;
differentUser: boolean;
activeUserId?: string;
isFavorite: boolean;
feedType: UserDataResource;
cardType: CardType;
item: UserData;
}

export const UserDataCard = ({
type, // "pack" or "trip"
destination,
id,
name,
total_weight,
is_public,
currentUserId,
favorites_count,
createdAt,
index,
differentUser,
activeUserId,
isFavorite,
}: UserDataCardProps) => {
const { editPack: changePackStatus, isLoading: isPackLoading } =
useEditPack();
const { editTrips: changeTripStatus, isLoading: isTripLoading } =
useEditTrips();
export const UserDataCard: FC<UserDataCardProps> = ({
item,
cardType,
feedType,
}) => {
const { addFavorite } = useAddFavorite();
const { currentTheme } = useTheme();
const user = useAuthUser();

const handleChangeStatus = (index) => {
if (type === 'pack') {
return changePackStatus(
{ id, is_public: !is_public, name },
{
onSuccess: (utils) => {
utils.getUserFavorites.invalidate();
},
},
);
}

if (type === 'trip') {
changeTripStatus(
{ id, is_public: !is_public },
{
onSuccess: (utils) => {
utils.getUserFavorites.invalidate();
},
},
);
}
};
const cardProps =
typeof convertersByType[feedType] === 'function'
? convertersByType[feedType](item, user?.id)
: null;

const handleAddToFavorite = () => {
if (!user) return;
const data = {
packId: id,
userId: currentUserId,
packId: item.id,
userId: user.id,
};

addFavorite(data, String(activeUserId));
addFavorite(data);
};

const truncatedName = truncateString(name, 25);
const truncatedDestination = truncateString(destination, 25);
if (!cardProps) {
return null;
}

return (
<View
style={{
alignItems: 'center',
justifyContent: 'center',
marginHorizontal: 8,
marginVertical: 4,
borderRadius: 8,
}}
>
<View
style={
{
minHeight: 150,
minWidth: Platform.OS === 'web' ? 250 : 225,
border: '1px solid gray',
borderLeft: `10px solid ${is_public ? 'green' : 'red'}`,
borderRadius: 8,
overflow: 'hidden',
backgroundColor: '#EBEBEB',
} as any
}
>
<RStack style={{ padding: 16, gap: 16 }}>
<RStack style={{ gap: 8 }}>
<RH2>
<View
style={
{
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
width: '100%',
gap: 10,
fontSize: 16,
fontWeight: 'bold',
} as any
}
>
<RText style={{ fontSize: 16, color: 'black' }}>
{truncatedName}
</RText>
{(isPackLoading && type === 'pack') ||
(isTripLoading && type === 'trip') ? (
<RSkeleton
style={{
height: 20,
width: 36,
}}
/>
) : (
<>
{!differentUser && (
<RSwitch
checked={is_public}
onCheckedChange={() => {
handleChangeStatus(index);
}}
size="$1.5"
/>
)}
</>
)}
</View>
</RH2>
{type === 'pack' ? (
<RText
style={{
fontSize: 12,
color: 'mediumpurple',
// marginLeft: '-0.5px',
// marginTop: '-3px',
}}
>
Total Weight: {total_weight?.toFixed(2)}g
</RText>
) : (
<RText
style={{
fontSize: 12,
color: 'mediumpurple',
// marginLeft: '-0.5px',
// marginTop: '-3px',
}}
>
Destination: {truncatedDestination}
</RText>
)}
</RStack>
const CardComponent = cardComponentsByType[feedType];

<RStack
style={{
flexDirection: 'row',
justifyContent: 'space-between',
}}
>
<RText
style={{
color: 'gray',
fontSize: 12,
fontWeight: '400',
}}
>
{formatDistanceToNow(
new Date(
!Number.isNaN(new Date(createdAt).getTime())
? createdAt
: new Date(),
).getTime(),
{
addSuffix: true,
},
) ?? 0}
</RText>
<View
style={{
justifyContent: 'center',
alignItems: 'center',
gap: 10,
}}
>
<RStack
color="gray"
gap="$2"
flexDirection="row"
fontWeight={400}
>
<TouchableOpacity
onPress={handleAddToFavorite}
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
}}
>
<AntDesign
name="heart"
size={16}
color={
isFavorite ? 'red' : currentTheme.colors.cardIconColor
}
/>
</TouchableOpacity>
<View>
<RText color={currentTheme.colors.text}>
{favorites_count}
</RText>
</View>
</RStack>
</View>
</RStack>
</RStack>
<View style={{ alignItems: 'center', justifyContent: 'center' }}>
<RLink href={`/${type}/${id}`} style={{ textDecoration: 'none' }}>
<RText color="gray" fontWeight="bold">
View Details
</RText>
</RLink>
</View>
</View>
</View>
return (
<CardComponent
{...cardProps}
cardType={cardType}
toggleFavorite={handleAddToFavorite}
/>
);
};
Loading

0 comments on commit c7cde00

Please sign in to comment.