From 44aee1b513a0cf6dc74717612fbcfe213924a94f Mon Sep 17 00:00:00 2001 From: Tadjaur Date: Wed, 30 Oct 2024 14:08:40 +0100 Subject: [PATCH 1/2] Fix items similar product --- packages/app/components/footer/Footer.tsx | 255 +++++++++++------- .../feed/components/FeedCard/FeedCard.tsx | 4 +- .../modules/feed/components/FeedCard/utils.ts | 7 + packages/app/modules/feed/model.ts | 3 +- .../feed/widgets/FeedPreview/FeedPreview.tsx | 15 +- .../app/modules/item/components/ItemCard.tsx | 5 +- packages/app/modules/item/components/index.ts | 1 + packages/app/modules/item/index.ts | 1 + server/wrangler.toml.example | 1 + 9 files changed, 188 insertions(+), 104 deletions(-) diff --git a/packages/app/components/footer/Footer.tsx b/packages/app/components/footer/Footer.tsx index 59081736d..2e2132391 100644 --- a/packages/app/components/footer/Footer.tsx +++ b/packages/app/components/footer/Footer.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; import { theme } from '../../theme'; import useTheme from '../../hooks/useTheme'; @@ -24,7 +25,14 @@ export default function Footer() { - + - PackRat + + PackRat + - - {firstFootorLinksGroup.map((item) => { - return ( - - {item.label} - - ); - })} - {secondFootorLinksGroup.map((item) => { - return ( - - {item.label} - - ); - })} + + + {firstFootorLinksGroup.map((item) => { + return ( + + {item.label} + + ); + })} + + + {secondFootorLinksGroup.map((item) => { + return ( + + {item.label} + + ); + })} + - - - + + + Facebook - - + + Instagram - - + + X - - + + { - { - return StyleSheet.create({ - mainContainer: { - width: '100%', - flexDirection: 'column', - paddingTop: 80, - paddingBottom: 40, - alignSelf: 'center', - alignItems: 'center', - justifyContent: 'space-evenly', - position: 'relative', - bottom: 0, - }, - mainFirstContainer: { - width: '100%', - flexDirection: xs || sm || md ? 'column' : 'row', - flexWrap: 'wrap', - paddingTop: 80, - paddingBottom: 40, - alignSelf: 'center', - alignItems: 'center', - justifyContent: 'space-evenly', - position: 'relative', - bottom: 0, - gap: xs || sm || md ? 10 : 0 - }, - firstMainContainer: { - width: '95%', - // justifyContent: 'center', - // alignItems: 'center', - }, - firstContainer: { - width: '100%', - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'flex-start', - gap: 4, - paddingVertical: 18, - }, - logo: { - backgroundColor: currentTheme.colors.tertiaryBlue, - borderRadius: 10, - cursor: 'pointer', - }, - navLinks: { - flexDirection: 'row', - flexWrap: 'wrap', - gap: 16, - margin: 10, - fontSize: 14, - color: currentTheme.colors.textPrimary, - paddingBottom: 40, - }, - navItem: { color: currentTheme.colors.textPrimary }, - credit: { - color: currentTheme.colors.textPrimary, - fontSize: 13, - textAlign: xs ? 'center' : 'left', - fontWeight: 'normal', - paddingTop: sm || md ? 10 : 'auto', - }, - lastContainer: { - display: 'flex', - flexWrap: 'wrap-reverse', - flexDirection: sm ? 'column-reverse' : 'row', - alignItems: 'center', - justifyContent: 'space-between', - width: sm || md ? 'auto' : '95%', - - }, - }); - } + return StyleSheet.create({ + mainContainer: { + width: '100%', + flexDirection: 'column', + paddingTop: 80, + paddingBottom: 40, + alignSelf: 'center', + alignItems: 'center', + justifyContent: 'space-evenly', + position: 'relative', + bottom: 0, + }, + mainFirstContainer: { + width: '100%', + flexDirection: xs || sm || md ? 'column' : 'row', + flexWrap: 'wrap', + paddingTop: 80, + paddingBottom: 40, + alignSelf: 'center', + alignItems: 'center', + justifyContent: 'space-evenly', + position: 'relative', + bottom: 0, + gap: xs || sm || md ? 10 : 0, + }, + firstMainContainer: { + width: '95%', + // justifyContent: 'center', + // alignItems: 'center', + }, + firstContainer: { + width: '100%', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-start', + gap: 4, + paddingVertical: 18, + }, + logo: { + backgroundColor: currentTheme.colors.tertiaryBlue, + borderRadius: 10, + cursor: 'pointer', + }, + navLinks: { + flexDirection: 'row', + flexWrap: 'wrap', + gap: 16, + margin: 10, + fontSize: 14, + color: currentTheme.colors.textPrimary, + paddingBottom: 40, + }, + navItem: { color: currentTheme.colors.textPrimary }, + credit: { + color: currentTheme.colors.textPrimary, + fontSize: 13, + textAlign: xs ? 'center' : 'left', + fontWeight: 'normal', + paddingTop: sm || md ? 10 : 'auto', + }, + lastContainer: { + display: 'flex', + flexWrap: 'wrap-reverse', + flexDirection: sm ? 'column-reverse' : 'row', + alignItems: 'center', + justifyContent: 'space-between', + width: sm || md ? 'auto' : '95%', + }, + }); }; diff --git a/packages/app/modules/feed/components/FeedCard/FeedCard.tsx b/packages/app/modules/feed/components/FeedCard/FeedCard.tsx index a4840e757..e1f84ca89 100644 --- a/packages/app/modules/feed/components/FeedCard/FeedCard.tsx +++ b/packages/app/modules/feed/components/FeedCard/FeedCard.tsx @@ -11,6 +11,7 @@ import { useAddFavorite } from 'app/modules/feed'; import { useAuthUser } from 'app/modules/auth'; import { TripCard } from 'app/modules/trip'; import { PackTemplateCard } from 'app/modules/pack-templates'; +import { ItemCard } from 'app/modules/item'; const convertersByType = { pack: feedItemPackCardConverter, @@ -18,9 +19,10 @@ const convertersByType = { packTemplate: feedItemPackTemplateCardConverter, }; -const cardComponentsByType = { +const cardComponentsByType: Record> = { pack: PackCard, trip: TripCard, + item: ItemCard, packTemplate: PackTemplateCard, }; diff --git a/packages/app/modules/feed/components/FeedCard/utils.ts b/packages/app/modules/feed/components/FeedCard/utils.ts index 51cae716d..07bc0f6a6 100644 --- a/packages/app/modules/feed/components/FeedCard/utils.ts +++ b/packages/app/modules/feed/components/FeedCard/utils.ts @@ -76,6 +76,13 @@ export const feedItemTripCardConverter: Converter< }; }; +export const feedItemCardConverter: Converter< + FeedItem, + RouterOutput['getPackTemplates'][0] +> = (input) => { + return input; +}; + export const feedItemPackTemplateCardConverter: Converter< FeedItem, RouterOutput['getPackTemplates'][0] diff --git a/packages/app/modules/feed/model.ts b/packages/app/modules/feed/model.ts index ea2213d82..4dbef57a8 100644 --- a/packages/app/modules/feed/model.ts +++ b/packages/app/modules/feed/model.ts @@ -7,7 +7,7 @@ export type FeedType = | 'similarPacks' | 'similarItems' | 'packTemplates'; -export type FeedResource = 'pack' | 'trip' | 'packTemplate'; +export type FeedResource = 'pack' | 'item' | 'trip' | 'packTemplate'; export interface BaseFeedItem { id: string; @@ -25,6 +25,7 @@ export interface BaseFeedItem { owner_id: string | { id: string }; createdAt: string; owners: Array<{ any: any }>; + ga; } interface PackFeedItem extends BaseFeedItem { diff --git a/packages/app/modules/feed/widgets/FeedPreview/FeedPreview.tsx b/packages/app/modules/feed/widgets/FeedPreview/FeedPreview.tsx index 0bb0dfae3..de5968ff6 100644 --- a/packages/app/modules/feed/widgets/FeedPreview/FeedPreview.tsx +++ b/packages/app/modules/feed/widgets/FeedPreview/FeedPreview.tsx @@ -4,10 +4,11 @@ import { useFeed } from '../../hooks'; import Loader from 'app/components/Loader'; import { FeedCard, type FeedItem } from 'app/modules/feed'; import { View } from 'tamagui'; +import type { FeedType } from 'app/modules/feed/model'; interface FeedPreviewScrollProps { itemWidth: number; - feedType: string; + feedType: FeedType; id?: string; } @@ -24,15 +25,23 @@ const FeedPreviewScroll: React.FC = ({ ) : ( {validFeedData - ?.filter((item): item is FeedItem => item.type !== null) + ?.filter( + (item): item is FeedItem => + item.type !== null || feedType === 'similarItems', + ) .map((item: FeedItem) => { return ( - + ); })} diff --git a/packages/app/modules/item/components/ItemCard.tsx b/packages/app/modules/item/components/ItemCard.tsx index ff3195180..036c48887 100644 --- a/packages/app/modules/item/components/ItemCard.tsx +++ b/packages/app/modules/item/components/ItemCard.tsx @@ -29,7 +29,10 @@ interface ItemCardProps { onAddPackPress: (itemId: string, e: any) => void; } -const ItemCard = ({ itemData, onAddPackPress }: ItemCardProps) => { +export const ItemCard: React.FC = ({ + itemData, + onAddPackPress, +}) => { const { currentTheme } = useTheme(); const router = useRouter(); const { xxs } = useResponsive(); diff --git a/packages/app/modules/item/components/index.ts b/packages/app/modules/item/components/index.ts index 7172ee83b..a7a303e69 100644 --- a/packages/app/modules/item/components/index.ts +++ b/packages/app/modules/item/components/index.ts @@ -4,3 +4,4 @@ export { ImportItemModal } from './ImportItemModal'; export { SearchItem } from './SearchItem'; export { AddItem } from './AddItem'; export { AddItemModal } from './AddItemModal'; +export { ItemCard } from './ItemCard'; diff --git a/packages/app/modules/item/index.ts b/packages/app/modules/item/index.ts index f5db5466a..518f85c39 100644 --- a/packages/app/modules/item/index.ts +++ b/packages/app/modules/item/index.ts @@ -6,5 +6,6 @@ export { SearchItem, AddItem, AddItemModal, + ItemCard, } from './components'; export * from './model'; diff --git a/server/wrangler.toml.example b/server/wrangler.toml.example index 56277582e..6d35b2a23 100644 --- a/server/wrangler.toml.example +++ b/server/wrangler.toml.example @@ -10,6 +10,7 @@ node_compat = true binding = "DB" database_name = "preview" database_id = "" +migrations_dir = "migrations-preview" [[env.preview.r2_buckets]] binding = 'GEOJSON_BUCKET' From 075ea5d639ee117a24b4407d3f423c9e21562dba Mon Sep 17 00:00:00 2001 From: Taron Date: Fri, 1 Nov 2024 18:47:58 +0400 Subject: [PATCH 2/2] add similar items cards --- .../feed/components/FeedCard/FeedCard.tsx | 2 + .../modules/feed/components/FeedCard/utils.ts | 4 +- .../item/components/ItemCard/ItemCard.tsx | 19 +++++++ .../ItemPrimaryCard.tsx} | 53 ++++++------------- .../components/ItemCard/ItemSecondaryCard.tsx | 31 +++++++++++ .../modules/item/components/ItemCard/index.ts | 1 + .../modules/item/components/ItemCard/model.ts | 19 +++++++ packages/app/modules/item/components/index.ts | 2 +- .../item/screens/ItemDetailsScreen.tsx | 1 + .../modules/item/screens/ProductsScreen.tsx | 8 ++- packages/ui/src/card/SecondaryCard.tsx | 27 ++++++---- server/src/controllers/user/getMe.ts | 3 +- server/src/drizzle/methods/Item.ts | 15 ++++-- 13 files changed, 128 insertions(+), 57 deletions(-) create mode 100644 packages/app/modules/item/components/ItemCard/ItemCard.tsx rename packages/app/modules/item/components/{ItemCard.tsx => ItemCard/ItemPrimaryCard.tsx} (69%) create mode 100644 packages/app/modules/item/components/ItemCard/ItemSecondaryCard.tsx create mode 100644 packages/app/modules/item/components/ItemCard/index.ts create mode 100644 packages/app/modules/item/components/ItemCard/model.ts diff --git a/packages/app/modules/feed/components/FeedCard/FeedCard.tsx b/packages/app/modules/feed/components/FeedCard/FeedCard.tsx index e1f84ca89..b0fbc9976 100644 --- a/packages/app/modules/feed/components/FeedCard/FeedCard.tsx +++ b/packages/app/modules/feed/components/FeedCard/FeedCard.tsx @@ -4,6 +4,7 @@ import { feedItemPackCardConverter, feedItemTripCardConverter, feedItemPackTemplateCardConverter, + feedItemCardConverter, } from './utils'; import { PackCard } from 'app/modules/pack'; import { type CardType } from '@packrat/ui'; @@ -16,6 +17,7 @@ import { ItemCard } from 'app/modules/item'; const convertersByType = { pack: feedItemPackCardConverter, trip: feedItemTripCardConverter, + item: feedItemCardConverter, packTemplate: feedItemPackTemplateCardConverter, }; diff --git a/packages/app/modules/feed/components/FeedCard/utils.ts b/packages/app/modules/feed/components/FeedCard/utils.ts index 07bc0f6a6..bf6dcafbb 100644 --- a/packages/app/modules/feed/components/FeedCard/utils.ts +++ b/packages/app/modules/feed/components/FeedCard/utils.ts @@ -4,7 +4,7 @@ import { type PackDetails } from 'app/modules/pack'; import { truncateString } from 'app/utils/truncateString'; import { type TripDetails } from 'modules/trip/model'; import { roundNumber } from 'app/utils'; -import { RouterOutput } from 'app/trpc'; +import { type RouterOutput } from 'app/trpc'; type Converter = ( input: Input, @@ -80,7 +80,7 @@ export const feedItemCardConverter: Converter< FeedItem, RouterOutput['getPackTemplates'][0] > = (input) => { - return input; + return { item: input }; }; export const feedItemPackTemplateCardConverter: Converter< diff --git a/packages/app/modules/item/components/ItemCard/ItemCard.tsx b/packages/app/modules/item/components/ItemCard/ItemCard.tsx new file mode 100644 index 000000000..878ecbffc --- /dev/null +++ b/packages/app/modules/item/components/ItemCard/ItemCard.tsx @@ -0,0 +1,19 @@ +import React, { type FC } from 'react'; +import { ItemPrimaryCard } from './ItemPrimaryCard'; +import { ItemSecondaryCard } from './ItemSecondaryCard'; +import type { ItemCardProps } from './model'; + +interface Props extends ItemCardProps { + cardType: 'primary' | 'secondary'; +} + +const ItemCards = { + primary: ItemPrimaryCard, + secondary: ItemSecondaryCard, +}; + +export const ItemCard: FC = (props) => { + const PackCardComponent = ItemCards[props.cardType]; + + return ; +}; diff --git a/packages/app/modules/item/components/ItemCard.tsx b/packages/app/modules/item/components/ItemCard/ItemPrimaryCard.tsx similarity index 69% rename from packages/app/modules/item/components/ItemCard.tsx rename to packages/app/modules/item/components/ItemCard/ItemPrimaryCard.tsx index 036c48887..5aa324742 100644 --- a/packages/app/modules/item/components/ItemCard.tsx +++ b/packages/app/modules/item/components/ItemCard/ItemPrimaryCard.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react'; import { Card } from 'tamagui'; -import ItemDetailsContent from './ItemDetailsContent'; +import ItemDetailsContent from '../ItemDetailsContent'; import { RStack, Image, RButton } from '@packrat/ui'; import { TouchableOpacity, View, Platform } from 'react-native'; import useTheme from 'app/hooks/useTheme'; @@ -8,29 +8,10 @@ import { useRouter } from 'app/hooks/router'; import useResponsive from 'app/hooks/useResponsive'; import { PlusCircle } from '@tamagui/lucide-icons'; import ItemPlaceholder from 'app/assets/item-placeholder.png'; +import type { ItemCardProps } from './model'; -interface Item { - id: string; - name: string; - category: { - name: string; - }; - sku: string; - seller: string; - weight: number; - unit: string; - description: string; - productUrl?: string; - images?: Array<{ url }>; -} - -interface ItemCardProps { - itemData: Item; - onAddPackPress: (itemId: string, e: any) => void; -} - -export const ItemCard: React.FC = ({ - itemData, +export const ItemPrimaryCard: React.FC = ({ + item, onAddPackPress, }) => { const { currentTheme } = useTheme(); @@ -40,8 +21,8 @@ export const ItemCard: React.FC = ({ const handlePress = (e) => { e.stopPropagation(); router.push({ - pathname: `/item/${itemData.id}`, - query: { itemId: itemData.id }, + pathname: `/item/${item.id}`, + query: { itemId: item.id }, }); }; @@ -76,7 +57,7 @@ export const ItemCard: React.FC = ({ > = ({ backgroundColor: 'transparent', }} onPress={(e) => { - onAddPackPress(itemData.id, e); + onAddPackPress(item.id, e); }} > @@ -104,14 +85,14 @@ export const ItemCard: React.FC = ({ @@ -121,5 +102,3 @@ export const ItemCard: React.FC = ({ ); }; - -export default ItemCard; diff --git a/packages/app/modules/item/components/ItemCard/ItemSecondaryCard.tsx b/packages/app/modules/item/components/ItemCard/ItemSecondaryCard.tsx new file mode 100644 index 000000000..dbe52de09 --- /dev/null +++ b/packages/app/modules/item/components/ItemCard/ItemSecondaryCard.tsx @@ -0,0 +1,31 @@ +import { Card, Image, RText } from '@packrat/ui'; +import React, { type FC } from 'react'; +import type { ItemCardProps } from './model'; +import ItemPlaceholder from 'app/assets/item-placeholder.png'; +import { convertWeight } from 'app/utils/convertWeight'; + +export const ItemSecondaryCard: FC = ({ item }) => { + return ( + + } + subtitle={`${convertWeight(item.weight, 'g', item.unit)} + ${item.unit}`} + actions={undefined} + type="secondary" + /> + ); +}; diff --git a/packages/app/modules/item/components/ItemCard/index.ts b/packages/app/modules/item/components/ItemCard/index.ts new file mode 100644 index 000000000..3279d334e --- /dev/null +++ b/packages/app/modules/item/components/ItemCard/index.ts @@ -0,0 +1 @@ +export * from './ItemCard'; diff --git a/packages/app/modules/item/components/ItemCard/model.ts b/packages/app/modules/item/components/ItemCard/model.ts new file mode 100644 index 000000000..b8d3a9cb4 --- /dev/null +++ b/packages/app/modules/item/components/ItemCard/model.ts @@ -0,0 +1,19 @@ +export interface Item { + id: string; + name: string; + category: { + name: string; + }; + sku: string; + seller: string; + weight: number; + unit: string; + description: string; + productUrl?: string; + images?: Array<{ url }>; +} + +export interface ItemCardProps { + item: Item; + onAddPackPress?: (itemId: string, e: any) => void; +} diff --git a/packages/app/modules/item/components/index.ts b/packages/app/modules/item/components/index.ts index a7a303e69..fa17accb7 100644 --- a/packages/app/modules/item/components/index.ts +++ b/packages/app/modules/item/components/index.ts @@ -4,4 +4,4 @@ export { ImportItemModal } from './ImportItemModal'; export { SearchItem } from './SearchItem'; export { AddItem } from './AddItem'; export { AddItemModal } from './AddItemModal'; -export { ItemCard } from './ItemCard'; +export { ItemCard } from './ItemCard/ItemCard'; diff --git a/packages/app/modules/item/screens/ItemDetailsScreen.tsx b/packages/app/modules/item/screens/ItemDetailsScreen.tsx index e1558b8d2..9c539f255 100644 --- a/packages/app/modules/item/screens/ItemDetailsScreen.tsx +++ b/packages/app/modules/item/screens/ItemDetailsScreen.tsx @@ -64,6 +64,7 @@ export function ItemDetailsScreen() { width: '80%', backgroundColor: currentTheme.colors.secondaryBlue, paddingBottom: 24, + gap: 16, paddingTop: 0, }} > diff --git a/packages/app/modules/item/screens/ProductsScreen.tsx b/packages/app/modules/item/screens/ProductsScreen.tsx index 478df5196..a00dcecaf 100644 --- a/packages/app/modules/item/screens/ProductsScreen.tsx +++ b/packages/app/modules/item/screens/ProductsScreen.tsx @@ -11,7 +11,7 @@ import { RText, } from '@packrat/ui'; import useResponsive from 'app/hooks/useResponsive'; -import ItemCard from '../components/ItemCard'; +import { ItemCard } from '../components/ItemCard'; import { useFeedSortOptions } from 'app/modules/feed/hooks/useFeedSortOptions'; import { useItemsFeed } from 'app/modules/item/hooks/useItemsFeed'; import { Search, X } from '@tamagui/lucide-icons'; @@ -95,7 +95,11 @@ export function ProductsScreen() { ( - + )} isLoading={isLoading} separatorHeight={12} diff --git a/packages/ui/src/card/SecondaryCard.tsx b/packages/ui/src/card/SecondaryCard.tsx index 1f5493817..708733233 100644 --- a/packages/ui/src/card/SecondaryCard.tsx +++ b/packages/ui/src/card/SecondaryCard.tsx @@ -1,6 +1,6 @@ import React, { type FC } from 'react'; import { type BaseCardProps } from './model'; -import { Card, View, XStack, YStack } from 'tamagui'; +import { Card, View, XStack, YStack, useTheme } from 'tamagui'; import RText from '../RText'; interface SecondaryCardProps extends Omit { @@ -8,21 +8,30 @@ interface SecondaryCardProps extends Omit { } export const SecondaryCard: FC = (props) => { + const theme = useTheme(); + return ( {props.image} = (props) => { flexDirection: 'row', }} > - + {props.title} {props.subtitle} - {props.actions} + {props.actions ? {props.actions} : null} diff --git a/server/src/controllers/user/getMe.ts b/server/src/controllers/user/getMe.ts index 6f1c3165c..1cb5ef380 100644 --- a/server/src/controllers/user/getMe.ts +++ b/server/src/controllers/user/getMe.ts @@ -5,7 +5,6 @@ import { protectedProcedure } from '../../trpc'; export const getMe = async (c: Context) => { try { const { user } = await c.req.json(); - console.log('user ', user); return c.json({ user }, 200); } catch (error) { return c.json({ error: `Failed to get user: ${error.message}` }, 500); @@ -15,6 +14,6 @@ export const getMe = async (c: Context) => { export function getMeRoute() { return protectedProcedure.query(async (opts) => { const { user } = opts.ctx; - return { ...user, role: 'admin' }; + return user; }); } diff --git a/server/src/drizzle/methods/Item.ts b/server/src/drizzle/methods/Item.ts index 8821a66b5..cd82ee183 100644 --- a/server/src/drizzle/methods/Item.ts +++ b/server/src/drizzle/methods/Item.ts @@ -188,10 +188,17 @@ export class Item { } async findAllInArray(arr: string[]) { - return await DbClient.instance - .select() - .from(ItemTable) - .where(inArray(ItemTable.id, arr)); + return await DbClient.instance.query.item.findMany({ + where: inArray(ItemTable.id, arr), + with: { + category: { + columns: { id: true, name: true }, + }, + images: { + columns: { url: true }, + }, + }, + }); } async findGlobal(limit: number, offset: number, searchString: string) {