@xnetjs/react 2.1.0 → 2.3.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/{chunk-H44ZSIH4.js → chunk-5ILJMPKO.js} +29 -6
- package/dist/{chunk-ANCTAEML.js → chunk-CZUUWSJ7.js} +254 -116
- package/dist/{chunk-SZQNGRTO.js → chunk-KK6VADMZ.js} +1 -1
- package/dist/{chunk-HTFAHJQK.js → chunk-QSJJNEFY.js} +1 -1
- package/dist/{chunk-ZGP56IIJ.js → chunk-RW3DSDKO.js} +1 -1
- package/dist/{chunk-VZMZQTR7.js → chunk-UVJJN33U.js} +2 -2
- package/dist/core.js +3 -3
- package/dist/database.js +2 -2
- package/dist/{experimental-DyPoZcJT.d.ts → experimental-Dv0MIlsc.d.ts} +65 -3
- package/dist/experimental.d.ts +1 -1
- package/dist/experimental.js +3 -3
- package/dist/index.d.ts +61 -5
- package/dist/index.js +59 -12
- package/dist/internal.js +2 -2
- package/package.json +10 -10
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
useMutate,
|
|
3
3
|
useQuery
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RW3DSDKO.js";
|
|
5
5
|
import {
|
|
6
6
|
XNetContext,
|
|
7
7
|
downloadBackup,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
useNodeStore,
|
|
10
10
|
useSecurityContext,
|
|
11
11
|
useXNet
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-5ILJMPKO.js";
|
|
13
13
|
|
|
14
14
|
// src/hooks/useTaskProjectionSync.ts
|
|
15
15
|
import { ExternalReferenceSchema, TaskSchema, isCompletedTaskStatus } from "@xnetjs/data";
|
|
@@ -3398,9 +3398,18 @@ var TRANSITIONS = {
|
|
|
3398
3398
|
AUTHENTICATE: "authenticating",
|
|
3399
3399
|
CREATE_NEW: "authenticating",
|
|
3400
3400
|
CREATE_RECOVERABLE: "creating-recoverable",
|
|
3401
|
+
CONTINUE_WITH_ATPROTO: "atproto-ceremony",
|
|
3401
3402
|
IMPORT_EXISTING: "import-identity",
|
|
3402
3403
|
BROWSER_UNSUPPORTED: "unsupported-browser"
|
|
3403
3404
|
},
|
|
3405
|
+
"atproto-ceremony": {
|
|
3406
|
+
// The ceremony handler stores the linked handle (ATPROTO_LINKED, self-loop)
|
|
3407
|
+
// then runs the existing passkey-create flow → PASSKEY_SUCCESS.
|
|
3408
|
+
ATPROTO_LINKED: "atproto-ceremony",
|
|
3409
|
+
PASSKEY_SUCCESS: "connecting-hub",
|
|
3410
|
+
ATPROTO_CEREMONY_FAILED: "auth-error",
|
|
3411
|
+
BACK_TO_WELCOME: "welcome"
|
|
3412
|
+
},
|
|
3404
3413
|
"creating-recoverable": {
|
|
3405
3414
|
RECOVERABLE_CREATED: "show-recovery-phrase",
|
|
3406
3415
|
PASSKEY_FAILED: "auth-error",
|
|
@@ -3478,6 +3487,16 @@ function onboardingReducer(current, event) {
|
|
|
3478
3487
|
case "IMPORT_FAILED":
|
|
3479
3488
|
nextContext.error = event.error;
|
|
3480
3489
|
break;
|
|
3490
|
+
case "ATPROTO_LINKED":
|
|
3491
|
+
nextContext.atprotoDid = event.atprotoDid;
|
|
3492
|
+
nextContext.atprotoHandle = event.atprotoHandle;
|
|
3493
|
+
nextContext.atprotoDisplayName = event.displayName ?? null;
|
|
3494
|
+
nextContext.error = null;
|
|
3495
|
+
break;
|
|
3496
|
+
case "ATPROTO_CEREMONY_FAILED":
|
|
3497
|
+
nextContext.error = event.error;
|
|
3498
|
+
break;
|
|
3499
|
+
case "CONTINUE_WITH_ATPROTO":
|
|
3481
3500
|
case "CREATE_RECOVERABLE":
|
|
3482
3501
|
nextContext.error = null;
|
|
3483
3502
|
break;
|
|
@@ -3504,7 +3523,10 @@ function createInitialState(hubUrl) {
|
|
|
3504
3523
|
hubUrl: hubUrl ?? null,
|
|
3505
3524
|
error: null,
|
|
3506
3525
|
isDemo: false,
|
|
3507
|
-
recoveryPhrase: null
|
|
3526
|
+
recoveryPhrase: null,
|
|
3527
|
+
atprotoDid: null,
|
|
3528
|
+
atprotoHandle: null,
|
|
3529
|
+
atprotoDisplayName: null
|
|
3508
3530
|
}
|
|
3509
3531
|
};
|
|
3510
3532
|
}
|
|
@@ -3530,7 +3552,8 @@ var OnboardingCtx = createContext(null);
|
|
|
3530
3552
|
function OnboardingProvider({
|
|
3531
3553
|
children,
|
|
3532
3554
|
defaultHubUrl = "wss://hub.xnet.fyi",
|
|
3533
|
-
onComplete
|
|
3555
|
+
onComplete,
|
|
3556
|
+
runAtprotoCeremony
|
|
3534
3557
|
}) {
|
|
3535
3558
|
const [{ state, context }, dispatch] = useReducer(
|
|
3536
3559
|
onboardingReducer,
|
|
@@ -3659,7 +3682,44 @@ function OnboardingProvider({
|
|
|
3659
3682
|
},
|
|
3660
3683
|
[state, manager]
|
|
3661
3684
|
);
|
|
3662
|
-
|
|
3685
|
+
const startAtprotoCeremony = useCallback18(
|
|
3686
|
+
(handleOrPds) => {
|
|
3687
|
+
if (!runAtprotoCeremony || authInFlight.current) return;
|
|
3688
|
+
authInFlight.current = true;
|
|
3689
|
+
runAtprotoCeremony({ handleOrPds }).then(async (result) => {
|
|
3690
|
+
dispatch({
|
|
3691
|
+
type: "ATPROTO_LINKED",
|
|
3692
|
+
atprotoDid: result.atprotoDid,
|
|
3693
|
+
atprotoHandle: result.atprotoHandle,
|
|
3694
|
+
displayName: result.displayName
|
|
3695
|
+
});
|
|
3696
|
+
const keyBundle = await manager.create();
|
|
3697
|
+
if (result.writeBinding) {
|
|
3698
|
+
await result.writeBinding(keyBundle.identity.did, keyBundle.signingKey);
|
|
3699
|
+
}
|
|
3700
|
+
dispatch({ type: "PASSKEY_SUCCESS", identity: keyBundle.identity, keyBundle });
|
|
3701
|
+
}).catch((err) => {
|
|
3702
|
+
dispatch({
|
|
3703
|
+
type: "ATPROTO_CEREMONY_FAILED",
|
|
3704
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
3705
|
+
});
|
|
3706
|
+
}).finally(() => {
|
|
3707
|
+
authInFlight.current = false;
|
|
3708
|
+
});
|
|
3709
|
+
},
|
|
3710
|
+
[runAtprotoCeremony, manager]
|
|
3711
|
+
);
|
|
3712
|
+
const value = useMemo14(
|
|
3713
|
+
() => ({
|
|
3714
|
+
state,
|
|
3715
|
+
context,
|
|
3716
|
+
send,
|
|
3717
|
+
atprotoEnabled: Boolean(runAtprotoCeremony),
|
|
3718
|
+
startAtprotoCeremony
|
|
3719
|
+
}),
|
|
3720
|
+
[state, context, send, runAtprotoCeremony, startAtprotoCeremony]
|
|
3721
|
+
);
|
|
3722
|
+
return /* @__PURE__ */ jsx6(OnboardingCtx.Provider, { value, children });
|
|
3663
3723
|
}
|
|
3664
3724
|
function useOnboarding() {
|
|
3665
3725
|
const ctx = useContext7(OnboardingCtx);
|
|
@@ -3911,7 +3971,7 @@ function UnsupportedBrowserScreen() {
|
|
|
3911
3971
|
// src/onboarding/screens/WelcomeScreen.tsx
|
|
3912
3972
|
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3913
3973
|
function WelcomeScreen() {
|
|
3914
|
-
const { send } = useOnboarding();
|
|
3974
|
+
const { send, atprotoEnabled } = useOnboarding();
|
|
3915
3975
|
return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col items-center justify-center min-h-screen bg-gradient-to-b from-background to-muted/30 text-foreground p-6", children: [
|
|
3916
3976
|
/* @__PURE__ */ jsx13("div", { className: "w-16 h-16 mb-8 rounded-2xl bg-primary/10 flex items-center justify-center", children: /* @__PURE__ */ jsxs11(
|
|
3917
3977
|
"svg",
|
|
@@ -3961,6 +4021,14 @@ function WelcomeScreen() {
|
|
|
3961
4021
|
}
|
|
3962
4022
|
),
|
|
3963
4023
|
/* @__PURE__ */ jsx13("p", { className: "text-xs text-muted-foreground/70 text-center max-w-xs mt-2 mb-6", children: "Creates a secure passkey on your device. No passwords needed." }),
|
|
4024
|
+
atprotoEnabled && /* @__PURE__ */ jsx13(
|
|
4025
|
+
"button",
|
|
4026
|
+
{
|
|
4027
|
+
className: "text-sm text-muted-foreground hover:text-foreground transition-colors underline-offset-4 hover:underline mb-2",
|
|
4028
|
+
onClick: () => send({ type: "CONTINUE_WITH_ATPROTO" }),
|
|
4029
|
+
children: "Continue with Bluesky (or any PDS)"
|
|
4030
|
+
}
|
|
4031
|
+
),
|
|
3964
4032
|
/* @__PURE__ */ jsx13(
|
|
3965
4033
|
"button",
|
|
3966
4034
|
{
|
|
@@ -3980,13 +4048,81 @@ function WelcomeScreen() {
|
|
|
3980
4048
|
] });
|
|
3981
4049
|
}
|
|
3982
4050
|
|
|
4051
|
+
// src/onboarding/screens/AtprotoCeremonyScreen.tsx
|
|
4052
|
+
import { useState as useState24 } from "react";
|
|
4053
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4054
|
+
function AtprotoCeremonyScreen() {
|
|
4055
|
+
const { context, send, startAtprotoCeremony } = useOnboarding();
|
|
4056
|
+
const [handle, setHandle] = useState24("");
|
|
4057
|
+
const linked = Boolean(context.atprotoDid);
|
|
4058
|
+
const submit = () => {
|
|
4059
|
+
const value = handle.trim();
|
|
4060
|
+
if (value) startAtprotoCeremony(value);
|
|
4061
|
+
};
|
|
4062
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-center justify-center min-h-screen bg-background text-foreground p-6", children: [
|
|
4063
|
+
/* @__PURE__ */ jsx14("h1", { className: "text-2xl font-semibold mb-2", children: "Continue with Bluesky" }),
|
|
4064
|
+
/* @__PURE__ */ jsx14("p", { className: "text-muted-foreground text-center mb-6 max-w-sm", children: "Sign in with your ATProto handle to claim a free global name. Works with Bluesky or any PDS." }),
|
|
4065
|
+
linked ? /* @__PURE__ */ jsxs12("p", { className: "text-sm text-muted-foreground mb-6", children: [
|
|
4066
|
+
"Linked ",
|
|
4067
|
+
/* @__PURE__ */ jsxs12("span", { className: "font-medium text-foreground", children: [
|
|
4068
|
+
"@",
|
|
4069
|
+
context.atprotoHandle
|
|
4070
|
+
] }),
|
|
4071
|
+
" \u2014 finishing your passkey\u2026"
|
|
4072
|
+
] }) : /* @__PURE__ */ jsxs12("div", { className: "w-full max-w-sm", children: [
|
|
4073
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: "atproto-handle", className: "sr-only", children: "ATProto handle" }),
|
|
4074
|
+
/* @__PURE__ */ jsx14(
|
|
4075
|
+
"input",
|
|
4076
|
+
{
|
|
4077
|
+
id: "atproto-handle",
|
|
4078
|
+
type: "text",
|
|
4079
|
+
inputMode: "url",
|
|
4080
|
+
autoCapitalize: "none",
|
|
4081
|
+
autoCorrect: "off",
|
|
4082
|
+
spellCheck: false,
|
|
4083
|
+
placeholder: "alice.bsky.social",
|
|
4084
|
+
value: handle,
|
|
4085
|
+
onChange: (e) => setHandle(e.target.value),
|
|
4086
|
+
onKeyDown: (e) => {
|
|
4087
|
+
if (e.key === "Enter") submit();
|
|
4088
|
+
},
|
|
4089
|
+
className: "w-full px-4 py-3 rounded-lg border border-border bg-background mb-3"
|
|
4090
|
+
}
|
|
4091
|
+
),
|
|
4092
|
+
/* @__PURE__ */ jsx14(
|
|
4093
|
+
"button",
|
|
4094
|
+
{
|
|
4095
|
+
onClick: submit,
|
|
4096
|
+
disabled: !handle.trim(),
|
|
4097
|
+
className: "w-full px-4 py-3 bg-primary text-primary-foreground rounded-lg font-medium disabled:opacity-50",
|
|
4098
|
+
children: "Continue"
|
|
4099
|
+
}
|
|
4100
|
+
)
|
|
4101
|
+
] }),
|
|
4102
|
+
context.error && /* @__PURE__ */ jsx14("p", { className: "text-sm text-destructive mt-4 max-w-sm text-center", children: context.error.message }),
|
|
4103
|
+
/* @__PURE__ */ jsxs12("p", { className: "text-xs text-muted-foreground/80 text-center max-w-xs mt-6", children: [
|
|
4104
|
+
"Your Bluesky account gives you a global name. It does ",
|
|
4105
|
+
/* @__PURE__ */ jsx14("strong", { children: "not" }),
|
|
4106
|
+
" hold or recover your xNet keys unless you later enable it as a recovery anchor."
|
|
4107
|
+
] }),
|
|
4108
|
+
/* @__PURE__ */ jsx14(
|
|
4109
|
+
"button",
|
|
4110
|
+
{
|
|
4111
|
+
className: "text-sm text-muted-foreground hover:text-foreground underline-offset-4 hover:underline mt-6",
|
|
4112
|
+
onClick: () => send({ type: "BACK_TO_WELCOME" }),
|
|
4113
|
+
children: "Back"
|
|
4114
|
+
}
|
|
4115
|
+
)
|
|
4116
|
+
] });
|
|
4117
|
+
}
|
|
4118
|
+
|
|
3983
4119
|
// src/onboarding/screens/GuardianRecoveryScreen.tsx
|
|
3984
4120
|
import { parseShare as parseShare2 } from "@xnetjs/identity";
|
|
3985
|
-
import { useMemo as useMemo15, useState as
|
|
3986
|
-
import { jsx as
|
|
4121
|
+
import { useMemo as useMemo15, useState as useState25 } from "react";
|
|
4122
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3987
4123
|
function GuardianRecoveryScreen() {
|
|
3988
4124
|
const { send, context } = useOnboarding();
|
|
3989
|
-
const [text, setText] =
|
|
4125
|
+
const [text, setText] = useState25("");
|
|
3990
4126
|
const { validCodes, invalidCount, threshold } = useMemo15(() => {
|
|
3991
4127
|
const lines = text.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
3992
4128
|
const valid = [];
|
|
@@ -4012,10 +4148,10 @@ function GuardianRecoveryScreen() {
|
|
|
4012
4148
|
if (threshold !== null) return `${validCodes.length} of ${threshold} needed`;
|
|
4013
4149
|
return `${validCodes.length} share${validCodes.length === 1 ? "" : "s"} pasted`;
|
|
4014
4150
|
})();
|
|
4015
|
-
return /* @__PURE__ */
|
|
4016
|
-
/* @__PURE__ */
|
|
4017
|
-
/* @__PURE__ */
|
|
4018
|
-
/* @__PURE__ */
|
|
4151
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex min-h-screen flex-col items-center justify-center bg-background p-6 text-foreground", children: [
|
|
4152
|
+
/* @__PURE__ */ jsx15("h1", { className: "mb-2 text-2xl font-semibold", children: "Recover with your guardians" }),
|
|
4153
|
+
/* @__PURE__ */ jsx15("p", { className: "mb-6 max-w-md text-center text-muted-foreground", children: "Paste the share codes your guardians gave you \u2014 one per line. You need enough of them to restore your identity; we\u2019ll tell you when you have enough." }),
|
|
4154
|
+
/* @__PURE__ */ jsx15(
|
|
4019
4155
|
"textarea",
|
|
4020
4156
|
{
|
|
4021
4157
|
autoFocus: true,
|
|
@@ -4029,14 +4165,14 @@ function GuardianRecoveryScreen() {
|
|
|
4029
4165
|
className: "mb-2 w-80 max-w-full resize-none rounded-lg border border-border bg-muted/30 p-3 font-mono text-xs outline-none focus:border-primary"
|
|
4030
4166
|
}
|
|
4031
4167
|
),
|
|
4032
|
-
/* @__PURE__ */
|
|
4168
|
+
/* @__PURE__ */ jsx15("div", { className: "mb-4 h-5 text-xs", children: /* @__PURE__ */ jsx15(
|
|
4033
4169
|
"span",
|
|
4034
4170
|
{
|
|
4035
4171
|
className: context.error || invalidCount > 0 ? "text-destructive" : "text-muted-foreground",
|
|
4036
4172
|
children: hint
|
|
4037
4173
|
}
|
|
4038
4174
|
) }),
|
|
4039
|
-
/* @__PURE__ */
|
|
4175
|
+
/* @__PURE__ */ jsx15(
|
|
4040
4176
|
"button",
|
|
4041
4177
|
{
|
|
4042
4178
|
disabled: !canRecover,
|
|
@@ -4045,7 +4181,7 @@ function GuardianRecoveryScreen() {
|
|
|
4045
4181
|
children: "Recover my identity"
|
|
4046
4182
|
}
|
|
4047
4183
|
),
|
|
4048
|
-
/* @__PURE__ */
|
|
4184
|
+
/* @__PURE__ */ jsx15(
|
|
4049
4185
|
"button",
|
|
4050
4186
|
{
|
|
4051
4187
|
className: "text-sm text-muted-foreground transition-colors hover:text-foreground",
|
|
@@ -4058,11 +4194,11 @@ function GuardianRecoveryScreen() {
|
|
|
4058
4194
|
|
|
4059
4195
|
// src/onboarding/screens/RecoveryPhraseScreen.tsx
|
|
4060
4196
|
import { validateRecoveryPhrase } from "@xnetjs/identity";
|
|
4061
|
-
import { useMemo as useMemo16, useState as
|
|
4062
|
-
import { jsx as
|
|
4197
|
+
import { useMemo as useMemo16, useState as useState26 } from "react";
|
|
4198
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
4063
4199
|
function RecoveryPhraseScreen() {
|
|
4064
4200
|
const { send, context } = useOnboarding();
|
|
4065
|
-
const [phrase, setPhrase] =
|
|
4201
|
+
const [phrase, setPhrase] = useState26("");
|
|
4066
4202
|
const validation = useMemo16(() => validateRecoveryPhrase(phrase), [phrase]);
|
|
4067
4203
|
const empty = phrase.trim().length === 0;
|
|
4068
4204
|
const hint = (() => {
|
|
@@ -4072,10 +4208,10 @@ function RecoveryPhraseScreen() {
|
|
|
4072
4208
|
}
|
|
4073
4209
|
return `Not in the wordlist: ${validation.unknownWords.join(", ")}`;
|
|
4074
4210
|
})();
|
|
4075
|
-
return /* @__PURE__ */
|
|
4076
|
-
/* @__PURE__ */
|
|
4077
|
-
/* @__PURE__ */
|
|
4078
|
-
/* @__PURE__ */
|
|
4211
|
+
return /* @__PURE__ */ jsxs14("div", { className: "flex min-h-screen flex-col items-center justify-center bg-background p-6 text-foreground", children: [
|
|
4212
|
+
/* @__PURE__ */ jsx16("h1", { className: "mb-2 text-2xl font-semibold", children: "Enter your recovery phrase" }),
|
|
4213
|
+
/* @__PURE__ */ jsx16("p", { className: "mb-6 max-w-md text-center text-muted-foreground", children: "Type the recovery phrase you saved. It restores the same identity and your encrypted data on this device." }),
|
|
4214
|
+
/* @__PURE__ */ jsx16(
|
|
4079
4215
|
"textarea",
|
|
4080
4216
|
{
|
|
4081
4217
|
autoFocus: true,
|
|
@@ -4089,11 +4225,11 @@ function RecoveryPhraseScreen() {
|
|
|
4089
4225
|
className: "mb-2 w-80 max-w-full resize-none rounded-lg border border-border bg-muted/30 p-3 font-mono text-sm outline-none focus:border-primary"
|
|
4090
4226
|
}
|
|
4091
4227
|
),
|
|
4092
|
-
/* @__PURE__ */
|
|
4093
|
-
hint && /* @__PURE__ */
|
|
4094
|
-
context.error && !hint && /* @__PURE__ */
|
|
4228
|
+
/* @__PURE__ */ jsxs14("div", { className: "mb-4 h-5 text-xs", children: [
|
|
4229
|
+
hint && /* @__PURE__ */ jsx16("span", { className: "text-destructive", children: hint }),
|
|
4230
|
+
context.error && !hint && /* @__PURE__ */ jsx16("span", { className: "text-destructive", children: context.error.message })
|
|
4095
4231
|
] }),
|
|
4096
|
-
/* @__PURE__ */
|
|
4232
|
+
/* @__PURE__ */ jsx16(
|
|
4097
4233
|
"button",
|
|
4098
4234
|
{
|
|
4099
4235
|
disabled: !validation.ok,
|
|
@@ -4102,7 +4238,7 @@ function RecoveryPhraseScreen() {
|
|
|
4102
4238
|
children: "Recover my identity"
|
|
4103
4239
|
}
|
|
4104
4240
|
),
|
|
4105
|
-
/* @__PURE__ */
|
|
4241
|
+
/* @__PURE__ */ jsx16(
|
|
4106
4242
|
"button",
|
|
4107
4243
|
{
|
|
4108
4244
|
className: "text-sm text-muted-foreground transition-colors hover:text-foreground",
|
|
@@ -4114,12 +4250,12 @@ function RecoveryPhraseScreen() {
|
|
|
4114
4250
|
}
|
|
4115
4251
|
|
|
4116
4252
|
// src/onboarding/screens/ShowRecoveryPhraseScreen.tsx
|
|
4117
|
-
import { useState as
|
|
4118
|
-
import { jsx as
|
|
4253
|
+
import { useState as useState27 } from "react";
|
|
4254
|
+
import { jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4119
4255
|
function ShowRecoveryPhraseScreen() {
|
|
4120
4256
|
const { send, context } = useOnboarding();
|
|
4121
|
-
const [saved, setSaved] =
|
|
4122
|
-
const [copied, setCopied] =
|
|
4257
|
+
const [saved, setSaved] = useState27(false);
|
|
4258
|
+
const [copied, setCopied] = useState27(false);
|
|
4123
4259
|
const phrase = context.recoveryPhrase ?? "";
|
|
4124
4260
|
const words = phrase.split(" ").filter(Boolean);
|
|
4125
4261
|
const copy = () => {
|
|
@@ -4128,14 +4264,14 @@ function ShowRecoveryPhraseScreen() {
|
|
|
4128
4264
|
() => setCopied(false)
|
|
4129
4265
|
);
|
|
4130
4266
|
};
|
|
4131
|
-
return /* @__PURE__ */
|
|
4132
|
-
/* @__PURE__ */
|
|
4133
|
-
/* @__PURE__ */
|
|
4134
|
-
/* @__PURE__ */
|
|
4135
|
-
/* @__PURE__ */
|
|
4136
|
-
/* @__PURE__ */
|
|
4267
|
+
return /* @__PURE__ */ jsxs15("div", { className: "flex min-h-screen flex-col items-center justify-center bg-background p-6 text-foreground", children: [
|
|
4268
|
+
/* @__PURE__ */ jsx17("h1", { className: "mb-2 text-2xl font-semibold", children: "Save your recovery phrase" }),
|
|
4269
|
+
/* @__PURE__ */ jsx17("p", { className: "mb-6 max-w-md text-center text-muted-foreground", children: "Write these words down and keep them somewhere safe. They are the only way to recover your workspace if you lose your passkey \u2014 we can\u2019t recover them for you." }),
|
|
4270
|
+
/* @__PURE__ */ jsx17("ol", { className: "mb-3 grid w-80 max-w-full grid-cols-2 gap-x-6 gap-y-1 rounded-lg border border-border bg-muted/30 p-4 font-mono text-sm", children: words.map((word, i) => /* @__PURE__ */ jsxs15("li", { className: "flex gap-2", children: [
|
|
4271
|
+
/* @__PURE__ */ jsx17("span", { className: "w-5 select-none text-right text-muted-foreground", children: i + 1 }),
|
|
4272
|
+
/* @__PURE__ */ jsx17("span", { children: word })
|
|
4137
4273
|
] }, `${i}-${word}`)) }),
|
|
4138
|
-
/* @__PURE__ */
|
|
4274
|
+
/* @__PURE__ */ jsx17(
|
|
4139
4275
|
"button",
|
|
4140
4276
|
{
|
|
4141
4277
|
className: "mb-5 text-xs text-muted-foreground transition-colors hover:text-foreground",
|
|
@@ -4143,8 +4279,8 @@ function ShowRecoveryPhraseScreen() {
|
|
|
4143
4279
|
children: copied ? "Copied \u2713" : "Copy to clipboard"
|
|
4144
4280
|
}
|
|
4145
4281
|
),
|
|
4146
|
-
/* @__PURE__ */
|
|
4147
|
-
/* @__PURE__ */
|
|
4282
|
+
/* @__PURE__ */ jsxs15("label", { className: "mb-4 flex max-w-xs cursor-pointer items-start gap-2 text-sm text-muted-foreground", children: [
|
|
4283
|
+
/* @__PURE__ */ jsx17(
|
|
4148
4284
|
"input",
|
|
4149
4285
|
{
|
|
4150
4286
|
type: "checkbox",
|
|
@@ -4155,7 +4291,7 @@ function ShowRecoveryPhraseScreen() {
|
|
|
4155
4291
|
),
|
|
4156
4292
|
"I\u2019ve saved my recovery phrase somewhere safe."
|
|
4157
4293
|
] }),
|
|
4158
|
-
/* @__PURE__ */
|
|
4294
|
+
/* @__PURE__ */ jsx17(
|
|
4159
4295
|
"button",
|
|
4160
4296
|
{
|
|
4161
4297
|
disabled: !saved,
|
|
@@ -4168,52 +4304,54 @@ function ShowRecoveryPhraseScreen() {
|
|
|
4168
4304
|
}
|
|
4169
4305
|
|
|
4170
4306
|
// src/onboarding/OnboardingFlow.tsx
|
|
4171
|
-
import { Fragment, jsx as
|
|
4307
|
+
import { Fragment, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4172
4308
|
function OnboardingFlow({ connectToHub, children }) {
|
|
4173
4309
|
const { state } = useOnboarding();
|
|
4174
4310
|
switch (state) {
|
|
4175
4311
|
case "welcome":
|
|
4176
|
-
return /* @__PURE__ */
|
|
4312
|
+
return /* @__PURE__ */ jsx18(WelcomeScreen, {});
|
|
4177
4313
|
case "authenticating":
|
|
4178
|
-
return /* @__PURE__ */
|
|
4314
|
+
return /* @__PURE__ */ jsx18(AuthenticatingScreen, {});
|
|
4179
4315
|
case "auth-error":
|
|
4180
|
-
return /* @__PURE__ */
|
|
4316
|
+
return /* @__PURE__ */ jsx18(AuthErrorScreen, {});
|
|
4181
4317
|
case "unsupported-browser":
|
|
4182
|
-
return /* @__PURE__ */
|
|
4318
|
+
return /* @__PURE__ */ jsx18(UnsupportedBrowserScreen, {});
|
|
4183
4319
|
case "import-identity":
|
|
4184
|
-
return /* @__PURE__ */
|
|
4320
|
+
return /* @__PURE__ */ jsx18(ImportIdentityScreen, {});
|
|
4185
4321
|
case "qr-scan":
|
|
4186
|
-
return /* @__PURE__ */
|
|
4187
|
-
/* @__PURE__ */
|
|
4188
|
-
/* @__PURE__ */
|
|
4322
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex flex-col items-center justify-center min-h-screen bg-background text-foreground p-6", children: [
|
|
4323
|
+
/* @__PURE__ */ jsx18("h1", { className: "text-2xl font-semibold mb-2", children: "QR Scan" }),
|
|
4324
|
+
/* @__PURE__ */ jsx18("p", { className: "text-muted-foreground", children: "Coming soon \u2014 scan a QR code from another device." })
|
|
4189
4325
|
] });
|
|
4190
4326
|
case "recovery-phrase":
|
|
4191
|
-
return /* @__PURE__ */
|
|
4327
|
+
return /* @__PURE__ */ jsx18(RecoveryPhraseScreen, {});
|
|
4192
4328
|
case "guardian-recovery":
|
|
4193
|
-
return /* @__PURE__ */
|
|
4329
|
+
return /* @__PURE__ */ jsx18(GuardianRecoveryScreen, {});
|
|
4330
|
+
case "atproto-ceremony":
|
|
4331
|
+
return /* @__PURE__ */ jsx18(AtprotoCeremonyScreen, {});
|
|
4194
4332
|
case "creating-recoverable":
|
|
4195
|
-
return /* @__PURE__ */
|
|
4333
|
+
return /* @__PURE__ */ jsx18(AuthenticatingScreen, {});
|
|
4196
4334
|
case "show-recovery-phrase":
|
|
4197
|
-
return /* @__PURE__ */
|
|
4335
|
+
return /* @__PURE__ */ jsx18(ShowRecoveryPhraseScreen, {});
|
|
4198
4336
|
case "connecting-hub":
|
|
4199
|
-
return /* @__PURE__ */
|
|
4337
|
+
return /* @__PURE__ */ jsx18(HubConnectScreen, { connectToHub });
|
|
4200
4338
|
case "ready":
|
|
4201
|
-
return /* @__PURE__ */
|
|
4339
|
+
return /* @__PURE__ */ jsx18(ReadyScreen, {});
|
|
4202
4340
|
case "complete":
|
|
4203
|
-
return /* @__PURE__ */
|
|
4341
|
+
return /* @__PURE__ */ jsx18(Fragment, { children });
|
|
4204
4342
|
default:
|
|
4205
|
-
return /* @__PURE__ */
|
|
4343
|
+
return /* @__PURE__ */ jsx18(WelcomeScreen, {});
|
|
4206
4344
|
}
|
|
4207
4345
|
}
|
|
4208
4346
|
|
|
4209
4347
|
// src/onboarding/screens/SmartWelcome.tsx
|
|
4210
4348
|
import { discoverExistingPasskey } from "@xnetjs/identity";
|
|
4211
|
-
import { useEffect as useEffect20, useState as
|
|
4212
|
-
import { jsx as
|
|
4349
|
+
import { useEffect as useEffect20, useState as useState28 } from "react";
|
|
4350
|
+
import { jsx as jsx19, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4213
4351
|
function SmartWelcome() {
|
|
4214
4352
|
const { send } = useOnboarding();
|
|
4215
|
-
const [checking, setChecking] =
|
|
4216
|
-
const [hasExisting, setHasExisting] =
|
|
4353
|
+
const [checking, setChecking] = useState28(true);
|
|
4354
|
+
const [hasExisting, setHasExisting] = useState28(false);
|
|
4217
4355
|
useEffect20(() => {
|
|
4218
4356
|
let cancelled = false;
|
|
4219
4357
|
discoverExistingPasskey().then((passkey) => {
|
|
@@ -4231,31 +4369,31 @@ function SmartWelcome() {
|
|
|
4231
4369
|
};
|
|
4232
4370
|
}, []);
|
|
4233
4371
|
if (checking) {
|
|
4234
|
-
return /* @__PURE__ */
|
|
4372
|
+
return /* @__PURE__ */ jsx19("div", { className: "onboarding-screen", children: /* @__PURE__ */ jsx19("p", { className: "spinner-text", children: "Checking for existing identity..." }) });
|
|
4235
4373
|
}
|
|
4236
4374
|
if (hasExisting) {
|
|
4237
4375
|
const authName = getPlatformAuthName();
|
|
4238
|
-
return /* @__PURE__ */
|
|
4239
|
-
/* @__PURE__ */
|
|
4240
|
-
/* @__PURE__ */
|
|
4376
|
+
return /* @__PURE__ */ jsxs17("div", { className: "onboarding-screen welcome-back", children: [
|
|
4377
|
+
/* @__PURE__ */ jsx19("h1", { children: "Welcome back!" }),
|
|
4378
|
+
/* @__PURE__ */ jsxs17("p", { className: "subtitle", children: [
|
|
4241
4379
|
"We found your xNet identity. Use ",
|
|
4242
4380
|
authName,
|
|
4243
4381
|
" to sign in."
|
|
4244
4382
|
] }),
|
|
4245
|
-
/* @__PURE__ */
|
|
4383
|
+
/* @__PURE__ */ jsxs17("button", { className: "primary-button", onClick: () => send({ type: "AUTHENTICATE" }), children: [
|
|
4246
4384
|
"Sign in with ",
|
|
4247
4385
|
authName
|
|
4248
4386
|
] }),
|
|
4249
|
-
/* @__PURE__ */
|
|
4387
|
+
/* @__PURE__ */ jsx19("button", { className: "text-button", onClick: () => send({ type: "CREATE_NEW" }), children: "Create a new identity instead" })
|
|
4250
4388
|
] });
|
|
4251
4389
|
}
|
|
4252
|
-
return /* @__PURE__ */
|
|
4390
|
+
return /* @__PURE__ */ jsx19(WelcomeScreen, {});
|
|
4253
4391
|
}
|
|
4254
4392
|
|
|
4255
4393
|
// src/onboarding/screens/SyncProgressOverlay.tsx
|
|
4256
4394
|
import { formatBytes as formatBytes2 } from "@xnetjs/core";
|
|
4257
4395
|
import { useEffect as useEffect21 } from "react";
|
|
4258
|
-
import { Fragment as Fragment2, jsx as
|
|
4396
|
+
import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4259
4397
|
function SyncProgressOverlay({
|
|
4260
4398
|
progress,
|
|
4261
4399
|
onComplete
|
|
@@ -4266,14 +4404,14 @@ function SyncProgressOverlay({
|
|
|
4266
4404
|
return () => clearTimeout(timer);
|
|
4267
4405
|
}
|
|
4268
4406
|
}, [progress.phase, onComplete]);
|
|
4269
|
-
return /* @__PURE__ */
|
|
4270
|
-
progress.phase === "connecting" && /* @__PURE__ */
|
|
4271
|
-
/* @__PURE__ */
|
|
4272
|
-
/* @__PURE__ */
|
|
4407
|
+
return /* @__PURE__ */ jsx20("div", { className: "sync-progress-overlay", children: /* @__PURE__ */ jsxs18("div", { className: "sync-card", children: [
|
|
4408
|
+
progress.phase === "connecting" && /* @__PURE__ */ jsxs18(Fragment2, { children: [
|
|
4409
|
+
/* @__PURE__ */ jsx20("h2", { children: "Connecting to server..." }),
|
|
4410
|
+
/* @__PURE__ */ jsx20("p", { className: "spinner-text", children: "Please wait" })
|
|
4273
4411
|
] }),
|
|
4274
|
-
progress.phase === "syncing" && /* @__PURE__ */
|
|
4275
|
-
/* @__PURE__ */
|
|
4276
|
-
/* @__PURE__ */
|
|
4412
|
+
progress.phase === "syncing" && /* @__PURE__ */ jsxs18(Fragment2, { children: [
|
|
4413
|
+
/* @__PURE__ */ jsx20("h2", { children: "Syncing your data" }),
|
|
4414
|
+
/* @__PURE__ */ jsx20("div", { className: "progress-bar", children: /* @__PURE__ */ jsx20(
|
|
4277
4415
|
"div",
|
|
4278
4416
|
{
|
|
4279
4417
|
className: "progress-fill",
|
|
@@ -4282,29 +4420,29 @@ function SyncProgressOverlay({
|
|
|
4282
4420
|
}
|
|
4283
4421
|
}
|
|
4284
4422
|
) }),
|
|
4285
|
-
/* @__PURE__ */
|
|
4423
|
+
/* @__PURE__ */ jsxs18("p", { className: "progress-text", children: [
|
|
4286
4424
|
progress.roomsSynced,
|
|
4287
4425
|
" of ",
|
|
4288
4426
|
progress.roomsTotal,
|
|
4289
4427
|
" items"
|
|
4290
4428
|
] }),
|
|
4291
|
-
/* @__PURE__ */
|
|
4429
|
+
/* @__PURE__ */ jsxs18("p", { className: "bytes-text", children: [
|
|
4292
4430
|
formatBytes2(progress.bytesReceived),
|
|
4293
4431
|
" received"
|
|
4294
4432
|
] })
|
|
4295
4433
|
] }),
|
|
4296
|
-
progress.phase === "complete" && /* @__PURE__ */
|
|
4297
|
-
/* @__PURE__ */
|
|
4298
|
-
/* @__PURE__ */
|
|
4434
|
+
progress.phase === "complete" && /* @__PURE__ */ jsxs18(Fragment2, { children: [
|
|
4435
|
+
/* @__PURE__ */ jsx20("h2", { children: "All synced!" }),
|
|
4436
|
+
/* @__PURE__ */ jsxs18("p", { children: [
|
|
4299
4437
|
progress.roomsTotal,
|
|
4300
4438
|
" items synchronized"
|
|
4301
4439
|
] })
|
|
4302
4440
|
] }),
|
|
4303
|
-
progress.phase === "error" && /* @__PURE__ */
|
|
4304
|
-
/* @__PURE__ */
|
|
4305
|
-
/* @__PURE__ */
|
|
4306
|
-
progress.error && /* @__PURE__ */
|
|
4307
|
-
/* @__PURE__ */
|
|
4441
|
+
progress.phase === "error" && /* @__PURE__ */ jsxs18(Fragment2, { children: [
|
|
4442
|
+
/* @__PURE__ */ jsx20("h2", { children: "Sync issue" }),
|
|
4443
|
+
/* @__PURE__ */ jsx20("p", { children: "Some data may not be up to date." }),
|
|
4444
|
+
progress.error && /* @__PURE__ */ jsx20("p", { className: "error-detail", children: progress.error.message }),
|
|
4445
|
+
/* @__PURE__ */ jsx20("button", { className: "primary-button", onClick: onComplete, children: "Continue anyway" })
|
|
4308
4446
|
] })
|
|
4309
4447
|
] }) });
|
|
4310
4448
|
}
|
|
@@ -4369,60 +4507,60 @@ function isTaskOverdue(timestamp, completed) {
|
|
|
4369
4507
|
|
|
4370
4508
|
// src/components/PageTasksPanel.tsx
|
|
4371
4509
|
import { Calendar, CheckSquare2, ChevronDown, ChevronRight, Square, Users } from "lucide-react";
|
|
4372
|
-
import { useMemo as useMemo17, useState as
|
|
4373
|
-
import { jsx as
|
|
4510
|
+
import { useMemo as useMemo17, useState as useState29 } from "react";
|
|
4511
|
+
import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4374
4512
|
function PageTasksPanel({ pageId }) {
|
|
4375
|
-
const [expanded, setExpanded] =
|
|
4513
|
+
const [expanded, setExpanded] = useState29(true);
|
|
4376
4514
|
const { tree, loading } = useTasks({ pageId });
|
|
4377
4515
|
const rows = useMemo17(() => flattenTaskTree(tree), [tree]);
|
|
4378
|
-
return /* @__PURE__ */
|
|
4379
|
-
/* @__PURE__ */
|
|
4516
|
+
return /* @__PURE__ */ jsxs19("div", { className: "mt-8 overflow-hidden rounded-lg border border-border", children: [
|
|
4517
|
+
/* @__PURE__ */ jsx21(
|
|
4380
4518
|
"button",
|
|
4381
4519
|
{
|
|
4382
4520
|
className: "w-full cursor-pointer border-none bg-secondary p-3 px-4 text-left",
|
|
4383
4521
|
onClick: () => setExpanded((value) => !value),
|
|
4384
4522
|
type: "button",
|
|
4385
|
-
children: /* @__PURE__ */
|
|
4386
|
-
/* @__PURE__ */
|
|
4523
|
+
children: /* @__PURE__ */ jsxs19("h3", { className: "m-0 flex items-center justify-between text-sm font-semibold text-foreground", children: [
|
|
4524
|
+
/* @__PURE__ */ jsxs19("span", { children: [
|
|
4387
4525
|
"Tasks on this page (",
|
|
4388
4526
|
rows.length,
|
|
4389
4527
|
")"
|
|
4390
4528
|
] }),
|
|
4391
|
-
expanded ? /* @__PURE__ */
|
|
4529
|
+
expanded ? /* @__PURE__ */ jsx21(ChevronDown, { size: 16, className: "text-muted-foreground" }) : /* @__PURE__ */ jsx21(ChevronRight, { size: 16, className: "text-muted-foreground" })
|
|
4392
4530
|
] })
|
|
4393
4531
|
}
|
|
4394
4532
|
),
|
|
4395
|
-
expanded && /* @__PURE__ */
|
|
4533
|
+
expanded && /* @__PURE__ */ jsx21("div", { className: "p-3", children: loading ? /* @__PURE__ */ jsx21("p", { className: "m-0 text-sm text-muted-foreground", children: "Loading tasks..." }) : rows.length === 0 ? /* @__PURE__ */ jsx21("p", { className: "m-0 text-sm text-muted-foreground", children: "Checklist items on this page will appear here." }) : /* @__PURE__ */ jsx21("ul", { className: "m-0 list-none space-y-1 p-0", children: rows.map((task) => {
|
|
4396
4534
|
const dueDateLabel = formatTaskDueDate(task.dueDate);
|
|
4397
4535
|
const overdue = isTaskOverdue(task.dueDate, task.completed);
|
|
4398
|
-
return /* @__PURE__ */
|
|
4536
|
+
return /* @__PURE__ */ jsx21("li", { children: /* @__PURE__ */ jsxs19(
|
|
4399
4537
|
"div",
|
|
4400
4538
|
{
|
|
4401
4539
|
className: "flex items-start gap-2 rounded-md px-2 py-2 transition-colors hover:bg-accent/40",
|
|
4402
4540
|
style: { paddingLeft: `${task.depth * 18 + 8}px` },
|
|
4403
4541
|
children: [
|
|
4404
|
-
task.completed ? /* @__PURE__ */
|
|
4405
|
-
/* @__PURE__ */
|
|
4406
|
-
/* @__PURE__ */
|
|
4542
|
+
task.completed ? /* @__PURE__ */ jsx21(CheckSquare2, { size: 15, className: "mt-0.5 flex-shrink-0 text-primary" }) : /* @__PURE__ */ jsx21(Square, { size: 15, className: "mt-0.5 flex-shrink-0 text-muted-foreground" }),
|
|
4543
|
+
/* @__PURE__ */ jsxs19("div", { className: "min-w-0 flex-1", children: [
|
|
4544
|
+
/* @__PURE__ */ jsx21(
|
|
4407
4545
|
"div",
|
|
4408
4546
|
{
|
|
4409
4547
|
className: `text-sm ${task.completed ? "line-through text-muted-foreground" : "text-foreground"}`,
|
|
4410
4548
|
children: task.title
|
|
4411
4549
|
}
|
|
4412
4550
|
),
|
|
4413
|
-
/* @__PURE__ */
|
|
4414
|
-
dueDateLabel ? /* @__PURE__ */
|
|
4551
|
+
/* @__PURE__ */ jsxs19("div", { className: "mt-1 flex flex-wrap items-center gap-2 text-[11px] text-muted-foreground", children: [
|
|
4552
|
+
dueDateLabel ? /* @__PURE__ */ jsxs19(
|
|
4415
4553
|
"span",
|
|
4416
4554
|
{
|
|
4417
4555
|
className: `inline-flex items-center gap-1 ${overdue ? "text-red-500" : "text-muted-foreground"}`,
|
|
4418
4556
|
children: [
|
|
4419
|
-
/* @__PURE__ */
|
|
4557
|
+
/* @__PURE__ */ jsx21(Calendar, { size: 11 }),
|
|
4420
4558
|
dueDateLabel
|
|
4421
4559
|
]
|
|
4422
4560
|
}
|
|
4423
4561
|
) : null,
|
|
4424
|
-
task.assigneeCount > 0 ? /* @__PURE__ */
|
|
4425
|
-
/* @__PURE__ */
|
|
4562
|
+
task.assigneeCount > 0 ? /* @__PURE__ */ jsxs19("span", { className: "inline-flex items-center gap-1", children: [
|
|
4563
|
+
/* @__PURE__ */ jsx21(Users, { size: 11 }),
|
|
4426
4564
|
task.assigneeCount
|
|
4427
4565
|
] }) : null
|
|
4428
4566
|
] })
|
|
@@ -4436,7 +4574,7 @@ function PageTasksPanel({ pageId }) {
|
|
|
4436
4574
|
|
|
4437
4575
|
// src/components/TaskCollectionEmbed.tsx
|
|
4438
4576
|
import { useMemo as useMemo18 } from "react";
|
|
4439
|
-
import { jsx as
|
|
4577
|
+
import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4440
4578
|
function TaskCollectionEmbed({
|
|
4441
4579
|
currentPageId,
|
|
4442
4580
|
currentDid,
|
|
@@ -4469,33 +4607,33 @@ function TaskCollectionEmbed({
|
|
|
4469
4607
|
}));
|
|
4470
4608
|
}, [data, showHierarchy, tree]);
|
|
4471
4609
|
if (missingPageContext) {
|
|
4472
|
-
return /* @__PURE__ */
|
|
4610
|
+
return /* @__PURE__ */ jsx22("div", { className: "p-4 text-sm text-muted-foreground", children: "This view needs a page context." });
|
|
4473
4611
|
}
|
|
4474
4612
|
if (loading) {
|
|
4475
|
-
return /* @__PURE__ */
|
|
4613
|
+
return /* @__PURE__ */ jsx22("div", { className: "p-4 text-sm text-muted-foreground", children: "Loading tasks..." });
|
|
4476
4614
|
}
|
|
4477
4615
|
if (rows.length === 0) {
|
|
4478
|
-
return /* @__PURE__ */
|
|
4616
|
+
return /* @__PURE__ */ jsx22("div", { className: "p-4 text-sm text-muted-foreground", children: "No tasks match the saved filters for this view." });
|
|
4479
4617
|
}
|
|
4480
|
-
return /* @__PURE__ */
|
|
4618
|
+
return /* @__PURE__ */ jsx22("div", { className: "p-3", children: /* @__PURE__ */ jsx22("ul", { className: "m-0 list-none space-y-1 p-0", children: rows.map((task) => {
|
|
4481
4619
|
const dueDateLabel = formatTaskDueDate(task.dueDate);
|
|
4482
4620
|
const overdue = isTaskOverdue(task.dueDate, task.completed);
|
|
4483
|
-
return /* @__PURE__ */
|
|
4621
|
+
return /* @__PURE__ */ jsx22("li", { children: /* @__PURE__ */ jsxs20(
|
|
4484
4622
|
"div",
|
|
4485
4623
|
{
|
|
4486
4624
|
className: "flex items-start gap-2 rounded-lg px-2 py-2 hover:bg-accent/40",
|
|
4487
4625
|
style: { paddingLeft: `${task.depth * 18 + 8}px` },
|
|
4488
4626
|
children: [
|
|
4489
|
-
/* @__PURE__ */
|
|
4490
|
-
/* @__PURE__ */
|
|
4491
|
-
/* @__PURE__ */
|
|
4627
|
+
/* @__PURE__ */ jsx22("span", { className: task.completed ? "text-primary" : "text-muted-foreground", children: task.completed ? "\u2611" : "\u2610" }),
|
|
4628
|
+
/* @__PURE__ */ jsxs20("div", { className: "min-w-0 flex-1", children: [
|
|
4629
|
+
/* @__PURE__ */ jsx22(
|
|
4492
4630
|
"div",
|
|
4493
4631
|
{
|
|
4494
4632
|
className: task.completed ? "truncate text-sm text-muted-foreground line-through" : "truncate text-sm text-foreground",
|
|
4495
4633
|
children: task.title
|
|
4496
4634
|
}
|
|
4497
4635
|
),
|
|
4498
|
-
dueDateLabel ? /* @__PURE__ */
|
|
4636
|
+
dueDateLabel ? /* @__PURE__ */ jsx22(
|
|
4499
4637
|
"div",
|
|
4500
4638
|
{
|
|
4501
4639
|
className: overdue ? "mt-1 text-[11px] text-red-500" : "mt-1 text-[11px] text-muted-foreground",
|