@flytedan/flytebot-design-system 0.15.0 → 0.16.0
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/dist/index.cjs +191 -123
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +106 -19
- package/dist/index.d.ts +106 -19
- package/dist/index.js +190 -123
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -172,6 +172,7 @@ __export(index_exports, {
|
|
|
172
172
|
channelWeightOf: () => channelWeightOf,
|
|
173
173
|
computeNeedMore: () => computeNeedMore,
|
|
174
174
|
computeVirtualWindow: () => computeVirtualWindow,
|
|
175
|
+
createLocalStorageAppearanceStore: () => createLocalStorageAppearanceStore,
|
|
175
176
|
createVersionStore: () => createVersionStore,
|
|
176
177
|
eqFilter: () => eqFilter,
|
|
177
178
|
extensionOf: () => extensionOf,
|
|
@@ -5624,6 +5625,43 @@ function savePrefs(prefs, opts) {
|
|
|
5624
5625
|
} catch {
|
|
5625
5626
|
}
|
|
5626
5627
|
}
|
|
5628
|
+
function createLocalStorageAppearanceStore(opts) {
|
|
5629
|
+
const key = opts?.storageKey ?? DEFAULT_STORAGE_KEY;
|
|
5630
|
+
const storage = resolveStorage(opts);
|
|
5631
|
+
let snapshot = loadPrefs(opts);
|
|
5632
|
+
const listeners3 = /* @__PURE__ */ new Set();
|
|
5633
|
+
const notify = () => listeners3.forEach((l) => l());
|
|
5634
|
+
const onStorageEvent = (e) => {
|
|
5635
|
+
if (e.key !== null && e.key !== key) return;
|
|
5636
|
+
snapshot = loadPrefs(opts);
|
|
5637
|
+
notify();
|
|
5638
|
+
};
|
|
5639
|
+
return {
|
|
5640
|
+
getSnapshot: () => snapshot,
|
|
5641
|
+
write(prefs) {
|
|
5642
|
+
snapshot = prefs;
|
|
5643
|
+
if (storage) {
|
|
5644
|
+
try {
|
|
5645
|
+
storage.setItem(key, JSON.stringify(prefs));
|
|
5646
|
+
} catch {
|
|
5647
|
+
}
|
|
5648
|
+
}
|
|
5649
|
+
notify();
|
|
5650
|
+
},
|
|
5651
|
+
subscribe(onChange) {
|
|
5652
|
+
listeners3.add(onChange);
|
|
5653
|
+
if (listeners3.size === 1 && typeof window !== "undefined") {
|
|
5654
|
+
window.addEventListener("storage", onStorageEvent);
|
|
5655
|
+
}
|
|
5656
|
+
return () => {
|
|
5657
|
+
listeners3.delete(onChange);
|
|
5658
|
+
if (listeners3.size === 0 && typeof window !== "undefined") {
|
|
5659
|
+
window.removeEventListener("storage", onStorageEvent);
|
|
5660
|
+
}
|
|
5661
|
+
};
|
|
5662
|
+
}
|
|
5663
|
+
};
|
|
5664
|
+
}
|
|
5627
5665
|
function applyPrefs(prefs, root = document.documentElement) {
|
|
5628
5666
|
root.setAttribute("data-theme", resolveTheme(prefs.theme));
|
|
5629
5667
|
root.setAttribute("data-text-scale", prefs.textScale);
|
|
@@ -5632,11 +5670,10 @@ function applyPrefs(prefs, root = document.documentElement) {
|
|
|
5632
5670
|
if (prefs.reduceMotion) root.setAttribute("data-motion", "reduce");
|
|
5633
5671
|
else root.removeAttribute("data-motion");
|
|
5634
5672
|
}
|
|
5635
|
-
function useAppearancePrefs(
|
|
5636
|
-
const
|
|
5673
|
+
function useAppearancePrefs(store) {
|
|
5674
|
+
const prefs = React33.useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
5637
5675
|
React33.useEffect(() => {
|
|
5638
5676
|
applyPrefs(prefs);
|
|
5639
|
-
savePrefs(prefs, opts);
|
|
5640
5677
|
}, [prefs]);
|
|
5641
5678
|
React33.useEffect(() => {
|
|
5642
5679
|
if (prefs.theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
|
|
@@ -5647,9 +5684,12 @@ function useAppearancePrefs(opts) {
|
|
|
5647
5684
|
mq.addEventListener("change", onChange);
|
|
5648
5685
|
return () => mq.removeEventListener("change", onChange);
|
|
5649
5686
|
}, [prefs]);
|
|
5650
|
-
const update = React33.useCallback(
|
|
5651
|
-
|
|
5652
|
-
|
|
5687
|
+
const update = React33.useCallback(
|
|
5688
|
+
(patch) => {
|
|
5689
|
+
store.write({ ...store.getSnapshot(), ...patch });
|
|
5690
|
+
},
|
|
5691
|
+
[store]
|
|
5692
|
+
);
|
|
5653
5693
|
return [prefs, update];
|
|
5654
5694
|
}
|
|
5655
5695
|
|
|
@@ -5666,8 +5706,12 @@ var TEXT_SCALE_OPTIONS = [
|
|
|
5666
5706
|
{ value: "lg", label: "L" },
|
|
5667
5707
|
{ value: "xl", label: "XL" }
|
|
5668
5708
|
];
|
|
5669
|
-
function AppearanceMenu({ className = "",
|
|
5670
|
-
const
|
|
5709
|
+
function AppearanceMenu({ className = "", store: storeProp, storageKey, storage, defaults }) {
|
|
5710
|
+
const store = React34.useMemo(
|
|
5711
|
+
() => storeProp ?? createLocalStorageAppearanceStore({ storageKey, storage, defaults }),
|
|
5712
|
+
[storeProp, storageKey, storage, defaults]
|
|
5713
|
+
);
|
|
5714
|
+
const [prefs, update] = useAppearancePrefs(store);
|
|
5671
5715
|
const [open, setOpen] = React34.useState(false);
|
|
5672
5716
|
const anchorRef = React34.useRef(null);
|
|
5673
5717
|
const patch = (p) => update(p);
|
|
@@ -5904,137 +5948,172 @@ function ApiSpecBrowser({
|
|
|
5904
5948
|
// src/components/platform/ProfilePage.tsx
|
|
5905
5949
|
var React36 = __toESM(require("react"), 1);
|
|
5906
5950
|
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5951
|
+
function fieldInitialValue(field, user) {
|
|
5952
|
+
if (field.value) return field.value(user);
|
|
5953
|
+
const raw = user[field.key];
|
|
5954
|
+
return raw == null ? "" : String(raw);
|
|
5955
|
+
}
|
|
5956
|
+
function groupFields(fields) {
|
|
5957
|
+
const order = [];
|
|
5958
|
+
const byGroup = /* @__PURE__ */ new Map();
|
|
5959
|
+
for (const field of fields) {
|
|
5960
|
+
const group = field.group ?? "Identity";
|
|
5961
|
+
if (!byGroup.has(group)) {
|
|
5962
|
+
byGroup.set(group, { group, description: field.groupDescription, fields: [] });
|
|
5963
|
+
order.push(group);
|
|
5964
|
+
}
|
|
5965
|
+
const entry = byGroup.get(group);
|
|
5966
|
+
if (entry.description === void 0) entry.description = field.groupDescription;
|
|
5967
|
+
entry.fields.push(field);
|
|
5968
|
+
}
|
|
5969
|
+
return order.map((g) => byGroup.get(g));
|
|
5970
|
+
}
|
|
5971
|
+
function ProfilePage({
|
|
5972
|
+
user: userProp,
|
|
5973
|
+
fields = [],
|
|
5974
|
+
notifications = [],
|
|
5975
|
+
extra,
|
|
5976
|
+
onChangePhoto,
|
|
5977
|
+
onSave,
|
|
5978
|
+
onNavigate,
|
|
5979
|
+
sessions,
|
|
5980
|
+
onSignOutEverywhere,
|
|
5981
|
+
className = ""
|
|
5982
|
+
}) {
|
|
5916
5983
|
const { user: sessionUser, roles, permissions, saveProfile: saveProfile2 } = useSessionContext();
|
|
5917
5984
|
const user = userProp || sessionUser;
|
|
5918
|
-
const
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5985
|
+
const initialFieldValues = React36.useMemo(() => {
|
|
5986
|
+
const values2 = {};
|
|
5987
|
+
for (const field of fields) values2[field.key] = fieldInitialValue(field, user);
|
|
5988
|
+
return values2;
|
|
5989
|
+
}, [user.id, fields]);
|
|
5990
|
+
const initialNotify = React36.useMemo(() => {
|
|
5991
|
+
const values2 = {};
|
|
5992
|
+
for (const n of notifications) values2[n.key] = !!user.notify?.[n.key];
|
|
5993
|
+
return values2;
|
|
5994
|
+
}, [user.id, notifications]);
|
|
5995
|
+
const [values, setValues] = React36.useState(initialFieldValues);
|
|
5996
|
+
const [notify, setNotify] = React36.useState(initialNotify);
|
|
5927
5997
|
const [saving, setSaving] = React36.useState(false);
|
|
5928
5998
|
const [saved, setSaved] = React36.useState(false);
|
|
5929
|
-
const
|
|
5930
|
-
|
|
5999
|
+
const [prevUserId, setPrevUserId] = React36.useState(user.id);
|
|
6000
|
+
if (user.id !== prevUserId) {
|
|
6001
|
+
setPrevUserId(user.id);
|
|
6002
|
+
setValues(initialFieldValues);
|
|
6003
|
+
setNotify(initialNotify);
|
|
6004
|
+
setSaved(false);
|
|
6005
|
+
}
|
|
6006
|
+
const setField = (key, v) => {
|
|
6007
|
+
setValues((d) => ({ ...d, [key]: v }));
|
|
5931
6008
|
setSaved(false);
|
|
5932
6009
|
};
|
|
5933
|
-
const
|
|
5934
|
-
|
|
6010
|
+
const toggleNotify = (key) => {
|
|
6011
|
+
setNotify((d) => ({ ...d, [key]: !d[key] }));
|
|
5935
6012
|
setSaved(false);
|
|
5936
6013
|
};
|
|
5937
|
-
const dirty =
|
|
5938
|
-
const canSave = !!(onSave || saveProfile2);
|
|
6014
|
+
const dirty = fields.some((f) => values[f.key] !== initialFieldValues[f.key]) || notifications.some((n) => notify[n.key] !== initialNotify[n.key]);
|
|
6015
|
+
const canSave = !!(onSave || saveProfile2) && (fields.length > 0 || notifications.length > 0);
|
|
5939
6016
|
const save = async () => {
|
|
5940
6017
|
if (!canSave) return;
|
|
5941
6018
|
setSaving(true);
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
6019
|
+
const draft = { ...values };
|
|
6020
|
+
if (notifications.length > 0) draft.notify = notify;
|
|
6021
|
+
try {
|
|
6022
|
+
if (onSave) await onSave(draft);
|
|
6023
|
+
else await saveProfile2(draft);
|
|
6024
|
+
setSaved(true);
|
|
6025
|
+
} finally {
|
|
6026
|
+
setSaving(false);
|
|
6027
|
+
}
|
|
5946
6028
|
};
|
|
5947
|
-
const
|
|
5948
|
-
|
|
5949
|
-
|
|
5950
|
-
|
|
5951
|
-
|
|
5952
|
-
|
|
6029
|
+
const discard = () => {
|
|
6030
|
+
setValues(initialFieldValues);
|
|
6031
|
+
setNotify(initialNotify);
|
|
6032
|
+
setSaved(false);
|
|
6033
|
+
};
|
|
6034
|
+
const displayName = fields.some((f) => f.key === "name") ? values.name || user.name : user.name;
|
|
6035
|
+
const fieldGroups = groupFields(fields);
|
|
6036
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 20, maxWidth: 860 }, children: [
|
|
5953
6037
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "fd-stack", style: { gap: 10 }, children: [
|
|
5954
6038
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-overline fd-muted", children: "Account" }),
|
|
5955
6039
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("h1", { className: "fd-h1", style: { margin: 0 }, children: "Your profile" }),
|
|
5956
6040
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "fd-body fd-secondary fd-prose", style: { margin: 0 }, children: "How you appear to colleagues and clients across every flytedesk app, and what we send you." })
|
|
5957
6041
|
] }),
|
|
5958
6042
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Card, { elevation: "flat", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap", alignItems: "flex-start" }, children: [
|
|
5959
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Avatar, { name:
|
|
6043
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Avatar, { name: displayName, size: "lg" }),
|
|
5960
6044
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "fd-stack", style: { gap: 4, flex: 1, minWidth: 200 }, children: [
|
|
5961
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-h3", style: { margin: 0 }, children:
|
|
5962
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { className: "fd-body-sm fd-muted", children: [
|
|
5963
|
-
draft.title || "No title set",
|
|
5964
|
-
" \xB7 ",
|
|
5965
|
-
user.team || "No team"
|
|
5966
|
-
] }),
|
|
6045
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-h3", style: { margin: 0 }, children: displayName }),
|
|
5967
6046
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { className: "fd-row", style: { gap: 6, flexWrap: "wrap", paddingTop: 4 }, children: [
|
|
5968
6047
|
roles.map((r) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Badge, { tone: r.id === "owner" ? "success" : "neutral", children: r.name }, r.id)),
|
|
5969
6048
|
user.sso ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Badge, { tone: "info", icon: "shield-check", children: "SSO" }) : null
|
|
5970
6049
|
] })
|
|
5971
6050
|
] }),
|
|
5972
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { variant: "secondary", size: "sm", icon: "image", children: "Change photo" })
|
|
6051
|
+
onChangePhoto ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { variant: "secondary", size: "sm", icon: "image", onClick: onChangePhoto, children: "Change photo" }) : null
|
|
5973
6052
|
] }) }),
|
|
5974
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
6053
|
+
fieldGroups.map(({ group, description, fields: groupFieldDefs }) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
5975
6054
|
Card,
|
|
5976
6055
|
{
|
|
5977
|
-
title: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
5978
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children:
|
|
5979
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children:
|
|
5980
|
-
] }),
|
|
6056
|
+
title: description ? /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
6057
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: group }),
|
|
6058
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: description })
|
|
6059
|
+
] }) : group,
|
|
5981
6060
|
elevation: "flat",
|
|
5982
6061
|
children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "fd-stack", style: { gap: 14 }, children: [
|
|
5983
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.
|
|
5984
|
-
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
5988
|
-
|
|
6062
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { style: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 14 }, children: groupFieldDefs.filter((f) => f.type !== "textarea").map((field) => {
|
|
6063
|
+
const help = typeof field.help === "function" ? field.help(user) : field.help;
|
|
6064
|
+
const readOnly = field.readOnly || field.type === "readonly";
|
|
6065
|
+
if (field.type === "select") {
|
|
6066
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
6067
|
+
Select,
|
|
6068
|
+
{
|
|
6069
|
+
label: field.label,
|
|
6070
|
+
value: values[field.key],
|
|
6071
|
+
onChange: readOnly ? void 0 : (e) => setField(field.key, e.target.value),
|
|
6072
|
+
options: field.options ?? [],
|
|
6073
|
+
placeholder: field.placeholder,
|
|
6074
|
+
help,
|
|
6075
|
+
disabled: readOnly
|
|
6076
|
+
},
|
|
6077
|
+
field.key
|
|
6078
|
+
);
|
|
6079
|
+
}
|
|
6080
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
5989
6081
|
Input,
|
|
5990
6082
|
{
|
|
5991
|
-
label:
|
|
5992
|
-
value:
|
|
5993
|
-
readOnly:
|
|
5994
|
-
|
|
5995
|
-
|
|
5996
|
-
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6000
|
-
|
|
6001
|
-
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
|
|
6083
|
+
label: field.label,
|
|
6084
|
+
value: values[field.key],
|
|
6085
|
+
onChange: readOnly ? void 0 : (e) => setField(field.key, e.target.value),
|
|
6086
|
+
readOnly,
|
|
6087
|
+
disabled: readOnly,
|
|
6088
|
+
placeholder: field.placeholder,
|
|
6089
|
+
help
|
|
6090
|
+
},
|
|
6091
|
+
field.key
|
|
6092
|
+
);
|
|
6093
|
+
}) }),
|
|
6094
|
+
groupFieldDefs.filter((f) => f.type === "textarea").map((field) => {
|
|
6095
|
+
const help = typeof field.help === "function" ? field.help(user) : field.help;
|
|
6096
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
6097
|
+
Textarea,
|
|
6098
|
+
{
|
|
6099
|
+
label: field.label,
|
|
6100
|
+
value: values[field.key],
|
|
6101
|
+
onChange: field.readOnly ? void 0 : (e) => setField(field.key, e.target.value),
|
|
6102
|
+
readOnly: field.readOnly,
|
|
6103
|
+
disabled: field.readOnly,
|
|
6104
|
+
rows: field.rows ?? 3,
|
|
6105
|
+
placeholder: field.placeholder,
|
|
6106
|
+
help
|
|
6107
|
+
},
|
|
6108
|
+
field.key
|
|
6109
|
+
);
|
|
6110
|
+
})
|
|
6011
6111
|
] })
|
|
6012
|
-
}
|
|
6013
|
-
|
|
6014
|
-
|
|
6015
|
-
|
|
6016
|
-
|
|
6017
|
-
{
|
|
6018
|
-
label: "Time zone",
|
|
6019
|
-
value: draft.timezone,
|
|
6020
|
-
onChange: (e) => set("timezone", e.target.value),
|
|
6021
|
-
options: TIMEZONES,
|
|
6022
|
-
help: "Flight dates and schedules render in this zone."
|
|
6023
|
-
}
|
|
6024
|
-
),
|
|
6025
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Select, { label: "Start of week", options: ["Monday", "Sunday"], placeholder: "Monday" })
|
|
6026
|
-
] }) }),
|
|
6027
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
6028
|
-
Card,
|
|
6029
|
-
{
|
|
6030
|
-
title: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
6031
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: "Notifications" }),
|
|
6032
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-body-sm fd-muted", style: { fontWeight: 400 }, children: "Email only for now \u2014 in-app notifications are on the roadmap" })
|
|
6033
|
-
] }),
|
|
6034
|
-
elevation: "flat",
|
|
6035
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "fd-stack", style: { gap: 14 }, children: NOTIFY.map((n) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Switch, { checked: !!draft.notify[n.key], onChange: () => setNotify(n.key), label: n.label, description: n.detail }, n.key)) })
|
|
6036
|
-
}
|
|
6037
|
-
),
|
|
6112
|
+
},
|
|
6113
|
+
group
|
|
6114
|
+
)),
|
|
6115
|
+
extra,
|
|
6116
|
+
notifications.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Card, { title: "Notifications", elevation: "flat", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "fd-stack", style: { gap: 14 }, children: notifications.map((n) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Switch, { checked: !!notify[n.key], onChange: () => toggleNotify(n.key), label: n.label, description: n.description }, n.key)) }) }) : null,
|
|
6038
6117
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
|
|
6039
6118
|
Card,
|
|
6040
6119
|
{
|
|
@@ -6066,13 +6145,13 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
6066
6145
|
]
|
|
6067
6146
|
}
|
|
6068
6147
|
),
|
|
6069
|
-
|
|
6148
|
+
sessions ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
6070
6149
|
Card,
|
|
6071
6150
|
{
|
|
6072
6151
|
title: "Signed-in devices",
|
|
6073
6152
|
elevation: "flat",
|
|
6074
|
-
action: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { size: "sm", variant: "ghost", icon: "sign-out", children: "Sign out everywhere" }),
|
|
6075
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "fd-stack", style: { gap: 0 }, children:
|
|
6153
|
+
action: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { size: "sm", variant: "ghost", icon: "sign-out", onClick: onSignOutEverywhere, children: "Sign out everywhere" }),
|
|
6154
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "fd-stack", style: { gap: 0 }, children: sessions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "fd-body-sm fd-muted", style: { margin: 0 }, children: "No other signed-in devices." }) : sessions.map((s) => /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "fd-row", style: { gap: 12, padding: "10px 0", borderTop: "1px solid var(--border)", flexWrap: "wrap" }, children: [
|
|
6076
6155
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("i", { className: "ph ph-device-mobile", style: { fontSize: 16, color: "var(--text-muted)" }, "aria-hidden": "true" }),
|
|
6077
6156
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { className: "fd-stack", style: { gap: 1, flex: 1, minWidth: 160 }, children: [
|
|
6078
6157
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: s.device }),
|
|
@@ -6098,19 +6177,7 @@ function ProfilePage({ user: userProp, onSave, onNavigate, sessions, showSession
|
|
|
6098
6177
|
boxShadow: "0 -4px 16px rgba(11,13,17,.06)"
|
|
6099
6178
|
}, children: [
|
|
6100
6179
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-body-sm", style: { fontWeight: 600, flex: 1 }, children: saved ? "Saved." : dirty ? "Unsaved changes" : "No pending changes" }),
|
|
6101
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
6102
|
-
Button,
|
|
6103
|
-
{
|
|
6104
|
-
size: "sm",
|
|
6105
|
-
variant: "ghost",
|
|
6106
|
-
disabled: !dirty || saving,
|
|
6107
|
-
onClick: () => {
|
|
6108
|
-
setDraft({ name: user.name || "", title: user.title || "", email: user.email || "", phone: user.phone || "", timezone: user.timezone || TIMEZONES[2], bio: user.bio || "", notify: user.notify || { planShared: true, planChanged: true, goalMissed: true, flagChanged: false, weekly: true } });
|
|
6109
|
-
setSaved(false);
|
|
6110
|
-
},
|
|
6111
|
-
children: "Discard"
|
|
6112
|
-
}
|
|
6113
|
-
),
|
|
6180
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { size: "sm", variant: "ghost", disabled: !dirty || saving, onClick: discard, children: "Discard" }),
|
|
6114
6181
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Button, { size: "sm", icon: "check", disabled: !dirty || !canSave, loading: saving, onClick: save, children: "Save changes" })
|
|
6115
6182
|
] })
|
|
6116
6183
|
] });
|
|
@@ -11956,6 +12023,7 @@ function createVersionStore(initialState, options) {
|
|
|
11956
12023
|
channelWeightOf,
|
|
11957
12024
|
computeNeedMore,
|
|
11958
12025
|
computeVirtualWindow,
|
|
12026
|
+
createLocalStorageAppearanceStore,
|
|
11959
12027
|
createVersionStore,
|
|
11960
12028
|
eqFilter,
|
|
11961
12029
|
extensionOf,
|