rn-vs-lb 1.0.65 → 1.0.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/Button/Button.stories.tsx +1 -1
- package/components/Button/DeleteAccountButton.stories.tsx +1 -1
- package/components/Button/PostButton.stories.tsx +1 -1
- package/components/Button/TelegramFeedbackLink.stories.tsx +1 -1
- package/components/Cards/BusinessIdeaCard.stories.tsx +73 -0
- package/components/Cards/BusinessIdeaCard.tsx +251 -0
- package/components/Cards/EventCard.stories.tsx +1 -1
- package/components/Cards/PlaceCard.stories.tsx +1 -1
- package/components/Cards/index.tsx +1 -0
- package/components/Chat/ChatItem.stories.tsx +1 -1
- package/components/Chat/ChatTab/ChatTabs.stories.tsx +1 -1
- package/components/Chat/ChatTab/SubTabButton.stories.tsx +1 -1
- package/components/Chat/InputMessage.stories.tsx +1 -1
- package/components/Chat/MessageItem/MessageItem.stories.tsx +1 -1
- package/components/Chat/PinnedMessagesBar/PinnedMessagesBar.stories.tsx +1 -1
- package/components/Gallery/AiAgentGallery.stories.tsx +1 -1
- package/components/Gallery/ProfileMediaGallery.stories.tsx +66 -0
- package/components/Gallery/ProfileMediaGallery.tsx +239 -0
- package/components/Gallery/ProfileMediaNavigationItem.tsx +73 -0
- package/components/Gallery/ProfileSelfiesGallery.pure.tsx +97 -0
- package/components/Gallery/ProfileSelfiesGallery.stories.tsx +86 -0
- package/components/Gallery/index.ts +4 -1
- package/components/Header/HeaderDefault.stories.tsx +1 -1
- package/components/Header/HeaderEdit.stories.tsx +1 -1
- package/components/Header/HeaderHome.stories.tsx +1 -1
- package/components/Header/HeaderSwitcher.stories.tsx +1 -1
- package/components/Header/HeaderWithImg.stories.tsx +1 -1
- package/components/Modals/GalleryModal.stories.tsx +1 -1
- package/components/Modals/GuestAiChatModal.stories.tsx +1 -1
- package/components/Modals/ReportModal.stories.tsx +1 -1
- package/components/Poll/CommentItem.stories.tsx +1 -1
- package/components/Poll/PollCardList.stories.tsx +1 -1
- package/components/Posts/EventCardList.stories.tsx +1 -1
- package/components/Posts/PlaceCardList.stories.tsx +1 -1
- package/components/Prank/HeroPrankCard.stories.tsx +47 -0
- package/components/Prank/HeroPrankCard.tsx +114 -0
- package/components/Prank/HomelessPrankPage.stories.tsx +58 -0
- package/components/Prank/UploadPromptCard.stories.tsx +55 -0
- package/components/Prank/UploadPromptCard.tsx +130 -0
- package/components/Prank/index.ts +5 -0
- package/components/Profile/ModalProfilePhoto.stories.tsx +1 -1
- package/components/Profile/ProfileCard/ProfileCard.stories.tsx +1 -1
- package/components/Profile/ProfilePhotoBanner.stories.tsx +1 -1
- package/components/Profile/ProfilePhotoUpload/ProfilePhotoUpload.stories.tsx +1 -1
- package/components/Profile/ProfileSummary/ProfileSummary.stories.tsx +52 -0
- package/components/Profile/ProfileSummary/ProfileSummary.tsx +188 -0
- package/components/Profile/ProfileTabs/UserProfileTabs.stories.tsx +1 -1
- package/components/Profile/index.ts +2 -0
- package/components/Screens/AppScreens.stories.tsx +572 -0
- package/components/Screens/HomeScreen.stories.tsx +159 -0
- package/components/Screens/LibraryScreen.stories.tsx +97 -0
- package/components/Settings/AppSettingsScreen.stories.tsx +134 -0
- package/components/Settings/AppSettingsScreen.tsx +215 -0
- package/components/Settings/SettingsHeader.tsx +37 -0
- package/components/Settings/SettingsListItem.tsx +142 -0
- package/components/Settings/SettingsManageAccountButton.tsx +58 -0
- package/components/Settings/SettingsOptionList.tsx +82 -0
- package/components/Settings/SettingsProfileCard.tsx +58 -0
- package/components/Settings/SettingsScreen.stories.tsx +66 -0
- package/components/Settings/SettingsScreen.tsx +129 -0
- package/components/Settings/SettingsSection.tsx +56 -0
- package/components/Settings/SettingsToggleItem.tsx +70 -0
- package/components/Settings/index.ts +23 -0
- package/components/Specialist/Hero.stories.tsx +1 -1
- package/components/Specialist/PortfolioCarousel.stories.tsx +1 -1
- package/components/Specialist/ServicesList.stories.tsx +1 -1
- package/components/Tooltip/DangerTooltip.stories.tsx +1 -1
- package/components/Tooltip/InfoTooltip.stories.tsx +1 -1
- package/components/Tooltip/InfoTooltipBase.stories.tsx +1 -1
- package/components/Tooltip/SucceedTooltip.stories.tsx +1 -1
- package/components/Tooltip/WarningTooltip.stories.tsx +1 -1
- package/components/UI/HorizontalCardSection.stories.tsx +85 -0
- package/components/UI/HorizontalCardSection.tsx +199 -0
- package/components/UI/TabBar/BottomTabBar.stories.tsx +87 -0
- package/components/UI/TabBar/BottomTabBar.tsx +128 -0
- package/components/UI/index.ts +4 -0
- package/components/UserCards/AiAgentHeroCard.stories.tsx +66 -0
- package/components/UserCards/AiAgentHeroCard.tsx +242 -0
- package/components/UserCards/Organizer.stories.tsx +1 -1
- package/components/UserCards/SpecialistCard.stories.tsx +1 -1
- package/components/UserCards/StoryCard.stories.tsx +1 -1
- package/components/UserCards/UserProfileCard.stories.tsx +1 -1
- package/components/UserCards/UserRow.stories.tsx +1 -1
- package/components/UserCards/index.ts +2 -0
- package/components/index.ts +2 -0
- package/package.json +2 -1
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
|
+
import { Meta, StoryFn } from '@storybook/react';
|
|
3
|
+
import { ScrollView, View, Text, StyleSheet } from 'react-native';
|
|
4
|
+
import { ThemeProvider, useTheme } from '../../theme';
|
|
5
|
+
import HeaderDefault from '../Header/HeaderDefault';
|
|
6
|
+
import { HeaderHome } from '../Header/HeaderHome';
|
|
7
|
+
import StatusFilter, { StatusOption } from '../UI/StatusFilter/StatusFilter';
|
|
8
|
+
import TabBar, { TabItem } from '../UI/TabBar/TabBar';
|
|
9
|
+
import HorizontalCardSection, { HorizontalCard } from '../UI/HorizontalCardSection';
|
|
10
|
+
import EventCardList from '../Posts/EventCardList';
|
|
11
|
+
import PlaceCardList from '../Posts/PlaceCardList';
|
|
12
|
+
import ProfileSummary from '../Profile/ProfileSummary/ProfileSummary';
|
|
13
|
+
import ProfilePhotoBanner from '../Profile/ProfilePhotoBanner';
|
|
14
|
+
import UserProfileTabs, { UserProfileTab } from '../Profile/ProfileTabs/UserProfileTabs';
|
|
15
|
+
import {
|
|
16
|
+
ChatItem,
|
|
17
|
+
ChatItemProps,
|
|
18
|
+
ChatTabs,
|
|
19
|
+
InputMessage,
|
|
20
|
+
MessageItem,
|
|
21
|
+
PinnedMessagesBar,
|
|
22
|
+
type MessageItemProps,
|
|
23
|
+
} from '../Chat';
|
|
24
|
+
import type { MessageDTO as TransportMessageDTO } from '../../types/message';
|
|
25
|
+
import Spacer from '../UI/Spacer';
|
|
26
|
+
|
|
27
|
+
const meta: Meta = {
|
|
28
|
+
title: 'Screens/Compositions/AppScreens',
|
|
29
|
+
component: () => null,
|
|
30
|
+
decorators: [
|
|
31
|
+
(Story) => (
|
|
32
|
+
<ThemeProvider>
|
|
33
|
+
<View style={styles.previewBackground}>
|
|
34
|
+
<Story />
|
|
35
|
+
</View>
|
|
36
|
+
</ThemeProvider>
|
|
37
|
+
),
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export default meta;
|
|
42
|
+
|
|
43
|
+
type Story = StoryFn;
|
|
44
|
+
|
|
45
|
+
const ScreenSurface: React.FC<React.PropsWithChildren<{ background?: string }>> = ({ children, background = '#f5f6f8' }) => (
|
|
46
|
+
<View style={styles.screenWrapper}>
|
|
47
|
+
<View style={[styles.screenSurface, { backgroundColor: background }]}>{children}</View>
|
|
48
|
+
</View>
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
type EventCardData = {
|
|
52
|
+
imageUri: string;
|
|
53
|
+
date: string;
|
|
54
|
+
title: string;
|
|
55
|
+
description: string;
|
|
56
|
+
isInvitation: boolean;
|
|
57
|
+
participantsCount?: number;
|
|
58
|
+
maxParticipants?: number;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
type PlaceCardData = {
|
|
62
|
+
imageUri: string;
|
|
63
|
+
title: string;
|
|
64
|
+
description: string;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const storyHighlights: HorizontalCard[] = [
|
|
68
|
+
{
|
|
69
|
+
id: '1',
|
|
70
|
+
title: 'City clean-up day',
|
|
71
|
+
image: { uri: 'https://images.unsplash.com/photo-1500530855697-b586d89ba3ee?auto=format&fit=crop&w=400&q=80' },
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: '2',
|
|
75
|
+
title: 'Street art workshop',
|
|
76
|
+
image: { uri: 'https://images.unsplash.com/photo-1489515217757-5fd1be406fef?auto=format&fit=crop&w=400&q=80' },
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: '3',
|
|
80
|
+
title: 'Local farmer market',
|
|
81
|
+
image: { uri: 'https://images.unsplash.com/photo-1504753793650-d4a2b783c15e?auto=format&fit=crop&w=400&q=80' },
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
const eventFeed: EventCardData[] = [
|
|
86
|
+
{
|
|
87
|
+
imageUri: 'https://images.unsplash.com/photo-1515169067865-5387ec356754?auto=format&fit=crop&w=800&q=80',
|
|
88
|
+
date: 'Tomorrow · 19:00',
|
|
89
|
+
title: 'Community jazz evening',
|
|
90
|
+
description: 'Bring your instrument or just enjoy. Open jam session with local musicians.',
|
|
91
|
+
isInvitation: true,
|
|
92
|
+
participantsCount: 24,
|
|
93
|
+
maxParticipants: 40,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
imageUri: 'https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?auto=format&fit=crop&w=800&q=80',
|
|
97
|
+
date: 'Sat, 12 Oct · 10:00',
|
|
98
|
+
title: 'Kids science fair',
|
|
99
|
+
description: 'Interactive experiments, robotics corner and eco-workshops for the whole family.',
|
|
100
|
+
isInvitation: false,
|
|
101
|
+
participantsCount: 75,
|
|
102
|
+
maxParticipants: 120,
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
const placeFeed: PlaceCardData[] = [
|
|
107
|
+
{
|
|
108
|
+
imageUri: 'https://images.unsplash.com/photo-1517248135467-4c7edcad34c4?auto=format&fit=crop&w=800&q=80',
|
|
109
|
+
title: 'Neighbourhood brunch spot',
|
|
110
|
+
description: 'Seasonal menu, rooftop seating and a cosy corner for remote work sessions.',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
imageUri: 'https://images.unsplash.com/photo-1504674900247-0877df9cc836?auto=format&fit=crop&w=800&q=80',
|
|
114
|
+
title: 'Artisan bakery & coffee',
|
|
115
|
+
description: 'Fresh sourdough every morning, latte art classes on weekends and playlists curated by DJs.',
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
|
|
119
|
+
const profileStats = [
|
|
120
|
+
{ label: 'Followers', value: '4 812' },
|
|
121
|
+
{ label: 'Following', value: '326' },
|
|
122
|
+
{ label: 'Projects', value: 48 },
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
const chatPreviewItems: ChatItemProps[] = [
|
|
126
|
+
{
|
|
127
|
+
variant: 'person',
|
|
128
|
+
senderFullName: 'Alex Johnson',
|
|
129
|
+
imgUrl: 'https://images.unsplash.com/photo-1529626455594-4ff0802cfb7e?auto=format&fit=crop&w=200&q=60',
|
|
130
|
+
isUserOnline: true,
|
|
131
|
+
lastMessage: 'See you at the community hub in 10?',
|
|
132
|
+
createdAt: '10:42',
|
|
133
|
+
unread: '+',
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
variant: 'group',
|
|
137
|
+
chatName: 'Organizers',
|
|
138
|
+
senderFullName: 'Nora',
|
|
139
|
+
imgUrl: 'https://images.unsplash.com/photo-1519340241574-2cec6aef0c01?auto=format&fit=crop&w=200&q=60',
|
|
140
|
+
lastMessage: 'Deck updated with logistics timeline.',
|
|
141
|
+
createdAt: '09:15',
|
|
142
|
+
unread: '+',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
variant: 'bot',
|
|
146
|
+
chatName: 'Event summary bot',
|
|
147
|
+
lastMessage: 'Digest for yesterday is ready. Tap to open.',
|
|
148
|
+
createdAt: '08:00',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
variant: 'person',
|
|
152
|
+
senderFullName: 'Jess Carter',
|
|
153
|
+
imgUrl: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?auto=format&fit=crop&w=200&q=60',
|
|
154
|
+
isUserOnline: false,
|
|
155
|
+
lastMessage: 'Uploading the press photos tonight.',
|
|
156
|
+
createdAt: 'Yesterday',
|
|
157
|
+
},
|
|
158
|
+
];
|
|
159
|
+
|
|
160
|
+
const getChatPreviewLabel = (item: ChatItemProps) =>
|
|
161
|
+
item.variant === 'person' ? item.chatName ?? item.senderFullName : item.chatName;
|
|
162
|
+
|
|
163
|
+
const conversationMessages: MessageItemProps['item'][] = [
|
|
164
|
+
{
|
|
165
|
+
_id: 'm-1',
|
|
166
|
+
sender: { _id: 'alex', fullName: 'Alex Johnson' },
|
|
167
|
+
content: 'Hey! Quick reminder that the venue opens at 18:30. Need help with setup?',
|
|
168
|
+
createdAt: '18:02',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
_id: 'm-2',
|
|
172
|
+
sender: { _id: 'me', fullName: 'You' },
|
|
173
|
+
content: 'All good! Flyers are printed and the volunteer brief is in the shared folder.',
|
|
174
|
+
createdAt: '18:05',
|
|
175
|
+
isEdited: true,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
_id: 'm-3',
|
|
179
|
+
sender: { _id: 'alex', fullName: 'Alex Johnson' },
|
|
180
|
+
content: 'Legend. Dropping the floor plan here 👉 https://example.com/layout',
|
|
181
|
+
createdAt: '18:06',
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
_id: 'm-4',
|
|
185
|
+
sender: { _id: 'alex', fullName: 'Alex Johnson' },
|
|
186
|
+
images: ['https://images.unsplash.com/photo-1556740749-887f6717d7e4?auto=format&fit=crop&w=600&q=80'],
|
|
187
|
+
content: 'Stage lighting looks like this right now.',
|
|
188
|
+
createdAt: '18:07',
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
_id: 'm-5',
|
|
192
|
+
sender: { _id: 'me', fullName: 'You' },
|
|
193
|
+
content: 'Perfect, thanks! I will pin the checklist so everyone sees it.',
|
|
194
|
+
createdAt: '18:08',
|
|
195
|
+
replyTo: {
|
|
196
|
+
_id: 'm-1',
|
|
197
|
+
sender: { _id: 'alex', fullName: 'Alex Johnson' },
|
|
198
|
+
content: 'Hey! Quick reminder that the venue opens at 18:30. Need help with setup?',
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
];
|
|
202
|
+
|
|
203
|
+
const pinnedConversationMessages: TransportMessageDTO[] = conversationMessages.slice(0, 3).map((message) => {
|
|
204
|
+
const mapped: TransportMessageDTO = {
|
|
205
|
+
_id: message._id,
|
|
206
|
+
sender: { _id: message.sender._id },
|
|
207
|
+
content: message.content ?? '',
|
|
208
|
+
createdAt: message.createdAt ?? '',
|
|
209
|
+
readBy: ['me'],
|
|
210
|
+
isEdited: !!message.isEdited,
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
if (message.images?.length) {
|
|
214
|
+
mapped.images = message.images;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (message.attachments?.length) {
|
|
218
|
+
mapped.attachments = message.attachments;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (message.replyTo) {
|
|
222
|
+
mapped.replyTo = {
|
|
223
|
+
_id: message.replyTo._id,
|
|
224
|
+
sender: { _id: message.replyTo.sender?._id ?? 'unknown' },
|
|
225
|
+
content: message.replyTo.content ?? '',
|
|
226
|
+
createdAt: '',
|
|
227
|
+
readBy: ['me'],
|
|
228
|
+
isEdited: false,
|
|
229
|
+
images: message.replyTo.images,
|
|
230
|
+
attachments: message.replyTo.attachments,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return mapped;
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
const useScreenPadding = () => {
|
|
238
|
+
const { sizes } = useTheme();
|
|
239
|
+
return useMemo(() => ({ paddingHorizontal: sizes.md, paddingBottom: sizes.lg }), [sizes]);
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
export const HomeFeed: Story = () => {
|
|
243
|
+
const [activeTab, setActiveTab] = useState(0);
|
|
244
|
+
const [selectedStatus, setSelectedStatus] = useState<StatusOption['key']>('all');
|
|
245
|
+
const padding = useScreenPadding();
|
|
246
|
+
|
|
247
|
+
const tabs: TabItem[] = [
|
|
248
|
+
{ key: 'feed', label: 'Events', icon: 'event' },
|
|
249
|
+
{ key: 'places', label: 'Places', icon: 'place' },
|
|
250
|
+
{ key: 'news', label: 'News', icon: 'article' },
|
|
251
|
+
{ key: 'tasks', label: 'Tasks', icon: 'check-circle' },
|
|
252
|
+
];
|
|
253
|
+
|
|
254
|
+
const statusOptions: StatusOption[] = [
|
|
255
|
+
{ key: 'all', label: 'All' },
|
|
256
|
+
{ key: 'today', label: 'Today' },
|
|
257
|
+
{ key: 'weekend', label: 'Weekend' },
|
|
258
|
+
{ key: 'foryou', label: 'For you' },
|
|
259
|
+
];
|
|
260
|
+
|
|
261
|
+
return (
|
|
262
|
+
<ScreenSurface>
|
|
263
|
+
<ScrollView
|
|
264
|
+
showsVerticalScrollIndicator={false}
|
|
265
|
+
contentContainerStyle={[styles.scrollContent, padding]}
|
|
266
|
+
>
|
|
267
|
+
<Spacer size="sm" />
|
|
268
|
+
<HeaderHome
|
|
269
|
+
logo={<Text style={styles.logo}>CityLife</Text>}
|
|
270
|
+
onPressCity={() => console.log('city')}
|
|
271
|
+
onPressMap={() => console.log('map')}
|
|
272
|
+
onPress={() => console.log('filters')}
|
|
273
|
+
onPressSpecialists={() => console.log('specialists')}
|
|
274
|
+
specialistsActive={activeTab === 3}
|
|
275
|
+
/>
|
|
276
|
+
|
|
277
|
+
<StatusFilter
|
|
278
|
+
selectedStatus={selectedStatus}
|
|
279
|
+
onChangeStatus={setSelectedStatus}
|
|
280
|
+
options={statusOptions}
|
|
281
|
+
type="rounded"
|
|
282
|
+
/>
|
|
283
|
+
|
|
284
|
+
<HorizontalCardSection
|
|
285
|
+
title="Highlights nearby"
|
|
286
|
+
cards={storyHighlights}
|
|
287
|
+
onPressSeeAll={() => console.log('see all highlights')}
|
|
288
|
+
/>
|
|
289
|
+
|
|
290
|
+
<TabBar activeTabIndex={activeTab} onChangeTab={setActiveTab} tabs={tabs} />
|
|
291
|
+
|
|
292
|
+
<View style={styles.feedSection}>
|
|
293
|
+
{activeTab === 1
|
|
294
|
+
? placeFeed.map((card, index) => (
|
|
295
|
+
<PlaceCardList
|
|
296
|
+
key={`place-${index}`}
|
|
297
|
+
imageUri={card.imageUri}
|
|
298
|
+
title={card.title}
|
|
299
|
+
description={card.description}
|
|
300
|
+
/>
|
|
301
|
+
))
|
|
302
|
+
: eventFeed.map((card, index) => (
|
|
303
|
+
<EventCardList
|
|
304
|
+
key={`event-${index}`}
|
|
305
|
+
imageUri={card.imageUri}
|
|
306
|
+
date={card.date}
|
|
307
|
+
title={card.title}
|
|
308
|
+
description={card.description}
|
|
309
|
+
isInvitation={card.isInvitation}
|
|
310
|
+
participantsCount={card.participantsCount}
|
|
311
|
+
maxParticipants={card.maxParticipants}
|
|
312
|
+
/>
|
|
313
|
+
))}
|
|
314
|
+
</View>
|
|
315
|
+
</ScrollView>
|
|
316
|
+
</ScreenSurface>
|
|
317
|
+
);
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
export const ProfilePublic: Story = () => {
|
|
321
|
+
const [activeTab, setActiveTab] = useState<UserProfileTab>('events');
|
|
322
|
+
const padding = useScreenPadding();
|
|
323
|
+
|
|
324
|
+
return (
|
|
325
|
+
<ScreenSurface>
|
|
326
|
+
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={[styles.scrollContent, padding]}>
|
|
327
|
+
<ProfileSummary
|
|
328
|
+
avatarUri="https://images.unsplash.com/photo-1524504388940-b1c1722653e1?auto=format&fit=crop&w=200&q=80"
|
|
329
|
+
name="Maria Ortega"
|
|
330
|
+
username="@maria.designs"
|
|
331
|
+
stats={profileStats}
|
|
332
|
+
website="maria.designs/community"
|
|
333
|
+
showAddButton={false}
|
|
334
|
+
onAvatarPress={() => console.log('open avatar')}
|
|
335
|
+
onEditPress={() => console.log('edit profile')}
|
|
336
|
+
/>
|
|
337
|
+
|
|
338
|
+
<UserProfileTabs activeTab={activeTab} onChangeTab={setActiveTab} />
|
|
339
|
+
|
|
340
|
+
<View style={styles.feedSection}>
|
|
341
|
+
{activeTab === 'events'
|
|
342
|
+
? eventFeed.map((card, index) => (
|
|
343
|
+
<EventCardList
|
|
344
|
+
key={`profile-event-${index}`}
|
|
345
|
+
imageUri={card.imageUri}
|
|
346
|
+
date={card.date}
|
|
347
|
+
title={card.title}
|
|
348
|
+
description={card.description}
|
|
349
|
+
isInvitation={false}
|
|
350
|
+
maxParticipants={card.maxParticipants}
|
|
351
|
+
participantsCount={card.participantsCount}
|
|
352
|
+
/>
|
|
353
|
+
))
|
|
354
|
+
: placeFeed.map((card, index) => (
|
|
355
|
+
<PlaceCardList
|
|
356
|
+
key={`profile-place-${index}`}
|
|
357
|
+
imageUri={card.imageUri}
|
|
358
|
+
title={card.title}
|
|
359
|
+
description={card.description}
|
|
360
|
+
/>
|
|
361
|
+
))}
|
|
362
|
+
</View>
|
|
363
|
+
</ScrollView>
|
|
364
|
+
</ScreenSurface>
|
|
365
|
+
);
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
export const ProfileOwner: Story = () => {
|
|
369
|
+
const [activeTab, setActiveTab] = useState<UserProfileTab>('events');
|
|
370
|
+
const padding = useScreenPadding();
|
|
371
|
+
|
|
372
|
+
return (
|
|
373
|
+
<ScreenSurface>
|
|
374
|
+
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={[styles.scrollContent, padding]}>
|
|
375
|
+
<ProfilePhotoBanner
|
|
376
|
+
message="Add a cover photo so neighbours recognise your projects faster."
|
|
377
|
+
buttonText="Upload cover"
|
|
378
|
+
onAddPhoto={() => console.log('add photo')}
|
|
379
|
+
onClose={() => console.log('dismiss banner')}
|
|
380
|
+
/>
|
|
381
|
+
|
|
382
|
+
<ProfileSummary
|
|
383
|
+
avatarUri="https://images.unsplash.com/photo-1544723795-3fb6469f5b39?auto=format&fit=crop&w=200&q=80"
|
|
384
|
+
name="You"
|
|
385
|
+
username="@city.creator"
|
|
386
|
+
stats={profileStats}
|
|
387
|
+
onAvatarPress={() => console.log('change avatar')}
|
|
388
|
+
onAddPress={() => console.log('add avatar')}
|
|
389
|
+
onEditPress={() => console.log('edit profile')}
|
|
390
|
+
editLabel="Edit profile"
|
|
391
|
+
/>
|
|
392
|
+
|
|
393
|
+
<UserProfileTabs activeTab={activeTab} onChangeTab={setActiveTab} />
|
|
394
|
+
|
|
395
|
+
<View style={styles.feedSection}>
|
|
396
|
+
{activeTab === 'events'
|
|
397
|
+
? eventFeed.map((card, index) => (
|
|
398
|
+
<EventCardList
|
|
399
|
+
key={`owner-event-${index}`}
|
|
400
|
+
imageUri={card.imageUri}
|
|
401
|
+
date={card.date}
|
|
402
|
+
title={card.title}
|
|
403
|
+
description={card.description}
|
|
404
|
+
isInvitation={index === 0}
|
|
405
|
+
maxParticipants={card.maxParticipants}
|
|
406
|
+
participantsCount={card.participantsCount}
|
|
407
|
+
/>
|
|
408
|
+
))
|
|
409
|
+
: placeFeed.map((card, index) => (
|
|
410
|
+
<PlaceCardList
|
|
411
|
+
key={`owner-place-${index}`}
|
|
412
|
+
imageUri={card.imageUri}
|
|
413
|
+
title={card.title}
|
|
414
|
+
description={card.description}
|
|
415
|
+
/>
|
|
416
|
+
))}
|
|
417
|
+
</View>
|
|
418
|
+
</ScrollView>
|
|
419
|
+
</ScreenSurface>
|
|
420
|
+
);
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
export const ChatList: Story = () => {
|
|
424
|
+
const [activeTab, setActiveTab] = useState<'person' | 'group' | 'bot'>('person');
|
|
425
|
+
const [botSubTab, setBotSubTab] = useState<'my' | 'others'>('my');
|
|
426
|
+
const padding = useScreenPadding();
|
|
427
|
+
|
|
428
|
+
return (
|
|
429
|
+
<ScreenSurface>
|
|
430
|
+
<ScrollView
|
|
431
|
+
showsVerticalScrollIndicator={false}
|
|
432
|
+
contentContainerStyle={[styles.scrollContent, padding]}
|
|
433
|
+
>
|
|
434
|
+
<HeaderDefault title="Messages" onBackPress={() => console.log('back')} />
|
|
435
|
+
|
|
436
|
+
<ChatTabs
|
|
437
|
+
activeTab={activeTab}
|
|
438
|
+
onChangeTab={setActiveTab}
|
|
439
|
+
hasUnreadPrivate
|
|
440
|
+
hasUnreadGroup
|
|
441
|
+
hasUnreadBot
|
|
442
|
+
showBotSubTabs
|
|
443
|
+
activeBotSubTab={botSubTab}
|
|
444
|
+
onChangeBotSubTab={setBotSubTab}
|
|
445
|
+
/>
|
|
446
|
+
|
|
447
|
+
<View style={[styles.feedSection, { paddingTop: 8 }]}>
|
|
448
|
+
{chatPreviewItems
|
|
449
|
+
.filter((item) =>
|
|
450
|
+
activeTab === 'bot'
|
|
451
|
+
? item.variant === 'bot'
|
|
452
|
+
: activeTab === 'group'
|
|
453
|
+
? item.variant === 'group'
|
|
454
|
+
: item.variant !== 'bot'
|
|
455
|
+
)
|
|
456
|
+
.map((item, index) => (
|
|
457
|
+
<ChatItem
|
|
458
|
+
key={`${item.variant}-${index}`}
|
|
459
|
+
{...item}
|
|
460
|
+
onPress={() => console.log('open chat', getChatPreviewLabel(item))}
|
|
461
|
+
/>
|
|
462
|
+
))}
|
|
463
|
+
</View>
|
|
464
|
+
</ScrollView>
|
|
465
|
+
</ScreenSurface>
|
|
466
|
+
);
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
export const Conversation: Story = () => {
|
|
470
|
+
const [messageValue, setMessageValue] = useState('');
|
|
471
|
+
const padding = useScreenPadding();
|
|
472
|
+
|
|
473
|
+
return (
|
|
474
|
+
<ScreenSurface background="#eef1f6">
|
|
475
|
+
<View style={[styles.conversationContainer, padding]}>
|
|
476
|
+
<HeaderDefault title="Alex Johnson" onBackPress={() => console.log('back')} />
|
|
477
|
+
|
|
478
|
+
<PinnedMessagesBar
|
|
479
|
+
pinnedMessages={pinnedConversationMessages}
|
|
480
|
+
onUnpin={(id) => console.log('unpin', id)}
|
|
481
|
+
onPress={(id) => console.log('open pinned message', id)}
|
|
482
|
+
isGroupChat={false}
|
|
483
|
+
myId="me"
|
|
484
|
+
lastReadMessageIdOpponent={null}
|
|
485
|
+
fixedItemHeight={84}
|
|
486
|
+
/>
|
|
487
|
+
|
|
488
|
+
<ScrollView
|
|
489
|
+
style={styles.messageList}
|
|
490
|
+
contentContainerStyle={styles.messageListContent}
|
|
491
|
+
showsVerticalScrollIndicator={false}
|
|
492
|
+
>
|
|
493
|
+
<Spacer size="sm" />
|
|
494
|
+
{conversationMessages.map((item) => (
|
|
495
|
+
<MessageItem
|
|
496
|
+
key={item._id}
|
|
497
|
+
item={item}
|
|
498
|
+
myId="me"
|
|
499
|
+
isGroupChat={false}
|
|
500
|
+
isReadByOpponent={item.sender._id === 'me'}
|
|
501
|
+
linkHandler={(url) => console.log('open link', url)}
|
|
502
|
+
timeText={item.createdAt}
|
|
503
|
+
/>
|
|
504
|
+
))}
|
|
505
|
+
</ScrollView>
|
|
506
|
+
|
|
507
|
+
<InputMessage
|
|
508
|
+
value={messageValue}
|
|
509
|
+
onChange={setMessageValue}
|
|
510
|
+
placeholder="Write a message"
|
|
511
|
+
editingLabel="Editing"
|
|
512
|
+
onSubmit={async () => {
|
|
513
|
+
console.log('send message', messageValue);
|
|
514
|
+
setMessageValue('');
|
|
515
|
+
return true;
|
|
516
|
+
}}
|
|
517
|
+
onAttachPress={async () => []}
|
|
518
|
+
/>
|
|
519
|
+
</View>
|
|
520
|
+
</ScreenSurface>
|
|
521
|
+
);
|
|
522
|
+
};
|
|
523
|
+
|
|
524
|
+
const styles = StyleSheet.create({
|
|
525
|
+
previewBackground: {
|
|
526
|
+
flex: 1,
|
|
527
|
+
alignItems: 'center',
|
|
528
|
+
justifyContent: 'center',
|
|
529
|
+
backgroundColor: '#e5e7eb',
|
|
530
|
+
paddingVertical: 32,
|
|
531
|
+
},
|
|
532
|
+
screenWrapper: {
|
|
533
|
+
width: '100%',
|
|
534
|
+
maxWidth: 420,
|
|
535
|
+
paddingHorizontal: 16,
|
|
536
|
+
},
|
|
537
|
+
screenSurface: {
|
|
538
|
+
width: '100%',
|
|
539
|
+
borderRadius: 28,
|
|
540
|
+
overflow: 'hidden',
|
|
541
|
+
borderWidth: 1,
|
|
542
|
+
borderColor: 'rgba(0,0,0,0.08)',
|
|
543
|
+
minHeight: 720,
|
|
544
|
+
},
|
|
545
|
+
scrollContent: {
|
|
546
|
+
paddingTop: 16,
|
|
547
|
+
gap: 16,
|
|
548
|
+
},
|
|
549
|
+
logo: {
|
|
550
|
+
fontSize: 24,
|
|
551
|
+
fontWeight: '700',
|
|
552
|
+
letterSpacing: 1,
|
|
553
|
+
},
|
|
554
|
+
feedSection: {
|
|
555
|
+
gap: 12,
|
|
556
|
+
paddingBottom: 32,
|
|
557
|
+
},
|
|
558
|
+
conversationContainer: {
|
|
559
|
+
flex: 1,
|
|
560
|
+
backgroundColor: '#ffffff',
|
|
561
|
+
gap: 12,
|
|
562
|
+
},
|
|
563
|
+
messageList: {
|
|
564
|
+
flex: 1,
|
|
565
|
+
},
|
|
566
|
+
messageListContent: {
|
|
567
|
+
paddingHorizontal: 8,
|
|
568
|
+
paddingBottom: 12,
|
|
569
|
+
gap: 12,
|
|
570
|
+
},
|
|
571
|
+
});
|
|
572
|
+
|