Viktoriia 6 dní pred
rodič
commit
82042cf86c

+ 20 - 2
src/modules/api/events/events-api.ts

@@ -56,7 +56,7 @@ export type EventSettings = {
   address1: string;
   location: string;
   capacity: number;
-  type: 1 | 2 | 3;
+  type: 1 | 2 | 3 | 4;
   registrations_info: 1 | 2 | 3 | 4 | 5;
   address2: string;
   details: string;
@@ -105,6 +105,8 @@ export type EventData = SingleEvent & {
   settings: EventSettings;
   participants_data: Participants[];
   participants_full_data: User[];
+  participants_approved_data: Participants[];
+  participants_approved_full_data: User[];
   joined: 0 | 1;
   attachments: EventAttachments[];
   files: EventAttachments[];
@@ -211,6 +213,12 @@ export interface PostUpdateEvent {
   event: any;
 }
 
+export interface PostUpdateSharedTrip {
+  token: string;
+  trip_id: number;
+  trip: any;
+}
+
 export const eventsApi = {
   getEventsList: (token: string, past: number) =>
     request.postForm<PostGetEventsListReturn>(API.GET_EVENTS_LIST, { token, past }),
@@ -261,5 +269,15 @@ export const eventsApi = {
   removeParticipant: (token: string, event_id: number, user_id: number) =>
     request.postForm<ResponseType>(API.REMOVE_PARTICIPANT, { token, event_id, user_id }),
   addSharedTrip: (data: PostAddSharedTrip) =>
-    request.postForm<ResponseType>(API.ADD_SHARED_TRIP, data)
+    request.postForm<ResponseType>(API.ADD_SHARED_TRIP, data),
+  updateSharedTrip: (data: PostUpdateSharedTrip) =>
+    request.postForm<ResponseType>(API.UPDATE_SHARED_TRIP, data),
+  sharedTripAddParticipant: (token: string, event_id: number, user_id: number) =>
+    request.postForm<ResponseType>(API.SHARED_TRIP_ADD_PARTICIPANT, {
+      token,
+      event_id,
+      user_id
+    }),
+  setFull: (token: string, id: number, full: 0 | 1) =>
+    request.postForm<ResponseType>(API.SET_FULL, { token, id, full })
 };

+ 2 - 1
src/modules/api/events/events-query-keys.tsx

@@ -24,5 +24,6 @@ export const eventsQueryKeys = {
   sharedTripRemoveParticipant: () => ['sharedTripRemoveParticipant'] as const,
   getSharedTripForEditing: () => ['getSharedTripForEditing'] as const,
   updateSharedTrip: () => ['updateSharedTrip'] as const,
-  cancelSharedTrip: () => ['cancelSharedTrip'] as const
+  cancelSharedTrip: () => ['cancelSharedTrip'] as const,
+  setFull: () => ['setFull'] as const
 };

+ 2 - 1
src/modules/api/events/queries/index.ts

@@ -16,9 +16,10 @@ export * from './use-post-cancel-event';
 export * from './use-post-remove-participant';
 export * from './use-post-join-shared-trip';
 export * from './use-post-unjoin-shared-trip';
-export * from './use-post-shared-trip-add-participant';
+export * from './use-post-add-participant';
 export * from './use-post-shared-trip-remove-participant';
 export * from './use-post-get-shared-trip-for-editing';
 export * from './use-post-update-shared-trip';
 export * from './use-post-cancel-shared-trip';
 export * from './use-post-add-shared-trip';
+export * from './use-post-set-event-full';

+ 0 - 0
src/modules/api/events/queries/use-post-shared-trip-add-participant.tsx → src/modules/api/events/queries/use-post-add-participant.tsx


+ 17 - 0
src/modules/api/events/queries/use-post-set-event-full.tsx

@@ -0,0 +1,17 @@
+import { useMutation } from '@tanstack/react-query';
+
+import { eventsQueryKeys } from '../events-query-keys';
+import { eventsApi } from '../events-api';
+
+import type { BaseAxiosError } from '../../../../types';
+import { ResponseType } from '@api/response-type';
+
+export const usePostSetFullMutation = () => {
+  return useMutation<ResponseType, BaseAxiosError, { token: string; id: number; full: 0 | 1 }>({
+    mutationKey: eventsQueryKeys.setFull(),
+    mutationFn: async (data) => {
+      const response = await eventsApi.setFull(data.token, data.id, data.full);
+      return response.data;
+    }
+  });
+};

+ 2 - 2
src/modules/api/events/queries/use-post-update-shared-trip.tsx

@@ -1,13 +1,13 @@
 import { useMutation } from '@tanstack/react-query';
 
 import { eventsQueryKeys } from '../events-query-keys';
-import { type PostUpdateEvent, eventsApi } from '../events-api';
+import { type PostUpdateSharedTrip, eventsApi } from '../events-api';
 
 import type { BaseAxiosError } from '../../../../types';
 import { ResponseType } from '@api/response-type';
 
 export const usePostUpdateSharedTripMutation = () => {
-  return useMutation<ResponseType, BaseAxiosError, PostUpdateEvent, ResponseType>({
+  return useMutation<ResponseType, BaseAxiosError, PostUpdateSharedTrip, ResponseType>({
     mutationKey: eventsQueryKeys.updateSharedTrip(),
     mutationFn: async (data) => {
       const response = await eventsApi.updateSharedTrip(data);

+ 36 - 4
src/screens/InAppScreens/TravelsScreen/Components/OptionsModal.tsx

@@ -4,13 +4,17 @@ import ActionSheet, { SheetManager } from 'react-native-actions-sheet';
 import { Colors } from 'src/theme';
 import { getFontSize } from 'src/utils';
 import BanIcon from 'assets/icons/messages/ban.svg';
-import { usePostRemoveParticipantMutation } from '@api/events';
+import {
+  usePostRemoveParticipantMutation,
+  usePostSharedTripAddParticipantMutation
+} from '@api/events';
 import { useSafeAreaInsets } from 'react-native-safe-area-context';
 
 const OptionsModal = () => {
   const insets = useSafeAreaInsets();
   const [userData, setUserData] = useState<any>(null);
   const { mutateAsync: removeParticipant } = usePostRemoveParticipantMutation();
+  const { mutateAsync: addParticipant } = usePostSharedTripAddParticipantMutation();
 
   const [shouldOpenWarningModal, setShouldOpenWarningModal] = useState<any>(null);
 
@@ -48,6 +52,28 @@ const OptionsModal = () => {
     }, 300);
   };
 
+  const handleAddParticipant = async () => {
+    if (!userData) return;
+
+    await addParticipant(
+      {
+        token: userData.token,
+        event_id: userData.eventId,
+        user_id: userData.userId
+      },
+      {
+        onSuccess: () => {
+          userData.filterParticipants();
+        }
+      }
+    );
+
+    setTimeout(() => {
+      SheetManager.hide('host-options-modal');
+      setShouldOpenWarningModal(null);
+    }, 300);
+  };
+
   return (
     <ActionSheet
       id="host-options-modal"
@@ -71,10 +97,16 @@ const OptionsModal = () => {
           <View style={[styles.optionsContainer, { paddingVertical: 0, gap: 0 }]}>
             <TouchableOpacity
               style={[styles.option, styles.dangerOption]}
-              onPress={handleRemoveParticipant}
+              onPress={userData.interested ? handleAddParticipant : handleRemoveParticipant}
             >
-              <Text style={[styles.optionText, styles.dangerText]}>Remove participant</Text>
-              <BanIcon fill={Colors.RED} />
+              {userData.interested ? (
+                <Text style={[styles.optionText]}>Add participant</Text>
+              ) : (
+                <>
+                  <Text style={[styles.optionText, styles.dangerText]}>Remove participant</Text>
+                  <BanIcon fill={Colors.RED} />
+                </>
+              )}
             </TouchableOpacity>
           </View>
         </View>

+ 112 - 92
src/screens/InAppScreens/TravelsScreen/CreateSharedTrip/index.tsx

@@ -31,7 +31,9 @@ import {
   usePostAddSharedTripMutation,
   usePostCancelEventMutation,
   usePostGetPhotosForRegionMutation,
-  usePostUpdateEventMutation
+  usePostSetFullMutation,
+  usePostUpdateEventMutation,
+  usePostUpdateSharedTripMutation
 } from '@api/events';
 import { SheetManager } from 'react-native-actions-sheet';
 import PhotosForRegionModal from '../Components/PhotosForRegionModal/PhotosForRegionModal';
@@ -39,6 +41,7 @@ import { API_HOST } from 'src/constants';
 import AddMapPinModal from '../Components/AddMapPinModal';
 import { NAVIGATION_PAGES } from 'src/types';
 import TrashSvg from 'assets/icons/travels-screens/trash-solid.svg';
+import { useGetRegionsWithFlagQuery } from '@api/regions';
 
 const EventSchema = yup.object({
   title: yup.string().required().min(3),
@@ -51,7 +54,6 @@ const EventSchema = yup.object({
 
 const CreateSharedTripScreen = ({ route }: { route: any }) => {
   const eventId = route.params?.eventId;
-  // TO DO
   const eventData = route.params?.event;
   const token = (storage.get('token', StoreType.STRING) as string) ?? null;
   const navigation = useNavigation();
@@ -59,8 +61,10 @@ const CreateSharedTripScreen = ({ route }: { route: any }) => {
   const richText = useRef<RichEditor | null>(null);
   const { mutateAsync: getPhotosForRegion } = usePostGetPhotosForRegionMutation();
   const { mutateAsync: addSharedTrip } = usePostAddSharedTripMutation();
-  const { mutateAsync: updateEvent } = usePostUpdateEventMutation();
+  const { mutateAsync: updateEvent } = usePostUpdateSharedTripMutation();
   const { mutateAsync: cancelEvent } = usePostCancelEventMutation();
+  const { mutateAsync: setFull } = usePostSetFullMutation();
+  const { data: regionslist } = useGetRegionsWithFlagQuery(true);
 
   const [isSubmitting, setIsSubmitting] = useState(false);
   const [calendarVisible, setCalendarVisible] = useState<'start_date' | 'end_date' | null>(null);
@@ -119,9 +123,9 @@ const CreateSharedTripScreen = ({ route }: { route: any }) => {
 
   const initialData: any = {
     title: eventData?.title ?? '',
-    start_date: eventData?.start_date ?? '',
-    end_date: eventData?.end_date ?? '',
-    tentative: eventData?.tentative ?? 0,
+    start_date: eventData?.date_from ?? '',
+    end_date: eventData?.date_to ?? '',
+    tentative: eventData?.date_tentative ?? 0,
     photo: null,
     details: eventData?.details ?? ''
   };
@@ -136,10 +140,21 @@ const CreateSharedTripScreen = ({ route }: { route: any }) => {
   });
 
   useEffect(() => {
-    if (eventData && eventData.regions) {
-      setRegions(eventData.regions);
+    if (eventData && eventData.regions && regionslist && regionslist.data) {
+      const parsedRegions = JSON.parse(eventData.regions);
+      let regionsData: any = [];
+      parsedRegions.forEach((region: any) => {
+        const regionWithFlag = regionslist.data?.find((r: any) => r.id === +region);
+        regionsData.push({
+          flag1: regionWithFlag?.flag ?? '',
+          flag2: null,
+          region_name: regionWithFlag?.name ?? '',
+          id: regionWithFlag?.id ?? region.id
+        });
+      });
+      setRegions(regionsData);
     }
-  }, [eventData]);
+  }, [eventData, regionslist]);
 
   const handleCancelTrip = () => {
     setModalInfo({
@@ -201,7 +216,7 @@ const CreateSharedTripScreen = ({ route }: { route: any }) => {
 
                 if (eventId) {
                   await updateEvent(
-                    { token, event_id: eventId, event: JSON.stringify(newTrip) },
+                    { token, trip_id: eventId, trip: JSON.stringify(newTrip) },
                     {
                       onSuccess: (res) => {
                         setIsSubmitting(false);
@@ -213,7 +228,6 @@ const CreateSharedTripScreen = ({ route }: { route: any }) => {
                     }
                   );
                 } else {
-                  console.log('newTrip', newTrip);
                   await addSharedTrip(
                     { token, trip: JSON.stringify(newTrip) },
                     {
@@ -292,92 +306,83 @@ const CreateSharedTripScreen = ({ route }: { route: any }) => {
                     />
                   </TouchableOpacity>
 
-                  {eventId ? (
-                    <Input
-                      header={'NomadMania region'}
-                      inputMode={'none'}
-                      editable={false}
-                      value={eventData?.region_name}
-                    />
-                  ) : (
-                    <View>
-                      <Text
-                        style={{
-                          color: Colors.DARK_BLUE,
-                          fontSize: getFontSize(14),
-                          fontFamily: 'redhat-700',
-                          marginBottom: 8
-                        }}
-                      >
-                        NomadMania regions
-                      </Text>
-
-                      <TouchableOpacity
-                        style={styles.addRegionBtn}
-                        onPress={() =>
-                          navigation.navigate(
-                            ...([
-                              NAVIGATION_PAGES.ADD_REGIONS,
-                              { regionsParams: regions, editId: eventId, isSharedTrip: true }
-                            ] as never)
-                          )
-                        }
-                      >
-                        <Text style={styles.addRegionBtntext}>Add Region</Text>
-                      </TouchableOpacity>
-
-                      {regions && regions.length ? (
-                        <View style={styles.regionsContainer}>
-                          {regions.map((region) => {
-                            const [name, ...rest] = region.region_name?.split(/ – | - /);
-                            const subname = rest?.join(' - ');
+                  <View>
+                    <Text
+                      style={{
+                        color: Colors.DARK_BLUE,
+                        fontSize: getFontSize(14),
+                        fontFamily: 'redhat-700',
+                        marginBottom: 8
+                      }}
+                    >
+                      NomadMania regions
+                    </Text>
 
-                            return (
-                              <View key={region.id} style={styles.regionItem}>
-                                <View style={styles.regionHeader}>
+                    <TouchableOpacity
+                      style={styles.addRegionBtn}
+                      onPress={() =>
+                        navigation.navigate(
+                          ...([
+                            NAVIGATION_PAGES.ADD_REGIONS,
+                            { regionsParams: regions, editId: eventId, isSharedTrip: true }
+                          ] as never)
+                        )
+                      }
+                    >
+                      <Text style={styles.addRegionBtntext}>Add Region</Text>
+                    </TouchableOpacity>
+
+                    {regions && regions.length ? (
+                      <View style={styles.regionsContainer}>
+                        {regions.map((region) => {
+                          const [name, ...rest] = region.region_name?.split(/ – | - /);
+                          const subname = rest?.join(' - ');
+
+                          return (
+                            <View key={region.id} style={styles.regionItem}>
+                              <View style={styles.regionHeader}>
+                                <Image
+                                  source={{ uri: `${API_HOST}/img/flags_new/${region.flag1}` }}
+                                  style={styles.flagStyle}
+                                />
+                                {region.flag2 && (
                                   <Image
-                                    source={{ uri: `${API_HOST}/img/flags_new/${region.flag1}` }}
-                                    style={styles.flagStyle}
+                                    source={{
+                                      uri: `${API_HOST}/img/flags_new/${region.flag2}`
+                                    }}
+                                    style={[styles.flagStyle, { marginLeft: -17 }]}
                                   />
-                                  {region.flag2 && (
-                                    <Image
-                                      source={{
-                                        uri: `${API_HOST}/img/flags_new/${region.flag2}`
-                                      }}
-                                      style={[styles.flagStyle, { marginLeft: -17 }]}
-                                    />
-                                  )}
-                                  <View style={styles.nameContainer}>
-                                    <Text style={styles.regionName}>{name}</Text>
-                                    <Text style={styles.regionSubname}>{subname}</Text>
-                                  </View>
+                                )}
+                                <View style={styles.nameContainer}>
+                                  <Text style={styles.regionName}>{name}</Text>
+                                  <Text style={styles.regionSubname}>{subname}</Text>
                                 </View>
-                                <TouchableOpacity
-                                  style={styles.trashBtn}
-                                  onPress={() => handleDeleteRegion(region.id)}
-                                >
-                                  <TrashSvg fill={Colors.WHITE} />
-                                </TouchableOpacity>
                               </View>
-                            );
-                          })}
-                        </View>
-                      ) : regionsError ? (
-                        <Text
-                          style={{
-                            color: Colors.RED,
-                            fontSize: getFontSize(12),
-                            fontFamily: 'redhat-600',
-                            marginTop: 5
-                          }}
-                        >
-                          {regionsError}
-                        </Text>
-                      ) : (
-                        <Text style={styles.noRegiosText}>No regions at the moment</Text>
-                      )}
-                    </View>
-                  )}
+                              <TouchableOpacity
+                                style={styles.trashBtn}
+                                onPress={() => handleDeleteRegion(region.id)}
+                              >
+                                <TrashSvg fill={Colors.WHITE} />
+                              </TouchableOpacity>
+                            </View>
+                          );
+                        })}
+                      </View>
+                    ) : regionsError ? (
+                      <Text
+                        style={{
+                          color: Colors.RED,
+                          fontSize: getFontSize(12),
+                          fontFamily: 'redhat-600',
+                          marginTop: 5
+                        }}
+                      >
+                        {regionsError}
+                      </Text>
+                    ) : (
+                      <Text style={styles.noRegiosText}>No regions at the moment</Text>
+                    )}
+                  </View>
 
                   {regions && regions.length > 0 && photos.length > 0 ? (
                     <Input
@@ -538,6 +543,21 @@ const CreateSharedTripScreen = ({ route }: { route: any }) => {
                         Update trip
                       </Button>
 
+                      <Button
+                        variant={ButtonVariants.OPACITY}
+                        containerStyles={{
+                          backgroundColor: Colors.WHITE,
+                          borderColor: Colors.BORDER_LIGHT
+                        }}
+                        textStyles={{ color: Colors.DARK_BLUE }}
+                        onPress={async () => {
+                          await setFull({ token, id: eventId, full: 1 });
+                          navigation.goBack();
+                        }}
+                      >
+                        Set Full
+                      </Button>
+
                       <Button
                         variant={ButtonVariants.OPACITY}
                         containerStyles={{

+ 188 - 19
src/screens/InAppScreens/TravelsScreen/EventScreen/index.tsx

@@ -104,6 +104,7 @@ const EventScreen = ({ route }: { route: any }) => {
 
   const [isExpanded, setIsExpanded] = useState(false);
   const [tooltipUser, setTooltipUser] = useState<number | null>(null);
+  const [tooltipInterested, setTooltipInterested] = useState<number | null>(null);
 
   const [event, setEvent] = useState<EventData | null>(null);
   const [registrationInfo, setRegistrationInfo] = useState<{ color: string; name: string } | null>(
@@ -112,6 +113,7 @@ const EventScreen = ({ route }: { route: any }) => {
   const [filteredParticipants, setFilteredParticipants] = useState<EventData['participants_data']>(
     []
   );
+  const [filteredInterested, setFilteredInterested] = useState<EventData['participants_data']>([]);
   const [maxVisibleParticipants, setMaxVisibleParticipants] = useState(0);
   const [maxVisibleParticipantsWithGap, setMaxVisibleParticipantsWithGap] = useState(0);
   const [joined, setJoined] = useState<0 | 1>(0);
@@ -162,7 +164,10 @@ const EventScreen = ({ route }: { route: any }) => {
       const partisipantsWidth = contentWidth / 2;
       setMaxVisibleParticipants(Math.floor(partisipantsWidth / 22));
       setMaxVisibleParticipantsWithGap(Math.floor(partisipantsWidth / 32));
-      setFilteredParticipants(data.data.participants_data);
+      setFilteredParticipants(
+        data.data.type === 4 ? data.data.participants_approved_data : data.data.participants_data
+      );
+      setFilteredInterested(data.data.participants_data);
 
       setRegistrationInfo(() => {
         if (data.data.full) {
@@ -389,7 +394,7 @@ const EventScreen = ({ route }: { route: any }) => {
       return;
     }
 
-    if (event.settings.type !== 1) {
+    if (event.settings.type !== 1 && event.settings.type !== 4) {
       setModalInfo({
         visible: true,
         type: 'success',
@@ -588,6 +593,50 @@ const EventScreen = ({ route }: { route: any }) => {
 
   const formatEventDate = (event: EventData) => {
     if (event.date_from && event.date_to) {
+      if (event.date_tentative) {
+        const dateFrom = moment(event.date_from, 'YYYY-MM').format('MMM YYYY');
+        const dateTo = moment(event.date_to, 'YYYY-MM').format('MMM YYYY');
+
+        if (dateFrom === dateTo) {
+          return (
+            <View>
+              <Text
+                style={{
+                  fontSize: getFontSize(12),
+                  fontWeight: '600',
+                  color: Colors.DARK_BLUE
+                }}
+              >
+                {dateFrom}
+              </Text>
+            </View>
+          );
+        }
+        return (
+          <View>
+            <Text
+              style={{
+                fontSize: getFontSize(12),
+                fontWeight: '600',
+                color: Colors.DARK_BLUE,
+                flex: 1
+              }}
+            >
+              {dateFrom} -{' '}
+            </Text>
+            <Text
+              style={{
+                fontSize: getFontSize(12),
+                fontWeight: '600',
+                color: Colors.DARK_BLUE,
+                flex: 1
+              }}
+            >
+              {dateTo}
+            </Text>
+          </View>
+        );
+      }
       return (
         <View>
           <Text
@@ -615,6 +664,21 @@ const EventScreen = ({ route }: { route: any }) => {
     } else {
       let date = moment(event.date, 'YYYY-MM-DD').format('DD MMMM YYYY');
 
+      if (event.date_tentative) {
+        return (
+          <View>
+            <Text
+              style={{
+                fontSize: getFontSize(12),
+                fontWeight: '600',
+                color: Colors.DARK_BLUE
+              }}
+            >
+              {moment(event.date, 'YYYY-MM').format('MMM YYYY')}
+            </Text>
+          </View>
+        );
+      }
       return (
         <View>
           <Text
@@ -736,7 +800,9 @@ const EventScreen = ({ route }: { route: any }) => {
       .catch((err) => console.error('Error opening event location', err));
   };
 
-  const photoUrl = API_HOST + '/webapi/events/get-main-photo/' + event.id;
+  const photoUrl = event.photo
+    ? API_HOST + '/webapi/events/get-main-photo/' + event.id
+    : API_HOST + '/static/img/events/trip.webp';
 
   return (
     <View style={styles.container}>
@@ -759,7 +825,8 @@ const EventScreen = ({ route }: { route: any }) => {
           showsVerticalScrollIndicator={false}
           removeClippedSubviews={false}
         >
-          {event.settings.type === 1 && photosForRegion.length > 0 ? (
+          {(event.settings.type === 1 || event.settings.type === 4) &&
+          photosForRegion.length > 0 ? (
             <ImageCarousel
               photos={photosForRegion as PhotosData[]}
               activeIndex={activeIndex}
@@ -861,7 +928,7 @@ const EventScreen = ({ route }: { route: any }) => {
                     flex: 1
                   }}
                 >
-                  {event.settings.address1}
+                  {event.address1}
                 </Text>
               </View>
 
@@ -892,7 +959,7 @@ const EventScreen = ({ route }: { route: any }) => {
                 </TouchableOpacity>
               )}
 
-              {event.settings.registrations_info !== 1 && (
+              {event.settings.registrations_info !== 1 && event.type !== 4 && (
                 <View style={{ flexDirection: 'row', alignItems: 'center', gap: 4, flex: 1 }}>
                   <NomadsIcon fill={Colors.DARK_BLUE} height={20} width={20} />
                   <Text
@@ -979,7 +1046,7 @@ const EventScreen = ({ route }: { route: any }) => {
               {filteredParticipants.length > 0 ? (
                 <View style={{ gap: 8, flex: 1 }}>
                   <Text style={[styles.travelSeriesTitle, { fontSize: 12 }]}>
-                    Participants{event.participants ? ` (${event.participants})` : ''}
+                    Participants{` (${filteredParticipants.length})`}
                   </Text>
 
                   <View style={[styles.statItem, { justifyContent: 'flex-start' }]}>
@@ -1043,9 +1110,13 @@ const EventScreen = ({ route }: { route: any }) => {
                             ...([
                               NAVIGATION_PAGES.PARTICIPANTS_LIST,
                               {
-                                participants: event.participants_full_data,
+                                participants:
+                                  event.type === 4
+                                    ? event.participants_approved_full_data
+                                    : event.participants_full_data,
                                 eventId: event.id,
-                                isHost: event.settings.host_profile === +currentUserId
+                                isHost: event.settings.host_profile === +currentUserId,
+                                isTrip: event.type === 4
                               }
                             ] as never)
                           )
@@ -1063,9 +1134,97 @@ const EventScreen = ({ route }: { route: any }) => {
               )}
             </View>
 
+            {filteredInterested.length > 0 && event.type === 4 && (
+              <View>
+                <View style={{ gap: 8, flex: 1 }}>
+                  <Text style={[styles.travelSeriesTitle, { fontSize: 12 }]}>
+                    Interested{` (${filteredInterested.length})`}
+                  </Text>
+
+                  <View style={[styles.statItem, { justifyContent: 'flex-start' }]}>
+                    <View style={styles.userImageContainer}>
+                      {(filteredInterested.length > maxVisibleParticipants
+                        ? filteredInterested.slice(0, maxVisibleParticipants - 1)
+                        : filteredInterested
+                      ).map((user, index) => (
+                        <Tooltip
+                          isVisible={tooltipInterested === index}
+                          content={
+                            <TouchableOpacity
+                              onPress={() => {
+                                setTooltipInterested(null);
+                                navigation.navigate(
+                                  ...([
+                                    NAVIGATION_PAGES.PUBLIC_PROFILE_VIEW,
+                                    { userId: user.uid }
+                                  ] as never)
+                                );
+                              }}
+                            >
+                              <Text>{user.name}</Text>
+                            </TouchableOpacity>
+                          }
+                          contentStyle={{ backgroundColor: Colors.FILL_LIGHT }}
+                          placement="top"
+                          onClose={() => setTooltipInterested(null)}
+                          key={index}
+                          backgroundColor="transparent"
+                        >
+                          <TouchableOpacity
+                            style={index !== 0 ? { marginLeft: -10 } : {}}
+                            onPress={() => setTooltipInterested(index)}
+                          >
+                            {user.avatar ? (
+                              <Image
+                                key={index}
+                                source={{ uri: API_HOST + user.avatar }}
+                                style={[styles.userImage]}
+                              />
+                            ) : (
+                              <AvatarWithInitials
+                                text={
+                                  user.name?.split(' ')[0][0] + (user.name?.split(' ')[1][0] ?? '')
+                                }
+                                flag={API_HOST + user?.flag}
+                                size={28}
+                                fontSize={12}
+                                borderColor={Colors.DARK_LIGHT}
+                                borderWidth={1}
+                              />
+                            )}
+                          </TouchableOpacity>
+                        </Tooltip>
+                      ))}
+                      <TouchableOpacity
+                        style={styles.userCountContainer}
+                        onPress={() =>
+                          navigation.navigate(
+                            ...([
+                              NAVIGATION_PAGES.PARTICIPANTS_LIST,
+                              {
+                                participants: event.participants_full_data,
+                                eventId: event.id,
+                                isHost: event.settings.host_profile === +currentUserId,
+                                interested: true,
+                                isTrip: event.type === 4
+                              }
+                            ] as never)
+                          )
+                        }
+                      >
+                        <View style={styles.dots}></View>
+                        <View style={styles.dots}></View>
+                        <View style={styles.dots}></View>
+                      </TouchableOpacity>
+                    </View>
+                  </View>
+                </View>
+              </View>
+            )}
+
             {/* TO DO */}
             {event.settings.host_profile === +currentUserId &&
-            event.settings.type === 1 &&
+            (event.settings.type === 1 || event.settings.type === 4) &&
             !event.archived ? (
               <TouchableOpacity
                 style={{
@@ -1085,15 +1244,25 @@ const EventScreen = ({ route }: { route: any }) => {
                     { token, event_id: event.id },
                     {
                       onSuccess: (res) => {
-                        navigation.navigate(
-                          ...([
-                            NAVIGATION_PAGES.CREATE_EVENT,
-                            {
-                              eventId: event.id,
-                              event: res
-                            }
-                          ] as never)
-                        );
+                        event.settings.type === 4
+                          ? navigation.navigate(
+                              ...([
+                                NAVIGATION_PAGES.CREATE_SHARED_TRIP,
+                                {
+                                  eventId: event.id,
+                                  event: res
+                                }
+                              ] as never)
+                            )
+                          : navigation.navigate(
+                              ...([
+                                NAVIGATION_PAGES.CREATE_EVENT,
+                                {
+                                  eventId: event.id,
+                                  event: res
+                                }
+                              ] as never)
+                            );
                       }
                     }
                   )

+ 8 - 4
src/screens/InAppScreens/TravelsScreen/EventsScreen/index.tsx

@@ -278,10 +278,14 @@ const EventsScreen = () => {
   const formatEventDate = (event: SingleEvent) => {
     if (event.date_from && event.date_to) {
       if (event.date_tentative) {
-        return `${moment(event.date_from, 'YYYY-MM').format('MMM YYYY')} - ${moment(
-          event.date_to,
-          'YYYY-MM'
-        ).format('MMM YYYY')}`;
+        const dateFrom = moment(event.date_from, 'YYYY-MM').format('MMM YYYY');
+        const dateTo = moment(event.date_to, 'YYYY-MM').format('MMM YYYY');
+
+        if (dateFrom === dateTo) {
+          return dateFrom;
+        }
+
+        return `${dateFrom} - ${dateTo}`;
       }
       return `${moment(event.date_from, 'YYYY-MM-DD').format('DD MMM YYYY')} - ${moment(event.date_to, 'YYYY-MM-DD').format('DD MMM YYYY')}`;
     } else {

+ 5 - 3
src/screens/InAppScreens/TravelsScreen/ParticipantsListScreen/index.tsx

@@ -20,7 +20,7 @@ type Props = {
 };
 
 const ParticipantsListScreen: FC<Props> = ({ navigation, route }) => {
-  const { participants, eventId, isHost } = route.params;
+  const { participants, eventId, isHost, interested, isTrip } = route.params;
   const token = storage.get('token', StoreType.STRING);
   const { data: masterCountries } = usePostGetCountriesRanking();
 
@@ -73,7 +73,9 @@ const ParticipantsListScreen: FC<Props> = ({ navigation, route }) => {
         name: user.first_name + ' ' + user.last_name,
         token,
         filterParticipants: () => handleFilterParticipants(user.user_id),
-        setIsWarningVisible: setModalState
+        setIsWarningVisible: setModalState,
+        interested: interested,
+        isTrip: isTrip
       } as any
     });
   };
@@ -81,7 +83,7 @@ const ParticipantsListScreen: FC<Props> = ({ navigation, route }) => {
   return (
     <PageWrapper>
       <Header
-        label="Participants"
+        label={interested ? 'Interested' : 'Participants'}
         rightElement={<FilterButton onPress={() => setModalVisible(!isModalVisible)} />}
       />
       <View style={styles.container}>

+ 8 - 2
src/types/api.ts

@@ -210,7 +210,10 @@ export enum API_ENDPOINT {
   GET_LAST_MAP_UPDATE_DATE = 'get-last-map-update-date',
   GET_SIZE_FOR_BOUNDING_BOX = 'get-size-for-bounding-box',
   GET_PROFILE_SERIES_DATA = 'get-profile-series-data',
-  ADD_SHARED_TRIP = 'add-shared-trip'
+  ADD_SHARED_TRIP = 'add-shared-trip',
+  UPDATE_SHARED_TRIP = 'update-shared-trip',
+  SHARED_TRIP_ADD_PARTICIPANT = 'add-participant',
+  SET_FULL = 'set-event-full'
 }
 
 export enum API {
@@ -393,7 +396,10 @@ export enum API {
   GET_LAST_MAP_UPDATE_DATE = `${API_ROUTE.MAPS}/${API_ENDPOINT.GET_LAST_MAP_UPDATE_DATE}`,
   GET_SIZE_FOR_BOUNDING_BOX = `${API_ROUTE.MAPS}/${API_ENDPOINT.GET_SIZE_FOR_BOUNDING_BOX}`,
   GET_PROFILE_SERIES_DATA = `${API_ROUTE.PROFILE}/${API_ENDPOINT.GET_PROFILE_SERIES_DATA}`,
-  ADD_SHARED_TRIP = `${API_ROUTE.EVENTS}/${API_ENDPOINT.ADD_SHARED_TRIP}`
+  ADD_SHARED_TRIP = `${API_ROUTE.EVENTS}/${API_ENDPOINT.ADD_SHARED_TRIP}`,
+  UPDATE_SHARED_TRIP = `${API_ROUTE.EVENTS}/${API_ENDPOINT.UPDATE_SHARED_TRIP}`,
+  SHARED_TRIP_ADD_PARTICIPANT = `${API_ROUTE.EVENTS}/${API_ENDPOINT.SHARED_TRIP_ADD_PARTICIPANT}`,
+  SET_FULL = `${API_ROUTE.EVENTS}/${API_ENDPOINT.SET_FULL}`
 }
 
 export type BaseAxiosError = AxiosError;