jetsetgo_departure-selection
Version:
A reusable departure selection component for travel booking applications
1,300 lines (1,297 loc) • 47.8 kB
JavaScript
import ze, { useState as G, useEffect as Be } from "react";
import { motion as M, AnimatePresence as He } from "framer-motion";
import { AlertCircle as Rt, AlertTriangle as Tt, Check as St, ChevronDown as Xe, ChevronLeft as Et, Calendar as Nt, ChevronRight as Dt } from "lucide-react";
import { clsx as Ct } from "clsx";
import { twMerge as Ot } from "tailwind-merge";
import { format as Ne, subDays as kt, addDays as Ze } from "date-fns";
import { create as Pt } from "zustand";
var De = { exports: {} }, ce = {};
/**
* @license React
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var qe;
function It() {
if (qe) return ce;
qe = 1;
var n = ze, c = Symbol.for("react.element"), o = Symbol.for("react.fragment"), u = Object.prototype.hasOwnProperty, i = n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, s = { key: !0, ref: !0, __self: !0, __source: !0 };
function x(g, b, N) {
var w, S = {}, k = null, Y = null;
N !== void 0 && (k = "" + N), b.key !== void 0 && (k = "" + b.key), b.ref !== void 0 && (Y = b.ref);
for (w in b) u.call(b, w) && !s.hasOwnProperty(w) && (S[w] = b[w]);
if (g && g.defaultProps) for (w in b = g.defaultProps, b) S[w] === void 0 && (S[w] = b[w]);
return { $$typeof: c, type: g, key: k, ref: Y, props: S, _owner: i.current };
}
return ce.Fragment = o, ce.jsx = x, ce.jsxs = x, ce;
}
var ue = {};
/**
* @license React
* react-jsx-runtime.development.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
var Je;
function Ft() {
return Je || (Je = 1, process.env.NODE_ENV !== "production" && function() {
var n = ze, c = Symbol.for("react.element"), o = Symbol.for("react.portal"), u = Symbol.for("react.fragment"), i = Symbol.for("react.strict_mode"), s = Symbol.for("react.profiler"), x = Symbol.for("react.provider"), g = Symbol.for("react.context"), b = Symbol.for("react.forward_ref"), N = Symbol.for("react.suspense"), w = Symbol.for("react.suspense_list"), S = Symbol.for("react.memo"), k = Symbol.for("react.lazy"), Y = Symbol.for("react.offscreen"), V = Symbol.iterator, D = "@@iterator";
function ge(e) {
if (e === null || typeof e != "object")
return null;
var r = V && e[V] || e[D];
return typeof r == "function" ? r : null;
}
var U = n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
function _(e) {
{
for (var r = arguments.length, a = new Array(r > 1 ? r - 1 : 0), l = 1; l < r; l++)
a[l - 1] = arguments[l];
P("error", e, a);
}
}
function P(e, r, a) {
{
var l = U.ReactDebugCurrentFrame, m = l.getStackAddendum();
m !== "" && (r += "%s", a = a.concat([m]));
var h = a.map(function(f) {
return String(f);
});
h.unshift("Warning: " + r), Function.prototype.apply.call(console[e], console, h);
}
}
var be = !1, F = !1, de = !1, L = !1, ne = !1, ee;
ee = Symbol.for("react.module.reference");
function ye(e) {
return !!(typeof e == "string" || typeof e == "function" || e === u || e === s || ne || e === i || e === N || e === w || L || e === Y || be || F || de || typeof e == "object" && e !== null && (e.$$typeof === k || e.$$typeof === S || e.$$typeof === x || e.$$typeof === g || e.$$typeof === b || // This needs to include all possible module reference object
// types supported by any Flight configuration anywhere since
// we don't know which Flight build this will end up being used
// with.
e.$$typeof === ee || e.getModuleId !== void 0));
}
function B(e, r, a) {
var l = e.displayName;
if (l)
return l;
var m = r.displayName || r.name || "";
return m !== "" ? a + "(" + m + ")" : a;
}
function ae(e) {
return e.displayName || "Context";
}
function C(e) {
if (e == null)
return null;
if (typeof e.tag == "number" && _("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."), typeof e == "function")
return e.displayName || e.name || null;
if (typeof e == "string")
return e;
switch (e) {
case u:
return "Fragment";
case o:
return "Portal";
case s:
return "Profiler";
case i:
return "StrictMode";
case N:
return "Suspense";
case w:
return "SuspenseList";
}
if (typeof e == "object")
switch (e.$$typeof) {
case g:
var r = e;
return ae(r) + ".Consumer";
case x:
var a = e;
return ae(a._context) + ".Provider";
case b:
return B(e, e.render, "ForwardRef");
case S:
var l = e.displayName || null;
return l !== null ? l : C(e.type) || "Memo";
case k: {
var m = e, h = m._payload, f = m._init;
try {
return C(f(h));
} catch {
return null;
}
}
}
return null;
}
var A = Object.assign, $ = 0, fe, ie, W, R, z, H, me;
function pe() {
}
pe.__reactDisabledLog = !0;
function je() {
{
if ($ === 0) {
fe = console.log, ie = console.info, W = console.warn, R = console.error, z = console.group, H = console.groupCollapsed, me = console.groupEnd;
var e = {
configurable: !0,
enumerable: !0,
value: pe,
writable: !0
};
Object.defineProperties(console, {
info: e,
log: e,
warn: e,
error: e,
group: e,
groupCollapsed: e,
groupEnd: e
});
}
$++;
}
}
function _e() {
{
if ($--, $ === 0) {
var e = {
configurable: !0,
enumerable: !0,
writable: !0
};
Object.defineProperties(console, {
log: A({}, e, {
value: fe
}),
info: A({}, e, {
value: ie
}),
warn: A({}, e, {
value: W
}),
error: A({}, e, {
value: R
}),
group: A({}, e, {
value: z
}),
groupCollapsed: A({}, e, {
value: H
}),
groupEnd: A({}, e, {
value: me
})
});
}
$ < 0 && _("disabledDepth fell below zero. This is a bug in React. Please file an issue.");
}
}
var se = U.ReactCurrentDispatcher, oe;
function X(e, r, a) {
{
if (oe === void 0)
try {
throw Error();
} catch (m) {
var l = m.stack.trim().match(/\n( *(at )?)/);
oe = l && l[1] || "";
}
return `
` + oe + e;
}
}
var q = !1, p;
{
var j = typeof WeakMap == "function" ? WeakMap : Map;
p = new j();
}
function J(e, r) {
if (!e || q)
return "";
{
var a = p.get(e);
if (a !== void 0)
return a;
}
var l;
q = !0;
var m = Error.prepareStackTrace;
Error.prepareStackTrace = void 0;
var h;
h = se.current, se.current = null, je();
try {
if (r) {
var f = function() {
throw Error();
};
if (Object.defineProperty(f.prototype, "props", {
set: function() {
throw Error();
}
}), typeof Reflect == "object" && Reflect.construct) {
try {
Reflect.construct(f, []);
} catch (E) {
l = E;
}
Reflect.construct(e, [], f);
} else {
try {
f.call();
} catch (E) {
l = E;
}
e.call(f.prototype);
}
} else {
try {
throw Error();
} catch (E) {
l = E;
}
e();
}
} catch (E) {
if (E && l && typeof E.stack == "string") {
for (var d = E.stack.split(`
`), T = l.stack.split(`
`), v = d.length - 1, y = T.length - 1; v >= 1 && y >= 0 && d[v] !== T[y]; )
y--;
for (; v >= 1 && y >= 0; v--, y--)
if (d[v] !== T[y]) {
if (v !== 1 || y !== 1)
do
if (v--, y--, y < 0 || d[v] !== T[y]) {
var I = `
` + d[v].replace(" at new ", " at ");
return e.displayName && I.includes("<anonymous>") && (I = I.replace("<anonymous>", e.displayName)), typeof e == "function" && p.set(e, I), I;
}
while (v >= 1 && y >= 0);
break;
}
}
} finally {
q = !1, se.current = h, _e(), Error.prepareStackTrace = m;
}
var re = e ? e.displayName || e.name : "", Q = re ? X(re) : "";
return typeof e == "function" && p.set(e, Q), Q;
}
function O(e, r, a) {
return J(e, !1);
}
function Z(e) {
var r = e.prototype;
return !!(r && r.isReactComponent);
}
function xe(e, r, a) {
if (e == null)
return "";
if (typeof e == "function")
return J(e, Z(e));
if (typeof e == "string")
return X(e);
switch (e) {
case N:
return X("Suspense");
case w:
return X("SuspenseList");
}
if (typeof e == "object")
switch (e.$$typeof) {
case b:
return O(e.render);
case S:
return xe(e.type, r, a);
case k: {
var l = e, m = l._payload, h = l._init;
try {
return xe(h(m), r, a);
} catch {
}
}
}
return "";
}
var le = Object.prototype.hasOwnProperty, Ce = {}, Oe = U.ReactDebugCurrentFrame;
function he(e) {
if (e) {
var r = e._owner, a = xe(e.type, e._source, r ? r.type : null);
Oe.setExtraStackFrame(a);
} else
Oe.setExtraStackFrame(null);
}
function rt(e, r, a, l, m) {
{
var h = Function.call.bind(le);
for (var f in e)
if (h(e, f)) {
var d = void 0;
try {
if (typeof e[f] != "function") {
var T = Error((l || "React class") + ": " + a + " type `" + f + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof e[f] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.");
throw T.name = "Invariant Violation", T;
}
d = e[f](r, f, l, a, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED");
} catch (v) {
d = v;
}
d && !(d instanceof Error) && (he(m), _("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", l || "React class", a, f, typeof d), he(null)), d instanceof Error && !(d.message in Ce) && (Ce[d.message] = !0, he(m), _("Failed %s type: %s", a, d.message), he(null));
}
}
}
var nt = Array.isArray;
function we(e) {
return nt(e);
}
function at(e) {
{
var r = typeof Symbol == "function" && Symbol.toStringTag, a = r && e[Symbol.toStringTag] || e.constructor.name || "Object";
return a;
}
}
function it(e) {
try {
return ke(e), !1;
} catch {
return !0;
}
}
function ke(e) {
return "" + e;
}
function Pe(e) {
if (it(e))
return _("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", at(e)), ke(e);
}
var Ie = U.ReactCurrentOwner, st = {
key: !0,
ref: !0,
__self: !0,
__source: !0
}, Fe, Ae;
function ot(e) {
if (le.call(e, "ref")) {
var r = Object.getOwnPropertyDescriptor(e, "ref").get;
if (r && r.isReactWarning)
return !1;
}
return e.ref !== void 0;
}
function lt(e) {
if (le.call(e, "key")) {
var r = Object.getOwnPropertyDescriptor(e, "key").get;
if (r && r.isReactWarning)
return !1;
}
return e.key !== void 0;
}
function ct(e, r) {
typeof e.ref == "string" && Ie.current;
}
function ut(e, r) {
{
var a = function() {
Fe || (Fe = !0, _("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", r));
};
a.isReactWarning = !0, Object.defineProperty(e, "key", {
get: a,
configurable: !0
});
}
}
function dt(e, r) {
{
var a = function() {
Ae || (Ae = !0, _("%s: `ref` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://reactjs.org/link/special-props)", r));
};
a.isReactWarning = !0, Object.defineProperty(e, "ref", {
get: a,
configurable: !0
});
}
}
var ft = function(e, r, a, l, m, h, f) {
var d = {
// This tag allows us to uniquely identify this as a React Element
$$typeof: c,
// Built-in properties that belong on the element
type: e,
key: r,
ref: a,
props: f,
// Record the component responsible for creating this element.
_owner: h
};
return d._store = {}, Object.defineProperty(d._store, "validated", {
configurable: !1,
enumerable: !1,
writable: !0,
value: !1
}), Object.defineProperty(d, "_self", {
configurable: !1,
enumerable: !1,
writable: !1,
value: l
}), Object.defineProperty(d, "_source", {
configurable: !1,
enumerable: !1,
writable: !1,
value: m
}), Object.freeze && (Object.freeze(d.props), Object.freeze(d)), d;
};
function mt(e, r, a, l, m) {
{
var h, f = {}, d = null, T = null;
a !== void 0 && (Pe(a), d = "" + a), lt(r) && (Pe(r.key), d = "" + r.key), ot(r) && (T = r.ref, ct(r, m));
for (h in r)
le.call(r, h) && !st.hasOwnProperty(h) && (f[h] = r[h]);
if (e && e.defaultProps) {
var v = e.defaultProps;
for (h in v)
f[h] === void 0 && (f[h] = v[h]);
}
if (d || T) {
var y = typeof e == "function" ? e.displayName || e.name || "Unknown" : e;
d && ut(f, y), T && dt(f, y);
}
return ft(e, d, T, m, l, Ie.current, f);
}
}
var Re = U.ReactCurrentOwner, $e = U.ReactDebugCurrentFrame;
function te(e) {
if (e) {
var r = e._owner, a = xe(e.type, e._source, r ? r.type : null);
$e.setExtraStackFrame(a);
} else
$e.setExtraStackFrame(null);
}
var Te;
Te = !1;
function Se(e) {
return typeof e == "object" && e !== null && e.$$typeof === c;
}
function We() {
{
if (Re.current) {
var e = C(Re.current.type);
if (e)
return `
Check the render method of \`` + e + "`.";
}
return "";
}
}
function pt(e) {
return "";
}
var Ue = {};
function xt(e) {
{
var r = We();
if (!r) {
var a = typeof e == "string" ? e : e.displayName || e.name;
a && (r = `
Check the top-level render call using <` + a + ">.");
}
return r;
}
}
function Le(e, r) {
{
if (!e._store || e._store.validated || e.key != null)
return;
e._store.validated = !0;
var a = xt(r);
if (Ue[a])
return;
Ue[a] = !0;
var l = "";
e && e._owner && e._owner !== Re.current && (l = " It was passed a child from " + C(e._owner.type) + "."), te(e), _('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.', a, l), te(null);
}
}
function Me(e, r) {
{
if (typeof e != "object")
return;
if (we(e))
for (var a = 0; a < e.length; a++) {
var l = e[a];
Se(l) && Le(l, r);
}
else if (Se(e))
e._store && (e._store.validated = !0);
else if (e) {
var m = ge(e);
if (typeof m == "function" && m !== e.entries)
for (var h = m.call(e), f; !(f = h.next()).done; )
Se(f.value) && Le(f.value, r);
}
}
}
function ht(e) {
{
var r = e.type;
if (r == null || typeof r == "string")
return;
var a;
if (typeof r == "function")
a = r.propTypes;
else if (typeof r == "object" && (r.$$typeof === b || // Note: Memo only checks outer props here.
// Inner props are checked in the reconciler.
r.$$typeof === S))
a = r.propTypes;
else
return;
if (a) {
var l = C(r);
rt(a, e.props, "prop", l, e);
} else if (r.PropTypes !== void 0 && !Te) {
Te = !0;
var m = C(r);
_("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", m || "Unknown");
}
typeof r.getDefaultProps == "function" && !r.getDefaultProps.isReactClassApproved && _("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead.");
}
}
function vt(e) {
{
for (var r = Object.keys(e.props), a = 0; a < r.length; a++) {
var l = r[a];
if (l !== "children" && l !== "key") {
te(e), _("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", l), te(null);
break;
}
}
e.ref !== null && (te(e), _("Invalid attribute `ref` supplied to `React.Fragment`."), te(null));
}
}
var Ye = {};
function Ve(e, r, a, l, m, h) {
{
var f = ye(e);
if (!f) {
var d = "";
(e === void 0 || typeof e == "object" && e !== null && Object.keys(e).length === 0) && (d += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.");
var T = pt();
T ? d += T : d += We();
var v;
e === null ? v = "null" : we(e) ? v = "array" : e !== void 0 && e.$$typeof === c ? (v = "<" + (C(e.type) || "Unknown") + " />", d = " Did you accidentally export a JSX literal instead of a component?") : v = typeof e, _("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", v, d);
}
var y = mt(e, r, a, m, h);
if (y == null)
return y;
if (f) {
var I = r.children;
if (I !== void 0)
if (l)
if (we(I)) {
for (var re = 0; re < I.length; re++)
Me(I[re], e);
Object.freeze && Object.freeze(I);
} else
_("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");
else
Me(I, e);
}
if (le.call(r, "key")) {
var Q = C(e), E = Object.keys(r).filter(function(wt) {
return wt !== "key";
}), Ee = E.length > 0 ? "{key: someKey, " + E.join(": ..., ") + ": ...}" : "{key: someKey}";
if (!Ye[Q + Ee]) {
var _t = E.length > 0 ? "{" + E.join(": ..., ") + ": ...}" : "{}";
_(`A props object containing a "key" prop is being spread into JSX:
let props = %s;
<%s {...props} />
React keys must be passed directly to JSX without using spread:
let props = %s;
<%s key={someKey} {...props} />`, Ee, Q, _t, Q), Ye[Q + Ee] = !0;
}
}
return e === u ? vt(y) : ht(y), y;
}
}
function gt(e, r, a) {
return Ve(e, r, a, !0);
}
function bt(e, r, a) {
return Ve(e, r, a, !1);
}
var yt = bt, jt = gt;
ue.Fragment = u, ue.jsx = yt, ue.jsxs = jt;
}()), ue;
}
process.env.NODE_ENV === "production" ? De.exports = It() : De.exports = Ft();
var t = De.exports;
function K(...n) {
return Ot(Ct(n));
}
function Qe({
departureTime: n,
arrivalTime: c,
departureLocation: o,
arrivalLocation: u
}) {
const i = Ne(/* @__PURE__ */ new Date(`2000-01-01T${n}`), "h:mm a"), s = Ne(/* @__PURE__ */ new Date(`2000-01-01T${c}`), "h:mm a");
return /* @__PURE__ */ t.jsxs("div", { className: "relative flex items-stretch gap-3", children: [
/* @__PURE__ */ t.jsxs("div", { className: "flex flex-col items-center", children: [
/* @__PURE__ */ t.jsx("div", { className: "relative top-[0.6rem]", children: /* @__PURE__ */ t.jsx("div", { className: "w-2.5 h-2.5 rounded-full bg-blue-500" }) }),
/* @__PURE__ */ t.jsx("div", { className: "w-0.5 bg-blue-200 flex-1 my-1.5" }),
/* @__PURE__ */ t.jsx("div", { className: "relative bottom-[0.6rem]", children: /* @__PURE__ */ t.jsx("div", { className: "w-2.5 h-2.5 rounded-full border-2 border-blue-500" }) })
] }),
/* @__PURE__ */ t.jsxs("div", { className: "flex-1 py-0.5", children: [
/* @__PURE__ */ t.jsxs("div", { className: "mb-4", children: [
/* @__PURE__ */ t.jsx("div", { className: "text-lg font-semibold leading-tight", children: i }),
/* @__PURE__ */ t.jsx("div", { className: "text-sm text-gray-600", children: o })
] }),
/* @__PURE__ */ t.jsxs("div", { children: [
/* @__PURE__ */ t.jsx("div", { className: "text-lg font-semibold leading-tight", children: s }),
/* @__PURE__ */ t.jsx("div", { className: "text-sm text-gray-600", children: u })
] })
] })
] });
}
function et({ flags: n }) {
return n.length === 0 ? null : /* @__PURE__ */ t.jsx("div", { className: "mt-4 flex flex-wrap gap-2", children: n.map((c, o) => /* @__PURE__ */ t.jsxs(
"span",
{
className: "inline-flex items-center gap-1 px-2 py-1 bg-amber-50 text-amber-700 rounded-full text-xs font-medium",
children: [
/* @__PURE__ */ t.jsx(Rt, { className: "h-3 w-3" }),
c.flag_name
]
},
o
)) });
}
function At({ pats: n, totalCost: c, isExpanded: o }) {
if (!o) return null;
const u = n.reduce((i, s) => {
const x = `${s.pat_type_name}-${s.pat_sub_type_name}`;
return i[x] || (i[x] = {
type: s.pat_type_name,
subType: s.pat_sub_type_name,
plural: s.pat_sub_type_plural,
count: 0,
price: 0
}), i[x].count += s.count, i[x].price += s.price, i;
}, {});
return /* @__PURE__ */ t.jsx(
M.div,
{
initial: { height: 0, opacity: 0 },
animate: { height: "auto", opacity: 1 },
className: "border-t border-gray-100 bg-gray-50",
children: /* @__PURE__ */ t.jsxs("div", { className: "p-4 space-y-3", children: [
/* @__PURE__ */ t.jsx("h4", { className: "font-medium text-gray-900", children: "Fare Breakdown" }),
/* @__PURE__ */ t.jsxs("div", { className: "space-y-2", children: [
Object.values(u).map((i, s) => /* @__PURE__ */ t.jsxs("div", { className: "flex justify-between text-sm", children: [
/* @__PURE__ */ t.jsxs("span", { className: "text-gray-600", children: [
i.count,
" x ",
i.count === 1 ? i.subType : i.plural
] }),
/* @__PURE__ */ t.jsxs("span", { className: "font-medium", children: [
"$",
i.price.toFixed(2)
] })
] }, s)),
/* @__PURE__ */ t.jsxs("div", { className: "pt-2 border-t border-gray-200 flex justify-between font-medium", children: [
/* @__PURE__ */ t.jsx("span", { children: "Total" }),
/* @__PURE__ */ t.jsxs("span", { className: "text-blue-600", children: [
"$",
c.toFixed(2)
] })
] })
] })
] })
}
);
}
function $t({
service: n,
isSelected: c,
isExpanded: o,
onSelect: u,
onToggleExpand: i,
disabled: s
}) {
const x = n.can_accept !== "yes";
return /* @__PURE__ */ t.jsxs(
M.div,
{
className: K(
"bg-white rounded-lg border transition-all duration-200 overflow-hidden",
c ? "border-green-500 shadow-lg" : "border-gray-200",
x && "opacity-75",
s && "opacity-50 cursor-not-allowed"
),
layout: !0,
children: [
/* @__PURE__ */ t.jsx("div", { className: "p-4", children: /* @__PURE__ */ t.jsxs(
"div",
{
className: K(
"flex items-start justify-between gap-4",
!x && !s && "cursor-pointer"
),
onClick: () => !x && !s && u(),
children: [
/* @__PURE__ */ t.jsxs("div", { className: "flex-1", children: [
/* @__PURE__ */ t.jsx(
Qe,
{
departureTime: n.departure_time,
arrivalTime: n.arrival_time,
departureLocation: n.departing_from,
arrivalLocation: n.travelling_to
}
),
/* @__PURE__ */ t.jsxs("div", { className: "flex flex-wrap gap-2 mt-4", children: [
x && /* @__PURE__ */ t.jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-1 bg-red-50 text-red-700 rounded-full text-xs font-medium", children: [
/* @__PURE__ */ t.jsx(Tt, { className: "h-3 w-3" }),
"Unavailable"
] }),
/* @__PURE__ */ t.jsx(et, { flags: n.flags })
] })
] }),
/* @__PURE__ */ t.jsxs("div", { className: "text-right", children: [
/* @__PURE__ */ t.jsxs("div", { className: K(
"flex items-center gap-2 text-2xl font-bold",
c ? "text-green-600" : "text-blue-600",
x && "text-gray-400"
), children: [
c && /* @__PURE__ */ t.jsx(St, { className: "h-5 w-5" }),
"$",
n.total_cost.toFixed(2)
] }),
/* @__PURE__ */ t.jsxs(
"button",
{
onClick: (g) => {
g.stopPropagation(), i();
},
className: "mt-2 text-sm font-medium text-gray-500 hover:text-gray-700 flex items-center gap-1 ml-auto",
children: [
o ? "Hide" : "Show",
" details",
/* @__PURE__ */ t.jsx(Xe, { className: K(
"h-4 w-4 transition-transform",
o && "rotate-180"
) })
]
}
)
] })
]
}
) }),
/* @__PURE__ */ t.jsx(
At,
{
pats: n.pats,
totalCost: n.total_cost,
isExpanded: o
}
)
]
}
);
}
function Ge({ services: n, selectedId: c, onSelect: o, title: u, isLoading: i }) {
const [s, x] = G(null);
return n.length === 0 ? null : /* @__PURE__ */ t.jsxs(
M.div,
{
className: "space-y-4",
animate: { opacity: i ? 0.5 : 1 },
transition: { duration: 0.2 },
children: [
/* @__PURE__ */ t.jsx("h3", { className: "text-xl font-semibold text-gray-900", children: u }),
/* @__PURE__ */ t.jsx("div", { className: "space-y-4", children: /* @__PURE__ */ t.jsx(He, { mode: "wait", children: n.map((g) => /* @__PURE__ */ t.jsx(
$t,
{
service: g,
isSelected: g.service_id === c,
isExpanded: g.service_id === s,
onSelect: () => !i && o(g.service_id),
onToggleExpand: () => {
x(
g.service_id === s ? null : g.service_id
);
},
disabled: i
},
g.service_id
)) }) })
]
}
);
}
function Wt({ dates: n, selectedDate: c, onSelect: o, onNavigate: u }) {
return /* @__PURE__ */ t.jsx("div", { className: "flex flex-col items-center gap-4 mb-8", children: /* @__PURE__ */ t.jsxs("div", { className: "flex items-center gap-4", children: [
/* @__PURE__ */ t.jsx(
"button",
{
onClick: () => u("backward"),
className: "p-2 hover:bg-gray-100 rounded-full transition-colors",
children: /* @__PURE__ */ t.jsx(Et, { className: "h-5 w-5 text-gray-600" })
}
),
/* @__PURE__ */ t.jsx("div", { className: "flex items-center gap-4 no-scrollbar", children: n.map((i) => /* @__PURE__ */ t.jsxs(
M.button,
{
whileHover: { scale: 1.02 },
whileTap: { scale: 0.98 },
onClick: () => o(i),
className: K(
"flex flex-col items-center min-w-[140px] px-4 py-3 rounded-lg transition-all",
c === i ? "bg-blue-500 text-white shadow-lg shadow-blue-500/20" : "bg-white border border-gray-200 hover:border-blue-200 text-gray-900"
),
children: [
/* @__PURE__ */ t.jsx(Nt, { className: K(
"h-5 w-5 mb-1",
c === i ? "text-white" : "text-blue-500"
) }),
/* @__PURE__ */ t.jsx("span", { className: "text-sm font-medium whitespace-nowrap", children: Ne(new Date(i), "EEE, d MMM") })
]
},
i
)) }),
/* @__PURE__ */ t.jsx(
"button",
{
onClick: () => u("forward"),
className: "p-2 hover:bg-gray-100 rounded-full transition-colors",
children: /* @__PURE__ */ t.jsx(Dt, { className: "h-5 w-5 text-gray-600" })
}
)
] }) });
}
function Ut({
sortBy: n,
onSortChange: c,
showUnavailable: o,
onToggleUnavailable: u
}) {
return /* @__PURE__ */ t.jsxs("div", { className: "flex items-center justify-between px-6 py-4 bg-white border border-gray-200 rounded-lg mb-6", children: [
/* @__PURE__ */ t.jsxs("div", { className: "flex items-center gap-3", children: [
/* @__PURE__ */ t.jsx("label", { className: "text-sm font-medium text-gray-700", children: "Sort by:" }),
/* @__PURE__ */ t.jsxs("div", { className: "relative", children: [
/* @__PURE__ */ t.jsxs(
"select",
{
value: n,
onChange: (i) => c(i.target.value),
className: "appearance-none bg-white border border-gray-200 rounded-lg pl-4 pr-10 py-2 text-sm font-medium text-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
children: [
/* @__PURE__ */ t.jsx("option", { value: "departure", children: "Departure time" }),
/* @__PURE__ */ t.jsx("option", { value: "price", children: "Price" })
]
}
),
/* @__PURE__ */ t.jsx(Xe, { className: "absolute right-3 top-1/2 -translate-y-1/2 h-4 w-4 text-gray-400 pointer-events-none" })
] })
] }),
/* @__PURE__ */ t.jsxs("div", { className: "flex items-center gap-3", children: [
/* @__PURE__ */ t.jsx("span", { className: "text-sm text-gray-600", children: "Show unavailable ferries" }),
/* @__PURE__ */ t.jsx(
"button",
{
onClick: u,
className: K(
"w-12 h-6 rounded-full transition-colors relative",
o ? "bg-blue-500" : "bg-gray-200"
),
children: /* @__PURE__ */ t.jsx("div", { className: K(
"absolute top-1 w-4 h-4 rounded-full bg-white transition-all",
o ? "right-1" : "left-1"
) })
}
)
] })
] });
}
function Lt({ service: n, title: c }) {
return /* @__PURE__ */ t.jsxs(
M.div,
{
initial: { opacity: 0, height: 0 },
animate: { opacity: 1, height: "auto" },
exit: { opacity: 0, height: 0 },
className: "bg-blue-50 rounded-lg border border-blue-100 p-4 mb-6",
children: [
/* @__PURE__ */ t.jsx("h4", { className: "text-sm font-medium text-blue-700 mb-3", children: c }),
/* @__PURE__ */ t.jsxs("div", { className: "bg-white rounded-lg p-4 border border-blue-100", children: [
/* @__PURE__ */ t.jsx(
Qe,
{
departureTime: n.departure_time,
arrivalTime: n.arrival_time,
departureLocation: n.departing_from,
arrivalLocation: n.travelling_to
}
),
/* @__PURE__ */ t.jsx(et, { flags: n.flags }),
/* @__PURE__ */ t.jsx("div", { className: "mt-3 text-right", children: /* @__PURE__ */ t.jsxs("span", { className: "text-lg font-semibold text-blue-600", children: [
"$",
n.total_cost.toFixed(2)
] }) })
] })
]
}
);
}
function Mt(n) {
if (console.log("getDefaultDate input:", {
servicesCount: n == null ? void 0 : n.length,
firstService: n == null ? void 0 : n[0],
allDates: n == null ? void 0 : n.map((s) => s.departure_date)
}), !n || !Array.isArray(n) || n.length === 0)
return console.warn("No valid departure services provided, using current date"), (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
const c = n.filter((s) => {
const x = (s == null ? void 0 : s.departure_date) && !isNaN(new Date(s.departure_date).getTime());
return x || console.warn("Invalid departure_date found:", s == null ? void 0 : s.departure_date), x;
});
if (c.length === 0)
return console.warn("No services with valid dates found, using current date"), (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
const u = [...c].sort((s, x) => new Date(s.departure_date).getTime() - new Date(x.departure_date).getTime())[0], i = u.departure_date;
return console.log("Date selection:", {
validDatesCount: c.length,
allValidDates: c.map((s) => s.departure_date),
selectedDate: i,
firstDepartureService: u
}), i;
}
function Yt(n, c = 1) {
const o = [], u = new Date(n);
for (let i = c; i > 0; i--) {
const s = kt(u, i);
o.push(s.toISOString().split("T")[0]);
}
o.push(n);
for (let i = 1; i <= c; i++) {
const s = Ze(u, i);
o.push(s.toISOString().split("T")[0]);
}
return o;
}
function Vt(n, c) {
const o = c === "forward" ? 1 : -1;
return n.map((u) => Ze(new Date(u), o).toISOString().split("T")[0]);
}
function ve(n) {
return (/* @__PURE__ */ new Date(`1970-01-01T${n}`)).getTime();
}
function Ke(n, c) {
return [...n].sort((o, u) => {
switch (c) {
case "departure":
return ve(o.departure_time) - ve(u.departure_time);
case "price":
const i = o.total_cost - u.total_cost;
return i === 0 ? ve(o.departure_time) - ve(u.departure_time) : i;
default:
return 0;
}
});
}
function tt(n, c) {
return c ? n : n.filter((o) => o.can_accept === "yes");
}
function Bt(n, c, o) {
let u = tt(n, c);
if (o) {
const i = (/* @__PURE__ */ new Date(`1970-01-01T${o}`)).getTime();
u = u.filter((s) => (/* @__PURE__ */ new Date(`1970-01-01T${s.departure_time}`)).getTime() > i);
}
return u;
}
const qt = {
selectedDepartureId: null,
selectedReturnId: null,
departureService: null,
returnService: null,
date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
totalCost: 0
}, Jt = Pt((n, c) => ({
selections: {},
setSelections: (o, u) => n((i) => ({
selections: {
...i.selections,
[o]: u
}
})),
getSelections: (o) => c().selections[o] || { ...qt },
clearSelections: (o) => n((u) => {
const { [o]: i, ...s } = u.selections;
return { selections: s };
})
}));
function er({
initialData: n,
onComplete: c,
onBack: o,
uiConfig: u,
selectedOutboundId: i,
selectedReturnId: s,
currentContext: x,
onDateSelect: g,
onServiceSelect: b,
onContextChange: N,
isLoading: w = !1,
loadingContext: S = "both",
requested_date: k
}) {
if (console.log("[DEBUG] DepartureSelection render"), !n)
return console.error("DepartureSelection requires initialData"), null;
const { departure: Y, return: V } = n, D = u, { getSelections: ge, setSelections: U } = Jt(), _ = ge("departure-selection-1"), [P, be] = G(
i !== void 0 ? i : _.selectedDepartureId
), [F, de] = G(
s !== void 0 ? s : _.selectedReturnId
), [L, ne] = G(
x === "return"
), [ee, ye] = G("departure"), [B, ae] = G(""), [C, A] = G([]), [$, fe] = G(!1);
Be(() => {
const p = L ? V : Y;
let j;
k && (j = k, console.log("Using requested_date from parent prop:", j));
const J = j && /^\d{4}-\d{2}-\d{2}$/.test(j);
let O = "";
J ? (O = j, console.log("Initial date set from requested_date:", O)) : p && p.length > 0 ? (O = Mt(p), console.log("Initial date set from getDefaultDate:", O)) : (O = (/* @__PURE__ */ new Date()).toISOString().split("T")[0], console.log("Initial date defaulted to today:", O)), ae(O);
let Z = Yt(O);
(!Z || Z.length === 0) && (console.warn("generateDateRange returned empty, defaulting to [initialDate]", { initialDate: O }), Z = [O]), A(Z), console.log("Date initialization:", { initialDate: O, dateRange: Z });
}, [Y, V, L, k]);
const ie = V && V.length > 0, W = tt(Ke(Y, ee), $), R = W.find((p) => p.service_id === P), z = Bt(
Ke(V, ee),
$,
R == null ? void 0 : R.departure_time
), H = z.find((p) => p.service_id === F);
Be(() => {
N && N({
previousContext: x || "outbound",
nextContext: L ? "return" : "outbound",
selectedOutboundId: P,
selectedReturnId: F
});
}, [L, P, F]);
const me = (p) => {
const j = Vt(C, p);
A(j);
}, pe = (p) => {
g && g({
date: p,
previousDate: B,
context: L ? "return" : "outbound"
}), ae(p);
}, je = (p) => {
const j = W.find((J) => J.service_id === p);
j && (be(p), de(null), ne(!1), b && b({
serviceId: p,
context: "outbound",
service: j
}), U("departure-selection-1", {
selectedDepartureId: p,
selectedReturnId: null,
departureService: j,
returnService: null,
date: B,
totalCost: j.total_cost
}));
}, _e = (p) => {
const j = z.find((J) => J.service_id === p);
!j || !R || (de(p), b && b({
serviceId: p,
context: "return",
service: j
}), U("departure-selection-1", {
selectedDepartureId: R.service_id,
selectedReturnId: p,
departureService: R,
returnService: j,
date: B,
totalCost: R.total_cost + j.total_cost
}));
}, se = () => {
N && N({
previousContext: "outbound",
nextContext: "return",
selectedOutboundId: P,
selectedReturnId: F
}), ne(!0);
}, oe = () => {
N && N({
previousContext: "return",
nextContext: "outbound",
selectedOutboundId: P,
selectedReturnId: F
}), ne(!1);
}, X = () => {
if (!R) return;
const p = {
selectedDepartureId: P,
selectedReturnId: F,
departureService: R,
returnService: H || null,
date: B,
totalCost: ((R == null ? void 0 : R.total_cost) || 0) + ((H == null ? void 0 : H.total_cost) || 0)
};
c(p);
}, q = B || k || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
return /* @__PURE__ */ t.jsx("div", { className: "container max-w-3xl mx-auto py-12 px-4", children: /* @__PURE__ */ t.jsxs(
M.div,
{
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
className: "space-y-8 relative",
children: [
w && /* @__PURE__ */ t.jsx("div", { className: "absolute inset-0 bg-white/80 flex items-center justify-center z-50 rounded-xl", children: /* @__PURE__ */ t.jsxs("div", { className: "text-center", children: [
/* @__PURE__ */ t.jsx("div", { className: "w-12 h-12 border-4 border-blue-500 border-t-transparent rounded-full animate-spin mx-auto" }),
/* @__PURE__ */ t.jsx("p", { className: "mt-4 text-gray-700 font-medium", children: "Loading..." })
] }) }),
/* @__PURE__ */ t.jsxs("div", { className: "text-center", children: [
/* @__PURE__ */ t.jsx("h2", { className: "text-3xl font-bold text-gray-900", children: D.pageTitle }),
/* @__PURE__ */ t.jsx("p", { className: "text-gray-600 mt-2", children: D.pageSubtitle })
] }),
/* @__PURE__ */ t.jsx(
Wt,
{
dates: C.length > 0 ? C : [q],
selectedDate: q,
onSelect: pe,
onNavigate: me
}
),
/* @__PURE__ */ t.jsxs("div", { className: "bg-gray-50 rounded-xl p-6 space-y-6", children: [
/* @__PURE__ */ t.jsx(
Ut,
{
sortBy: ee,
onSortChange: ye,
showUnavailable: $,
onToggleUnavailable: () => fe(!$)
}
),
/* @__PURE__ */ t.jsx(He, { mode: "wait", children: L && R ? /* @__PURE__ */ t.jsxs(
M.div,
{
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -20 },
children: [
/* @__PURE__ */ t.jsx("div", { onClick: oe, className: "cursor-pointer", children: /* @__PURE__ */ t.jsx(
Lt,
{
service: R,
title: "Selected Outbound Journey (click to change)"
}
) }),
z.length > 0 ? /* @__PURE__ */ t.jsx(
Ge,
{
services: z,
selectedId: F,
onSelect: _e,
title: D.returnTitle,
isLoading: w && (S === "return" || S === "both")
}
) : /* @__PURE__ */ t.jsx("div", { className: "flex flex-col items-center justify-center py-12", children: /* @__PURE__ */ t.jsxs("div", { className: "bg-blue-50 border border-blue-200 rounded-xl px-6 py-8 text-center max-w-lg mx-auto", children: [
/* @__PURE__ */ t.jsxs("svg", { className: "mx-auto mb-4 h-10 w-10 text-blue-400", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: [
/* @__PURE__ */ t.jsx("circle", { cx: "12", cy: "12", r: "10" }),
/* @__PURE__ */ t.jsx("path", { d: "M12 8v4m0 4h.01" })
] }),
/* @__PURE__ */ t.jsxs("h3", { className: "text-xl font-semibold text-blue-900 mb-2", children: [
"No return journeys available on ",
q
] }),
/* @__PURE__ */ t.jsx("p", { className: "text-blue-800 mb-4", children: "We couldn't find any return journeys for your chosen date. Please use the date picker above to select another date." })
] }) })
]
},
"return-selection"
) : /* @__PURE__ */ t.jsx(
M.div,
{
initial: { opacity: 0, y: 20 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -20 },
children: (console.log("[DEBUG] Render outbound section:", {
departure: W,
departureLength: W.length,
selectedDate: B,
dates: C,
selectedDepartureId: P,
branch: W.length > 0 ? "ServiceList" : "EmptyState"
}), W.length > 0 ? /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
/* @__PURE__ */ t.jsx(
Ge,
{
services: W,
selectedId: P,
onSelect: je,
title: D.outboundTitle,
isLoading: w && (S === "outbound" || S === "both")
}
),
P && /* @__PURE__ */ t.jsx(
M.div,
{
initial: { opacity: 0 },
animate: { opacity: 1 },
className: "mt-6",
children: /* @__PURE__ */ t.jsx(
"button",
{
onClick: D.outboundButtonMode === "continue" ? se : X,
className: "w-full py-3 bg-blue-500 text-white rounded-lg font-medium hover:bg-blue-600 transition-colors",
children: D.outboundButtonMode === "continue" ? D.continueToReturnText : D.finalContinueText
}
)
}
)
] }) : /* @__PURE__ */ t.jsx("div", { className: "flex flex-col items-center justify-center py-12", children: /* @__PURE__ */ t.jsxs("div", { className: "bg-blue-50 border border-blue-200 rounded-xl px-6 py-8 text-center max-w-lg mx-auto", children: [
/* @__PURE__ */ t.jsxs("svg", { className: "mx-auto mb-4 h-10 w-10 text-blue-400", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", children: [
/* @__PURE__ */ t.jsx("circle", { cx: "12", cy: "12", r: "10" }),
/* @__PURE__ */ t.jsx("path", { d: "M12 8v4m0 4h.01" })
] }),
/* @__PURE__ */ t.jsxs("h3", { className: "text-xl font-semibold text-blue-900 mb-2", children: [
"No journeys available on ",
q
] }),
/* @__PURE__ */ t.jsx("p", { className: "text-blue-800 mb-4", children: "We couldn't find any journeys for your chosen date. Please try another date or check back soon!" })
] }) }))
},
"departure-selection"
) })
] }),
/* @__PURE__ */ t.jsxs("div", { className: "flex justify-between items-center", children: [
o && /* @__PURE__ */ t.jsx(
"button",
{
onClick: o,
className: "px-6 py-3 text-gray-600 font-medium hover:bg-gray-50 rounded-lg transition-colors",
children: L ? D.backToOutboundText : D.backText
}
),
(P && !ie || ie && F) && /* @__PURE__ */ t.jsx(
"button",
{
onClick: X,
className: "px-8 py-3 bg-blue-500 text-white font-medium rounded-lg hover:bg-blue-600 transition-colors",
children: D.finalContinueText
}
)
] })
]
}
) });
}
export {
er as DepartureSelection
};