Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
209 changes: 103 additions & 106 deletions frontend/components/ItineraryDay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import { removeInvalidTravelData, moveLocation } from "lib/itinerary";

type PropsT = {
day: Day;
dayIndex: number;
isEditing: boolean;
};

export default function ItineraryDay({ day, isEditing }: PropsT) {
export default function ItineraryDay({ day, dayIndex, isEditing }: PropsT) {
const { trip, isFetching: isFetchingTrip } = useTrip();
const { open } = useModal();

Expand Down Expand Up @@ -93,116 +94,112 @@ export default function ItineraryDay({ day, isEditing }: PropsT) {
isAddingLocation ||
isFetchingTrip;

const date = trip?.startDate ? dayjs(trip.startDate).add(dayIndex, "day").format("dddd, MMMM D") : "";
const { notes, locations } = day;

return (
<>
{trip?.itinerary?.map(({ id: dayId, notes, locations }, i) => {
const date = dayjs(trip.startDate).add(i, "day").format("dddd, MMMM D");
return (
<div key={dayId} className="mb-8">
<div className="mb-3">
<div className="flex flex-col">
<h1 className="text-xl font-bold text-gray-700">Day {i + 1}</h1>
<span className="text-gray-500 text-[13px]">{date}</span>
</div>
<InputNotesSimple
value={notes}
onBlur={(value) => setNotesMutation.mutate({ notes: value })}
className="mt-1 mb-4"
canEdit={isEditing}
/>
</div>
{!!locations?.length && (
<ul className="flex flex-col">
{locations?.map(({ locationId, type, id }, index) => {
const location =
trip?.hotspots?.find((h) => h.id === locationId) || trip?.markers?.find((m) => m.id === locationId);
<div className="mb-8">
<div className="mb-3">
<div className="flex flex-col">
<h1 className="text-xl font-bold text-gray-700">Day {dayIndex + 1}</h1>
<span className="text-gray-500 text-[13px]">{date}</span>
</div>
<InputNotesSimple
value={notes}
onBlur={(value) => setNotesMutation.mutate({ notes: value })}
className="mt-1 mb-4"
canEdit={isEditing}
/>
</div>
{!!locations?.length && (
<ul className="flex flex-col">
{locations?.map(({ locationId, type, id }, index) => {
const location =
trip?.hotspots?.find((h) => h.id === locationId) || trip?.markers?.find((m) => m.id === locationId);

return (
<React.Fragment key={id}>
{index !== 0 && (
<li>
<TravelTime isLoading={isLoading} isEditing={isEditing} dayId={dayId} id={id} />
</li>
return (
<React.Fragment key={id}>
{index !== 0 && (
<li>
<TravelTime isLoading={isLoading} isEditing={isEditing} dayId={day.id} id={id} />
</li>
)}
<li className="flex items-start gap-2 text-sm text-gray-700 group relative p-3 bg-white rounded-lg shadow">
<button
className="flex gap-2 text-left -my-[9px] py-3 -ml-4 pl-4 grow"
onClick={
location
? () =>
type === "hotspot"
? open("hotspot", { hotspot: location })
: open("viewMarker", { markerId: location.id })
: undefined
}
disabled={!location}
>
{location ? (
<MarkerWithIcon
showStroke={false}
icon={(location as any)?.icon || "hotspot"}
className="inline-block scale-[.85] flex-shrink-0 print:hidden"
/>
) : (
<Icon name="warning" className="text-red-500 text-[22px]" />
)}
<span>
<div className="truncate font-medium mt-[2px]">{location?.name || "Unknown Location"}</div>
{location?.notes && (
<span className="text-gray-700 text-sm relative group whitespace-pre-wrap">
{location.notes}
</span>
)}
</span>
</button>
{isEditing && (
<div className="flex items-center gap-1.5 ml-auto">
{index !== locations.length - 1 && (
<button
type="button"
onClick={() => moveLocationMutation.mutate({ id, direction: "down" })}
className="text-[16px] p-1 text-gray-600 sm:opacity-0 group-hover:opacity-100 transition-opacity -mt-px"
>
<Icon name="angleDownBold" />
</button>
)}
<li className="flex items-start gap-2 text-sm text-gray-700 group relative p-3 bg-white rounded-lg shadow">
{index !== 0 && (
<button
className="flex gap-2 text-left -my-[9px] py-3 -ml-4 pl-4 grow"
onClick={
location
? () =>
type === "hotspot"
? open("hotspot", { hotspot: location })
: open("viewMarker", { markerId: location.id })
: undefined
}
disabled={!location}
type="button"
onClick={() => moveLocationMutation.mutate({ id, direction: "up" })}
className="text-[16px] p-1 -mt-1 text-gray-600 sm:opacity-0 group-hover:opacity-100 transition-opacity"
>
{location ? (
<MarkerWithIcon
showStroke={false}
icon={(location as any)?.icon || "hotspot"}
className="inline-block scale-[.85] flex-shrink-0 print:hidden"
/>
) : (
<Icon name="warning" className="text-red-500 text-[22px]" />
)}
<span>
<div className="truncate font-medium mt-[2px]">{location?.name || "Unknown Location"}</div>
{location?.notes && (
<span className="text-gray-700 text-sm relative group whitespace-pre-wrap">
{location.notes}
</span>
)}
</span>
<Icon name="angleDownBold" className="rotate-180" />
</button>
{isEditing && (
<div className="flex items-center gap-1.5 ml-auto">
{index !== locations.length - 1 && (
<button
type="button"
onClick={() => moveLocationMutation.mutate({ id, direction: "down" })}
className="text-[16px] p-1 text-gray-600 sm:opacity-0 group-hover:opacity-100 transition-opacity -mt-px"
>
<Icon name="angleDownBold" />
</button>
)}
{index !== 0 && (
<button
type="button"
onClick={() => moveLocationMutation.mutate({ id, direction: "up" })}
className="text-[16px] p-1 -mt-1 text-gray-600 sm:opacity-0 group-hover:opacity-100 transition-opacity"
>
<Icon name="angleDownBold" className="rotate-180" />
</button>
)}
<button
type="button"
onClick={() => removeLocationMutation.mutate({ id })}
className="text-[16px] p-1 -mt-1 text-gray-600 sm:opacity-0 group-hover:opacity-100 transition-opacity"
>
<Icon name="xMarkBold" />
</button>
</div>
)}
</li>
</React.Fragment>
);
})}
</ul>
)}
{isEditing && (
<div className="flex justify-between items-center gap-2 mt-3">
<Button size="xs" color="gray" onClick={() => open("addItineraryLocation", { dayId })}>
+ Add Location
</Button>
<button type="button" onClick={handleRemoveDay} className="text-[12px] py-0.5 px-1.5 text-red-700">
Remove day
</button>
</div>
)}
</div>
);
})}
</>
)}
<button
type="button"
onClick={() => removeLocationMutation.mutate({ id })}
className="text-[16px] p-1 -mt-1 text-gray-600 sm:opacity-0 group-hover:opacity-100 transition-opacity"
>
<Icon name="xMarkBold" />
</button>
</div>
)}
</li>
</React.Fragment>
);
})}
</ul>
)}
{isEditing && (
<div className="flex justify-between items-center gap-2 mt-3">
<Button size="xs" color="gray" onClick={() => open("addItineraryLocation", { dayId: day.id })}>
+ Add Location
</Button>
<button type="button" onClick={handleRemoveDay} className="text-[12px] py-0.5 px-1.5 text-red-700">
Remove day
</button>
</div>
)}
</div>
);
}
2 changes: 1 addition & 1 deletion frontend/pages/[tripId]/itinerary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export default function Itinerary() {
No itinerary has been set for this trip yet.
</div>
)}
{trip?.itinerary?.map((day) => <ItineraryDay key={day.id} day={day} isEditing={isEditing} />)}
{trip?.itinerary?.map((day, index) => <ItineraryDay key={day.id} day={day} dayIndex={index} isEditing={isEditing} />)}
{isEditing && hasStartDate && (
<Button color="primary" onClick={handleAddDay} className="mb-8">
Add Day
Expand Down