-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
251 additions
and
70 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 104 additions & 5 deletions
109
lib/components/organisms/RewardTile/RewardTile.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,114 @@ | ||
import { Meta, StoryFn } from "@storybook/react"; | ||
import React from "react"; | ||
import RewardTile from "./index"; | ||
import { Meta, StoryFn } from '@storybook/react'; | ||
import React from 'react'; | ||
import { TileHeight, TileType } from '../../../types/tile'; | ||
import RewardTile from './index'; | ||
// @ts-ignore | ||
import { undefined } from 'zod'; | ||
import rewardImage from '../../../assets/reward.png'; | ||
|
||
export default { | ||
title: "components/organisms/RewardTile", | ||
title: 'components/organisms/RewardTile', | ||
component: RewardTile, | ||
} as Meta; | ||
|
||
const Template: StoryFn<typeof RewardTile> = (args) => <RewardTile {...args} />; | ||
|
||
export const Default = Template.bind({}); | ||
Default.args = { | ||
// Add default props here | ||
tile: { | ||
tileHeight: TileHeight.Full, | ||
active: true, | ||
type: TileType.Reward, | ||
configuration: { | ||
rewardId: '02fdea07-e3eb-4a2d-a66a-cb0368427bd2', | ||
showPrice: false, | ||
reward: { | ||
id: '02fdea07-e3eb-4a2d-a66a-cb0368427bd2', | ||
createdAt: '2024-08-20T08:46:43.851Z', | ||
updatedAt: '2024-08-20T08:46:43.851Z', | ||
name: 'Spotify Premium', | ||
description: 'Get 1 year subscription', | ||
pictureUrl: rewardImage, | ||
value: 0, | ||
price: 0, | ||
priority: 0, | ||
availability: { | ||
start: '2024-08-20T08:46:43.848Z', | ||
end: '2024-09-14T03:04:54.056Z', | ||
}, | ||
purchasable: true, | ||
terms: '', | ||
tier: undefined, | ||
venues: [], | ||
category: null, | ||
discounts: [], | ||
summary: undefined, | ||
redemptionChannels: ['IN_STORE', 'ONLINE'], | ||
purchasableForAudiences: [], | ||
logoUrl: null, | ||
redemptionMessage: undefined, | ||
visibilityCriteria: undefined, | ||
type: 'VOUCHER', | ||
codeType: 'HUMAN', | ||
code: null, | ||
purchaseExpiration: null, | ||
hideCode: false, | ||
notificationConfig: null, | ||
}, | ||
}, | ||
id: '511b2a95-5094-4a01-b958-05643f813822', | ||
createdAt: '2024-08-20T13:05:16.974Z', | ||
updatedAt: '2024-08-20T13:05:16.974Z', | ||
visibilityCriteria: null, | ||
}, | ||
}; | ||
|
||
export const DefaultWithPoints = Template.bind({}); | ||
DefaultWithPoints.args = { | ||
tile: { | ||
tileHeight: TileHeight.Full, | ||
active: true, | ||
type: TileType.Reward, | ||
configuration: { | ||
rewardId: '02fdea07-e3eb-4a2d-a66a-cb0368427bd2', | ||
showPrice: false, | ||
reward: { | ||
id: '02fdea07-e3eb-4a2d-a66a-cb0368427bd2', | ||
createdAt: '2024-08-20T08:46:43.851Z', | ||
updatedAt: '2024-08-20T08:46:43.851Z', | ||
name: 'Spotify Premium', | ||
description: 'Get 1 year subscription', | ||
pictureUrl: rewardImage, | ||
value: 0, | ||
price: 61, | ||
priority: 0, | ||
availability: { | ||
start: '2024-08-20T08:46:43.848Z', | ||
end: '2024-09-14T03:04:54.056Z', | ||
}, | ||
purchasable: true, | ||
terms: '', | ||
tier: undefined, | ||
venues: [], | ||
category: null, | ||
discounts: [], | ||
summary: undefined, | ||
redemptionChannels: ['IN_STORE', 'ONLINE'], | ||
purchasableForAudiences: [], | ||
logoUrl: null, | ||
redemptionMessage: undefined, | ||
visibilityCriteria: undefined, | ||
type: 'VOUCHER', | ||
codeType: 'HUMAN', | ||
code: null, | ||
purchaseExpiration: null, | ||
hideCode: false, | ||
notificationConfig: null, | ||
}, | ||
}, | ||
id: '511b2a95-5094-4a01-b958-05643f813822', | ||
createdAt: '2024-08-20T13:05:16.974Z', | ||
updatedAt: '2024-08-20T13:05:16.974Z', | ||
visibilityCriteria: null, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,134 @@ | ||
import React, { createContext, useContext } from "react"; | ||
import { RewardTileConfig } from "../../../types/tile"; | ||
import { | ||
Button as ButtonAtom, | ||
Image as ImageAtom, | ||
Text, | ||
Tile, | ||
} from "../../atoms"; | ||
|
||
type RewardTileContextType = { | ||
configuration: RewardTileConfig; | ||
}; | ||
|
||
const RewardTileContext = createContext<RewardTileContextType | undefined>( | ||
undefined | ||
); | ||
import React from 'react'; | ||
import { Image, StyleSheet, View } from 'react-native'; | ||
import { useWllSdk } from '../../../context/WllSdkContext'; | ||
import { RewardTileConfig, Tile } from '../../../types/tile'; | ||
import { createResponsiveStyle } from '../../../utils/responsiveHelper'; | ||
import { BaseTile, Icon, Text } from '../../atoms'; | ||
import { useTileContext } from '../../atoms/BaseTile'; | ||
import { useSectionContext } from '../Section'; | ||
|
||
type RewardTileProps = { | ||
configuration: RewardTileConfig; | ||
children: React.ReactNode; | ||
tile: Tile; | ||
}; | ||
|
||
const RewardTile: React.FC<RewardTileProps> & { | ||
Image: typeof ImageAtom; | ||
Title: typeof Text; | ||
Description: typeof Text; | ||
Button: typeof ButtonAtom; | ||
} = ({ configuration, children }) => { | ||
Image: typeof RewardTileImage; | ||
Title: typeof RewardTileTitle; | ||
Description: typeof RewardTileDescription; | ||
Points: typeof RewardTilePoints; | ||
} = ({ tile }) => { | ||
const { theme } = useWllSdk(); | ||
return ( | ||
<BaseTile tile={tile}> | ||
<RewardTile.Image /> | ||
<View style={styles.textContainer}> | ||
<View style={styles.row}> | ||
<RewardTile.Title /> | ||
<Icon name="ChevronRight" color={theme.derivedSurfaceText[20]} /> | ||
</View> | ||
<RewardTile.Description /> | ||
<RewardTile.Points /> | ||
</View> | ||
</BaseTile> | ||
); | ||
}; | ||
|
||
const RewardTileImage: React.FC = () => { | ||
const { configuration } = useTileContext(); | ||
const { reward } = configuration as RewardTileConfig; | ||
|
||
if (!reward?.pictureUrl) return null; | ||
return ( | ||
<RewardTileContext.Provider value={{ configuration }}> | ||
<Tile>{children}</Tile> | ||
</RewardTileContext.Provider> | ||
<View style={styles.imageContainer}> | ||
<Image source={{ uri: reward?.pictureUrl }} style={styles.image} /> | ||
</View> | ||
); | ||
}; | ||
|
||
const useRewardTileContext = () => { | ||
const context = useContext(RewardTileContext); | ||
if (!context) { | ||
throw new Error( | ||
"RewardTile compound components must be used within RewardTile" | ||
); | ||
} | ||
return context; | ||
const RewardTileTitle: React.FC = () => { | ||
const { configuration } = useTileContext(); | ||
const { reward } = configuration as RewardTileConfig; | ||
|
||
if (!reward?.name) return null; | ||
return ( | ||
<Text variant="title" ellipsizeMode="tail" numberOfLines={1}> | ||
{reward?.name} | ||
</Text> | ||
); | ||
}; | ||
|
||
RewardTile.Image = ImageAtom; | ||
RewardTile.Title = Text; | ||
RewardTile.Description = Text; | ||
RewardTile.Button = ButtonAtom; | ||
const RewardTileDescription: React.FC = () => { | ||
const { configuration } = useTileContext(); | ||
const { reward } = configuration as RewardTileConfig; | ||
|
||
if (!reward?.description) return null; | ||
return <Text variant="body">{reward?.description}</Text>; | ||
}; | ||
|
||
const RewardTilePoints: React.FC = () => { | ||
const { sectionData } = useSectionContext(); | ||
const { configuration } = useTileContext(); | ||
const { theme } = useWllSdk(); | ||
const { reward } = configuration as RewardTileConfig; | ||
|
||
const effectiveMultiplier = sectionData?.pointsMultiplier ?? 1; | ||
const effectivePrefix = sectionData?.pointsPrefix ?? ''; | ||
const effectiveSuffix = sectionData?.pointsSuffix ?? 'pts'; | ||
const calculatedPoints = | ||
reward?.price !== undefined ? reward.price * effectiveMultiplier : null; | ||
if (reward?.price === 0) return null; | ||
return ( | ||
<Text | ||
style={[ | ||
styles.points, | ||
{ | ||
color: theme.primary, | ||
}, | ||
]} | ||
> | ||
{effectivePrefix} | ||
{calculatedPoints} | ||
{effectiveSuffix} | ||
</Text> | ||
); | ||
}; | ||
|
||
const styles = StyleSheet.create({ | ||
imageContainer: createResponsiveStyle({ | ||
width: '100%', | ||
flexBasis: '50%', | ||
marginBottom: [8, 8, 12], | ||
}), | ||
image: { | ||
position: 'absolute', | ||
top: 0, | ||
left: 0, | ||
bottom: 0, | ||
right: 0, | ||
width: '100%', | ||
height: '100%', | ||
resizeMode: 'cover', | ||
}, | ||
textContainer: createResponsiveStyle({ | ||
paddingHorizontal: [8, 8, 12], | ||
flex: 1, | ||
}), | ||
row: createResponsiveStyle({ | ||
flexDirection: 'row', | ||
alignItems: 'center', | ||
justifyContent: 'space-between', | ||
marginBottom: [4, 4, 8], | ||
}), | ||
points: { | ||
marginTop: 8, | ||
fontSize: 14, | ||
fontWeight: 'bold', | ||
}, | ||
}); | ||
|
||
RewardTile.Image = RewardTileImage; | ||
RewardTile.Title = RewardTileTitle; | ||
RewardTile.Description = RewardTileDescription; | ||
RewardTile.Points = RewardTilePoints; | ||
|
||
export default RewardTile; |
Oops, something went wrong.