@hachej/boring-core 0.1.20 → 0.1.22
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/{CoreFront-CDeLdfb0.d.ts → CoreFront-CgAkiEts.d.ts} +1 -0
- package/dist/app/front/index.d.ts +1 -1
- package/dist/app/front/index.js +1 -1
- package/dist/app/server/index.d.ts +6 -3
- package/dist/app/server/index.js +221 -69
- package/dist/{authHook-C5ShLjAS.d.ts → authHook-DUqyxueY.d.ts} +2 -2
- package/dist/{chunk-V5CXMFHP.js → chunk-6D7LEQSL.js} +35 -2
- package/dist/chunk-AQBXNPMD.js +17 -0
- package/dist/{chunk-HSRBZLKT.js → chunk-C3YMOITB.js} +17 -0
- package/dist/{chunk-A5TMALZR.js → chunk-JMCBLJ6W.js} +614 -497
- package/dist/{connection-jW1Xwcne.d.ts → connection-AL8KSENV.d.ts} +1 -1
- package/dist/front/index.d.ts +12 -3
- package/dist/front/index.js +3 -1
- package/dist/{migrate-D49JsATX.d.ts → migrate-B4dwdtGP.d.ts} +1 -1
- package/dist/server/db/index.d.ts +4 -4
- package/dist/server/db/index.js +1 -1
- package/dist/server/index.d.ts +37 -6
- package/dist/server/index.js +2 -2
- package/dist/shared/index.d.ts +15 -1
- package/dist/shared/index.js +7 -1
- package/dist/{index-COZa03RP.d.ts → types-CbMOXLBf.d.ts} +8 -0
- package/drizzle/0010_telemetry_events.sql +12 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +4 -4
|
@@ -131,7 +131,9 @@ var routes = {
|
|
|
131
131
|
forgotPassword: "/auth/forgot-password",
|
|
132
132
|
resetPassword: "/auth/reset-password",
|
|
133
133
|
verifyEmail: "/auth/verify-email",
|
|
134
|
+
authError: "/auth/error",
|
|
134
135
|
callbackGithub: "/auth/callback/github",
|
|
136
|
+
callbackGoogle: "/auth/callback/google",
|
|
135
137
|
me: "/me",
|
|
136
138
|
workspaceMembers: "/w/:id/members",
|
|
137
139
|
workspaceInvites: "/w/:id/invites",
|
|
@@ -200,6 +202,9 @@ function useConfig() {
|
|
|
200
202
|
throw new Error("useConfig must be used within a ConfigProvider");
|
|
201
203
|
return ctx;
|
|
202
204
|
}
|
|
205
|
+
function useOptionalConfig() {
|
|
206
|
+
return useContext(ConfigContext);
|
|
207
|
+
}
|
|
203
208
|
function useConfigLoaded() {
|
|
204
209
|
return useContext(ConfigContext) !== null;
|
|
205
210
|
}
|
|
@@ -680,21 +685,67 @@ function useUser() {
|
|
|
680
685
|
return useContext5(UserContext);
|
|
681
686
|
}
|
|
682
687
|
|
|
683
|
-
// src/front/auth/
|
|
688
|
+
// src/front/auth/GoogleAuthButton.tsx
|
|
684
689
|
import { useState as useState7 } from "react";
|
|
690
|
+
import { Button as Button2 } from "@hachej/boring-ui-kit";
|
|
691
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
692
|
+
function GoogleAuthButton({
|
|
693
|
+
callbackURL = "/",
|
|
694
|
+
errorCallbackURL = callbackURL,
|
|
695
|
+
onError
|
|
696
|
+
}) {
|
|
697
|
+
const signIn = useSignIn();
|
|
698
|
+
const [isSubmitting, setIsSubmitting] = useState7(false);
|
|
699
|
+
async function handleClick() {
|
|
700
|
+
setIsSubmitting(true);
|
|
701
|
+
try {
|
|
702
|
+
const result = await signIn.social({ provider: "google", callbackURL, errorCallbackURL });
|
|
703
|
+
if (result?.error) {
|
|
704
|
+
onError?.(result.error.message);
|
|
705
|
+
}
|
|
706
|
+
} catch (error) {
|
|
707
|
+
onError?.(error instanceof Error ? error.message : void 0);
|
|
708
|
+
} finally {
|
|
709
|
+
setIsSubmitting(false);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
return /* @__PURE__ */ jsx7(
|
|
713
|
+
Button2,
|
|
714
|
+
{
|
|
715
|
+
type: "button",
|
|
716
|
+
variant: "outline",
|
|
717
|
+
className: "w-full",
|
|
718
|
+
disabled: isSubmitting,
|
|
719
|
+
onClick: () => void handleClick(),
|
|
720
|
+
children: isSubmitting ? "Redirecting\u2026" : "Continue with Google"
|
|
721
|
+
}
|
|
722
|
+
);
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// src/front/auth/SignInPage.tsx
|
|
726
|
+
import { useState as useState8 } from "react";
|
|
685
727
|
import { useForm } from "react-hook-form";
|
|
686
728
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
687
729
|
import { z } from "zod";
|
|
688
|
-
import { Button as
|
|
689
|
-
import { jsx as
|
|
730
|
+
import { Button as Button3, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Input, Label } from "@hachej/boring-ui-kit";
|
|
731
|
+
import { Fragment, jsx as jsx8, jsxs } from "react/jsx-runtime";
|
|
690
732
|
var signInSchema = z.object({
|
|
691
733
|
email: z.string().email("Please enter a valid email"),
|
|
692
734
|
password: z.string().min(1, "Password is required")
|
|
693
735
|
});
|
|
736
|
+
var DEFAULT_GOOGLE_SIGNIN_ERROR = "We could not complete Google sign in. Please try again or continue with email.";
|
|
737
|
+
function readGoogleAuthError() {
|
|
738
|
+
if (typeof window === "undefined") return null;
|
|
739
|
+
const error = new URLSearchParams(window.location.search).get("error");
|
|
740
|
+
return error ? DEFAULT_GOOGLE_SIGNIN_ERROR : null;
|
|
741
|
+
}
|
|
694
742
|
function SignInPage() {
|
|
695
743
|
const signIn = useSignIn();
|
|
696
|
-
const
|
|
697
|
-
const [
|
|
744
|
+
const config = useOptionalConfig();
|
|
745
|
+
const [serverError, setServerError] = useState8(null);
|
|
746
|
+
const [oauthError, setOauthError] = useState8(() => readGoogleAuthError());
|
|
747
|
+
const [isSubmitting, setIsSubmitting] = useState8(false);
|
|
748
|
+
const showGoogleAuth = config?.features.googleOauth === true;
|
|
698
749
|
const {
|
|
699
750
|
register,
|
|
700
751
|
handleSubmit,
|
|
@@ -704,6 +755,7 @@ function SignInPage() {
|
|
|
704
755
|
});
|
|
705
756
|
async function onSubmit(data) {
|
|
706
757
|
setServerError(null);
|
|
758
|
+
setOauthError(null);
|
|
707
759
|
setIsSubmitting(true);
|
|
708
760
|
try {
|
|
709
761
|
const result = await signIn.email({
|
|
@@ -719,17 +771,30 @@ function SignInPage() {
|
|
|
719
771
|
setIsSubmitting(false);
|
|
720
772
|
}
|
|
721
773
|
}
|
|
722
|
-
return /* @__PURE__ */
|
|
774
|
+
return /* @__PURE__ */ jsx8("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs(Card, { className: "w-full max-w-sm", children: [
|
|
723
775
|
/* @__PURE__ */ jsxs(CardHeader, { children: [
|
|
724
|
-
/* @__PURE__ */
|
|
725
|
-
/* @__PURE__ */
|
|
776
|
+
/* @__PURE__ */ jsx8(CardTitle, { children: "Sign in" }),
|
|
777
|
+
/* @__PURE__ */ jsx8(CardDescription, { children: "Enter your credentials to continue" })
|
|
726
778
|
] }),
|
|
727
779
|
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit(onSubmit), noValidate: true, children: [
|
|
728
780
|
/* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
|
|
729
|
-
|
|
781
|
+
showGoogleAuth && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
782
|
+
/* @__PURE__ */ jsx8(
|
|
783
|
+
GoogleAuthButton,
|
|
784
|
+
{
|
|
785
|
+
errorCallbackURL: routes.signin,
|
|
786
|
+
onError: (message) => setOauthError(message || DEFAULT_GOOGLE_SIGNIN_ERROR)
|
|
787
|
+
}
|
|
788
|
+
),
|
|
789
|
+
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
790
|
+
/* @__PURE__ */ jsx8("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx8("span", { className: "w-full border-t" }) }),
|
|
791
|
+
/* @__PURE__ */ jsx8("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ jsx8("span", { className: "bg-card px-2 text-muted-foreground", children: "Or continue with email" }) })
|
|
792
|
+
] })
|
|
793
|
+
] }),
|
|
794
|
+
(serverError ?? oauthError) && /* @__PURE__ */ jsx8("div", { role: "alert", className: "text-sm text-destructive", children: serverError ?? oauthError }),
|
|
730
795
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
731
|
-
/* @__PURE__ */
|
|
732
|
-
/* @__PURE__ */
|
|
796
|
+
/* @__PURE__ */ jsx8(Label, { htmlFor: "email", children: "Email" }),
|
|
797
|
+
/* @__PURE__ */ jsx8(
|
|
733
798
|
Input,
|
|
734
799
|
{
|
|
735
800
|
id: "email",
|
|
@@ -739,11 +804,11 @@ function SignInPage() {
|
|
|
739
804
|
...register("email")
|
|
740
805
|
}
|
|
741
806
|
),
|
|
742
|
-
errors.email && /* @__PURE__ */
|
|
807
|
+
errors.email && /* @__PURE__ */ jsx8("p", { className: "text-sm text-destructive", children: errors.email.message })
|
|
743
808
|
] }),
|
|
744
809
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
745
|
-
/* @__PURE__ */
|
|
746
|
-
/* @__PURE__ */
|
|
810
|
+
/* @__PURE__ */ jsx8(Label, { htmlFor: "password", children: "Password" }),
|
|
811
|
+
/* @__PURE__ */ jsx8(
|
|
747
812
|
Input,
|
|
748
813
|
{
|
|
749
814
|
id: "password",
|
|
@@ -752,14 +817,14 @@ function SignInPage() {
|
|
|
752
817
|
...register("password")
|
|
753
818
|
}
|
|
754
819
|
),
|
|
755
|
-
errors.password && /* @__PURE__ */
|
|
820
|
+
errors.password && /* @__PURE__ */ jsx8("p", { className: "text-sm text-destructive", children: errors.password.message })
|
|
756
821
|
] })
|
|
757
822
|
] }),
|
|
758
823
|
/* @__PURE__ */ jsxs(CardFooter, { className: "flex flex-col gap-4", children: [
|
|
759
|
-
/* @__PURE__ */
|
|
824
|
+
/* @__PURE__ */ jsx8(Button3, { type: "submit", className: "w-full", disabled: isSubmitting, children: isSubmitting ? "Signing in\u2026" : "Sign in" }),
|
|
760
825
|
/* @__PURE__ */ jsxs("div", { className: "flex justify-between text-sm w-full", children: [
|
|
761
|
-
/* @__PURE__ */
|
|
762
|
-
/* @__PURE__ */
|
|
826
|
+
/* @__PURE__ */ jsx8("a", { href: routes.forgotPassword, className: "text-muted-foreground hover:underline", children: "Forgot password?" }),
|
|
827
|
+
/* @__PURE__ */ jsx8("a", { href: routes.signup, className: "text-muted-foreground hover:underline", children: "Sign up" })
|
|
763
828
|
] })
|
|
764
829
|
] })
|
|
765
830
|
] })
|
|
@@ -767,23 +832,32 @@ function SignInPage() {
|
|
|
767
832
|
}
|
|
768
833
|
|
|
769
834
|
// src/front/auth/SignUpPage.tsx
|
|
770
|
-
import { useState as
|
|
835
|
+
import { useState as useState9 } from "react";
|
|
771
836
|
import { useForm as useForm2 } from "react-hook-form";
|
|
772
837
|
import { zodResolver as zodResolver2 } from "@hookform/resolvers/zod";
|
|
773
838
|
import { z as z2 } from "zod";
|
|
774
|
-
import { Button as
|
|
775
|
-
import { jsx as
|
|
839
|
+
import { Button as Button4, Card as Card2, CardContent as CardContent2, CardDescription as CardDescription2, CardFooter as CardFooter2, CardHeader as CardHeader2, CardTitle as CardTitle2, Input as Input2, Label as Label2 } from "@hachej/boring-ui-kit";
|
|
840
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
776
841
|
var signUpSchema = z2.object({
|
|
777
842
|
name: z2.string().min(1, "Name is required"),
|
|
778
843
|
email: z2.string().email("Please enter a valid email"),
|
|
779
844
|
password: z2.string().min(8, "Password must be at least 8 characters")
|
|
780
845
|
});
|
|
846
|
+
var DEFAULT_GOOGLE_SIGNUP_ERROR = "We could not complete Google sign up. Please try again or continue with email.";
|
|
847
|
+
function readGoogleAuthError2() {
|
|
848
|
+
if (typeof window === "undefined") return null;
|
|
849
|
+
const error = new URLSearchParams(window.location.search).get("error");
|
|
850
|
+
return error ? DEFAULT_GOOGLE_SIGNUP_ERROR : null;
|
|
851
|
+
}
|
|
781
852
|
function SignUpPage() {
|
|
782
853
|
const signUp = useSignUp();
|
|
783
|
-
const
|
|
784
|
-
const [
|
|
785
|
-
const [
|
|
854
|
+
const config = useOptionalConfig();
|
|
855
|
+
const [serverError, setServerError] = useState9(null);
|
|
856
|
+
const [oauthError, setOauthError] = useState9(() => readGoogleAuthError2());
|
|
857
|
+
const [isSubmitting, setIsSubmitting] = useState9(false);
|
|
858
|
+
const [success, setSuccess] = useState9(false);
|
|
786
859
|
const inviteToken = typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("invite_token") : null;
|
|
860
|
+
const showGoogleAuth = config?.features.googleOauth === true && !inviteToken;
|
|
787
861
|
const {
|
|
788
862
|
register,
|
|
789
863
|
handleSubmit,
|
|
@@ -793,6 +867,7 @@ function SignUpPage() {
|
|
|
793
867
|
});
|
|
794
868
|
async function onSubmit(data) {
|
|
795
869
|
setServerError(null);
|
|
870
|
+
setOauthError(null);
|
|
796
871
|
setIsSubmitting(true);
|
|
797
872
|
try {
|
|
798
873
|
const fetchOptions = inviteToken ? { headers: { "x-invite-token": inviteToken } } : void 0;
|
|
@@ -812,25 +887,38 @@ function SignUpPage() {
|
|
|
812
887
|
}
|
|
813
888
|
}
|
|
814
889
|
if (success) {
|
|
815
|
-
return /* @__PURE__ */
|
|
890
|
+
return /* @__PURE__ */ jsx9("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs2(Card2, { className: "w-full max-w-sm", children: [
|
|
816
891
|
/* @__PURE__ */ jsxs2(CardHeader2, { children: [
|
|
817
|
-
/* @__PURE__ */
|
|
818
|
-
/* @__PURE__ */
|
|
892
|
+
/* @__PURE__ */ jsx9(CardTitle2, { children: "Check your email" }),
|
|
893
|
+
/* @__PURE__ */ jsx9(CardDescription2, { children: "We sent a verification link to your email address. Please check your inbox to continue." })
|
|
819
894
|
] }),
|
|
820
|
-
/* @__PURE__ */
|
|
895
|
+
/* @__PURE__ */ jsx9(CardFooter2, { children: /* @__PURE__ */ jsx9("a", { href: routes.signin, className: "text-sm text-muted-foreground hover:underline", children: "Back to sign in" }) })
|
|
821
896
|
] }) });
|
|
822
897
|
}
|
|
823
|
-
return /* @__PURE__ */
|
|
898
|
+
return /* @__PURE__ */ jsx9("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs2(Card2, { className: "w-full max-w-sm", children: [
|
|
824
899
|
/* @__PURE__ */ jsxs2(CardHeader2, { children: [
|
|
825
|
-
/* @__PURE__ */
|
|
826
|
-
/* @__PURE__ */
|
|
900
|
+
/* @__PURE__ */ jsx9(CardTitle2, { children: "Create an account" }),
|
|
901
|
+
/* @__PURE__ */ jsx9(CardDescription2, { children: "Enter your details to get started" })
|
|
827
902
|
] }),
|
|
828
903
|
/* @__PURE__ */ jsxs2("form", { onSubmit: handleSubmit(onSubmit), noValidate: true, children: [
|
|
829
904
|
/* @__PURE__ */ jsxs2(CardContent2, { className: "space-y-4", children: [
|
|
830
|
-
|
|
905
|
+
showGoogleAuth && /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
906
|
+
/* @__PURE__ */ jsx9(
|
|
907
|
+
GoogleAuthButton,
|
|
908
|
+
{
|
|
909
|
+
errorCallbackURL: routes.signup,
|
|
910
|
+
onError: (message) => setOauthError(message || DEFAULT_GOOGLE_SIGNUP_ERROR)
|
|
911
|
+
}
|
|
912
|
+
),
|
|
913
|
+
/* @__PURE__ */ jsxs2("div", { className: "relative", children: [
|
|
914
|
+
/* @__PURE__ */ jsx9("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsx9("span", { className: "w-full border-t" }) }),
|
|
915
|
+
/* @__PURE__ */ jsx9("div", { className: "relative flex justify-center text-xs uppercase", children: /* @__PURE__ */ jsx9("span", { className: "bg-card px-2 text-muted-foreground", children: "Or continue with email" }) })
|
|
916
|
+
] })
|
|
917
|
+
] }),
|
|
918
|
+
(serverError ?? oauthError) && /* @__PURE__ */ jsx9("div", { role: "alert", className: "text-sm text-destructive", children: serverError ?? oauthError }),
|
|
831
919
|
/* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
832
|
-
/* @__PURE__ */
|
|
833
|
-
/* @__PURE__ */
|
|
920
|
+
/* @__PURE__ */ jsx9(Label2, { htmlFor: "name", children: "Name" }),
|
|
921
|
+
/* @__PURE__ */ jsx9(
|
|
834
922
|
Input2,
|
|
835
923
|
{
|
|
836
924
|
id: "name",
|
|
@@ -840,11 +928,11 @@ function SignUpPage() {
|
|
|
840
928
|
...register("name")
|
|
841
929
|
}
|
|
842
930
|
),
|
|
843
|
-
errors.name && /* @__PURE__ */
|
|
931
|
+
errors.name && /* @__PURE__ */ jsx9("p", { className: "text-sm text-destructive", children: errors.name.message })
|
|
844
932
|
] }),
|
|
845
933
|
/* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
846
|
-
/* @__PURE__ */
|
|
847
|
-
/* @__PURE__ */
|
|
934
|
+
/* @__PURE__ */ jsx9(Label2, { htmlFor: "email", children: "Email" }),
|
|
935
|
+
/* @__PURE__ */ jsx9(
|
|
848
936
|
Input2,
|
|
849
937
|
{
|
|
850
938
|
id: "email",
|
|
@@ -854,11 +942,11 @@ function SignUpPage() {
|
|
|
854
942
|
...register("email")
|
|
855
943
|
}
|
|
856
944
|
),
|
|
857
|
-
errors.email && /* @__PURE__ */
|
|
945
|
+
errors.email && /* @__PURE__ */ jsx9("p", { className: "text-sm text-destructive", children: errors.email.message })
|
|
858
946
|
] }),
|
|
859
947
|
/* @__PURE__ */ jsxs2("div", { className: "space-y-2", children: [
|
|
860
|
-
/* @__PURE__ */
|
|
861
|
-
/* @__PURE__ */
|
|
948
|
+
/* @__PURE__ */ jsx9(Label2, { htmlFor: "password", children: "Password" }),
|
|
949
|
+
/* @__PURE__ */ jsx9(
|
|
862
950
|
Input2,
|
|
863
951
|
{
|
|
864
952
|
id: "password",
|
|
@@ -868,14 +956,14 @@ function SignUpPage() {
|
|
|
868
956
|
...register("password")
|
|
869
957
|
}
|
|
870
958
|
),
|
|
871
|
-
errors.password && /* @__PURE__ */
|
|
959
|
+
errors.password && /* @__PURE__ */ jsx9("p", { className: "text-sm text-destructive", children: errors.password.message })
|
|
872
960
|
] })
|
|
873
961
|
] }),
|
|
874
962
|
/* @__PURE__ */ jsxs2(CardFooter2, { className: "flex flex-col gap-4", children: [
|
|
875
|
-
/* @__PURE__ */
|
|
963
|
+
/* @__PURE__ */ jsx9(Button4, { type: "submit", className: "w-full", disabled: isSubmitting, children: isSubmitting ? "Creating account\u2026" : "Sign up" }),
|
|
876
964
|
/* @__PURE__ */ jsxs2("div", { className: "text-sm text-center", children: [
|
|
877
|
-
/* @__PURE__ */
|
|
878
|
-
/* @__PURE__ */
|
|
965
|
+
/* @__PURE__ */ jsx9("span", { className: "text-muted-foreground", children: "Already have an account? " }),
|
|
966
|
+
/* @__PURE__ */ jsx9("a", { href: routes.signin, className: "hover:underline", children: "Sign in" })
|
|
879
967
|
] })
|
|
880
968
|
] })
|
|
881
969
|
] })
|
|
@@ -883,19 +971,19 @@ function SignUpPage() {
|
|
|
883
971
|
}
|
|
884
972
|
|
|
885
973
|
// src/front/auth/ForgotPasswordPage.tsx
|
|
886
|
-
import { useState as
|
|
974
|
+
import { useState as useState10 } from "react";
|
|
887
975
|
import { useForm as useForm3 } from "react-hook-form";
|
|
888
976
|
import { zodResolver as zodResolver3 } from "@hookform/resolvers/zod";
|
|
889
977
|
import { z as z3 } from "zod";
|
|
890
|
-
import { Button as
|
|
891
|
-
import { jsx as
|
|
978
|
+
import { Button as Button5, Card as Card3, CardContent as CardContent3, CardDescription as CardDescription3, CardFooter as CardFooter3, CardHeader as CardHeader3, CardTitle as CardTitle3, Input as Input3, Label as Label3 } from "@hachej/boring-ui-kit";
|
|
979
|
+
import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
892
980
|
var forgotSchema = z3.object({
|
|
893
981
|
email: z3.string().email("Please enter a valid email")
|
|
894
982
|
});
|
|
895
983
|
function ForgotPasswordPage() {
|
|
896
984
|
const forgetPassword = useForgetPassword();
|
|
897
|
-
const [isSubmitting, setIsSubmitting] =
|
|
898
|
-
const [submitted, setSubmitted] =
|
|
985
|
+
const [isSubmitting, setIsSubmitting] = useState10(false);
|
|
986
|
+
const [submitted, setSubmitted] = useState10(false);
|
|
899
987
|
const {
|
|
900
988
|
register,
|
|
901
989
|
handleSubmit,
|
|
@@ -914,23 +1002,23 @@ function ForgotPasswordPage() {
|
|
|
914
1002
|
}
|
|
915
1003
|
}
|
|
916
1004
|
if (submitted) {
|
|
917
|
-
return /* @__PURE__ */
|
|
1005
|
+
return /* @__PURE__ */ jsx10("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs3(Card3, { className: "w-full max-w-sm", children: [
|
|
918
1006
|
/* @__PURE__ */ jsxs3(CardHeader3, { children: [
|
|
919
|
-
/* @__PURE__ */
|
|
920
|
-
/* @__PURE__ */
|
|
1007
|
+
/* @__PURE__ */ jsx10(CardTitle3, { children: "Check your inbox" }),
|
|
1008
|
+
/* @__PURE__ */ jsx10(CardDescription3, { children: "If an account exists with that email, we sent a password reset link. Check your inbox and follow the instructions." })
|
|
921
1009
|
] }),
|
|
922
|
-
/* @__PURE__ */
|
|
1010
|
+
/* @__PURE__ */ jsx10(CardFooter3, { children: /* @__PURE__ */ jsx10("a", { href: routes.signin, className: "text-sm text-muted-foreground hover:underline", children: "Back to sign in" }) })
|
|
923
1011
|
] }) });
|
|
924
1012
|
}
|
|
925
|
-
return /* @__PURE__ */
|
|
1013
|
+
return /* @__PURE__ */ jsx10("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs3(Card3, { className: "w-full max-w-sm", children: [
|
|
926
1014
|
/* @__PURE__ */ jsxs3(CardHeader3, { children: [
|
|
927
|
-
/* @__PURE__ */
|
|
928
|
-
/* @__PURE__ */
|
|
1015
|
+
/* @__PURE__ */ jsx10(CardTitle3, { children: "Forgot password" }),
|
|
1016
|
+
/* @__PURE__ */ jsx10(CardDescription3, { children: "Enter your email and we'll send you a reset link" })
|
|
929
1017
|
] }),
|
|
930
1018
|
/* @__PURE__ */ jsxs3("form", { onSubmit: handleSubmit(onSubmit), noValidate: true, children: [
|
|
931
|
-
/* @__PURE__ */
|
|
932
|
-
/* @__PURE__ */
|
|
933
|
-
/* @__PURE__ */
|
|
1019
|
+
/* @__PURE__ */ jsx10(CardContent3, { className: "space-y-4", children: /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
|
|
1020
|
+
/* @__PURE__ */ jsx10(Label3, { htmlFor: "email", children: "Email" }),
|
|
1021
|
+
/* @__PURE__ */ jsx10(
|
|
934
1022
|
Input3,
|
|
935
1023
|
{
|
|
936
1024
|
id: "email",
|
|
@@ -940,23 +1028,23 @@ function ForgotPasswordPage() {
|
|
|
940
1028
|
...register("email")
|
|
941
1029
|
}
|
|
942
1030
|
),
|
|
943
|
-
errors.email && /* @__PURE__ */
|
|
1031
|
+
errors.email && /* @__PURE__ */ jsx10("p", { className: "text-sm text-destructive", children: errors.email.message })
|
|
944
1032
|
] }) }),
|
|
945
1033
|
/* @__PURE__ */ jsxs3(CardFooter3, { className: "flex flex-col gap-4", children: [
|
|
946
|
-
/* @__PURE__ */
|
|
947
|
-
/* @__PURE__ */
|
|
1034
|
+
/* @__PURE__ */ jsx10(Button5, { type: "submit", className: "w-full", disabled: isSubmitting, children: isSubmitting ? "Sending\u2026" : "Send reset link" }),
|
|
1035
|
+
/* @__PURE__ */ jsx10("a", { href: routes.signin, className: "text-sm text-muted-foreground hover:underline", children: "Back to sign in" })
|
|
948
1036
|
] })
|
|
949
1037
|
] })
|
|
950
1038
|
] }) });
|
|
951
1039
|
}
|
|
952
1040
|
|
|
953
1041
|
// src/front/auth/ResetPasswordPage.tsx
|
|
954
|
-
import { useState as
|
|
1042
|
+
import { useState as useState11 } from "react";
|
|
955
1043
|
import { useForm as useForm4 } from "react-hook-form";
|
|
956
1044
|
import { zodResolver as zodResolver4 } from "@hookform/resolvers/zod";
|
|
957
1045
|
import { z as z4 } from "zod";
|
|
958
|
-
import { Button as
|
|
959
|
-
import { jsx as
|
|
1046
|
+
import { Button as Button6, Card as Card4, CardContent as CardContent4, CardDescription as CardDescription4, CardFooter as CardFooter4, CardHeader as CardHeader4, CardTitle as CardTitle4, Input as Input4, Label as Label4 } from "@hachej/boring-ui-kit";
|
|
1047
|
+
import { jsx as jsx11, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
960
1048
|
var resetSchema = z4.object({
|
|
961
1049
|
password: z4.string().min(8, "Password must be at least 8 characters"),
|
|
962
1050
|
confirmPassword: z4.string()
|
|
@@ -966,9 +1054,9 @@ var resetSchema = z4.object({
|
|
|
966
1054
|
});
|
|
967
1055
|
function ResetPasswordPage() {
|
|
968
1056
|
const resetPassword = useResetPassword();
|
|
969
|
-
const [serverError, setServerError] =
|
|
970
|
-
const [isSubmitting, setIsSubmitting] =
|
|
971
|
-
const [expired, setExpired] =
|
|
1057
|
+
const [serverError, setServerError] = useState11(null);
|
|
1058
|
+
const [isSubmitting, setIsSubmitting] = useState11(false);
|
|
1059
|
+
const [expired, setExpired] = useState11(false);
|
|
972
1060
|
const token = typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("token") : null;
|
|
973
1061
|
const {
|
|
974
1062
|
register,
|
|
@@ -1006,25 +1094,25 @@ function ResetPasswordPage() {
|
|
|
1006
1094
|
}
|
|
1007
1095
|
}
|
|
1008
1096
|
if (!token || expired) {
|
|
1009
|
-
return /* @__PURE__ */
|
|
1097
|
+
return /* @__PURE__ */ jsx11("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs4(Card4, { className: "w-full max-w-sm", children: [
|
|
1010
1098
|
/* @__PURE__ */ jsxs4(CardHeader4, { children: [
|
|
1011
|
-
/* @__PURE__ */
|
|
1012
|
-
/* @__PURE__ */
|
|
1099
|
+
/* @__PURE__ */ jsx11(CardTitle4, { children: "Link expired" }),
|
|
1100
|
+
/* @__PURE__ */ jsx11(CardDescription4, { children: "This reset link is no longer valid. Please request a new one." })
|
|
1013
1101
|
] }),
|
|
1014
|
-
/* @__PURE__ */
|
|
1102
|
+
/* @__PURE__ */ jsx11(CardFooter4, { children: /* @__PURE__ */ jsx11("a", { href: routes.forgotPassword, children: /* @__PURE__ */ jsx11(Button6, { variant: "outline", children: "Request new link" }) }) })
|
|
1015
1103
|
] }) });
|
|
1016
1104
|
}
|
|
1017
|
-
return /* @__PURE__ */
|
|
1105
|
+
return /* @__PURE__ */ jsx11("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs4(Card4, { className: "w-full max-w-sm", children: [
|
|
1018
1106
|
/* @__PURE__ */ jsxs4(CardHeader4, { children: [
|
|
1019
|
-
/* @__PURE__ */
|
|
1020
|
-
/* @__PURE__ */
|
|
1107
|
+
/* @__PURE__ */ jsx11(CardTitle4, { children: "Reset password" }),
|
|
1108
|
+
/* @__PURE__ */ jsx11(CardDescription4, { children: "Enter your new password below" })
|
|
1021
1109
|
] }),
|
|
1022
1110
|
/* @__PURE__ */ jsxs4("form", { onSubmit: handleSubmit(onSubmit), noValidate: true, children: [
|
|
1023
1111
|
/* @__PURE__ */ jsxs4(CardContent4, { className: "space-y-4", children: [
|
|
1024
|
-
serverError && /* @__PURE__ */
|
|
1112
|
+
serverError && /* @__PURE__ */ jsx11("div", { role: "alert", className: "text-sm text-destructive", children: serverError }),
|
|
1025
1113
|
/* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
|
|
1026
|
-
/* @__PURE__ */
|
|
1027
|
-
/* @__PURE__ */
|
|
1114
|
+
/* @__PURE__ */ jsx11(Label4, { htmlFor: "password", children: "New password" }),
|
|
1115
|
+
/* @__PURE__ */ jsx11(
|
|
1028
1116
|
Input4,
|
|
1029
1117
|
{
|
|
1030
1118
|
id: "password",
|
|
@@ -1034,11 +1122,11 @@ function ResetPasswordPage() {
|
|
|
1034
1122
|
...register("password")
|
|
1035
1123
|
}
|
|
1036
1124
|
),
|
|
1037
|
-
errors.password && /* @__PURE__ */
|
|
1125
|
+
errors.password && /* @__PURE__ */ jsx11("p", { className: "text-sm text-destructive", children: errors.password.message })
|
|
1038
1126
|
] }),
|
|
1039
1127
|
/* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
|
|
1040
|
-
/* @__PURE__ */
|
|
1041
|
-
/* @__PURE__ */
|
|
1128
|
+
/* @__PURE__ */ jsx11(Label4, { htmlFor: "confirmPassword", children: "Confirm password" }),
|
|
1129
|
+
/* @__PURE__ */ jsx11(
|
|
1042
1130
|
Input4,
|
|
1043
1131
|
{
|
|
1044
1132
|
id: "confirmPassword",
|
|
@@ -1047,18 +1135,18 @@ function ResetPasswordPage() {
|
|
|
1047
1135
|
...register("confirmPassword")
|
|
1048
1136
|
}
|
|
1049
1137
|
),
|
|
1050
|
-
errors.confirmPassword && /* @__PURE__ */
|
|
1138
|
+
errors.confirmPassword && /* @__PURE__ */ jsx11("p", { className: "text-sm text-destructive", children: errors.confirmPassword.message })
|
|
1051
1139
|
] })
|
|
1052
1140
|
] }),
|
|
1053
|
-
/* @__PURE__ */
|
|
1141
|
+
/* @__PURE__ */ jsx11(CardFooter4, { children: /* @__PURE__ */ jsx11(Button6, { type: "submit", className: "w-full", disabled: isSubmitting, children: isSubmitting ? "Resetting\u2026" : "Reset password" }) })
|
|
1054
1142
|
] })
|
|
1055
1143
|
] }) });
|
|
1056
1144
|
}
|
|
1057
1145
|
|
|
1058
1146
|
// src/front/auth/VerifyEmailPage.tsx
|
|
1059
|
-
import { useCallback as useCallback3, useEffect as useEffect8, useRef as useRef4, useState as
|
|
1060
|
-
import { Button as
|
|
1061
|
-
import { jsx as
|
|
1147
|
+
import { useCallback as useCallback3, useEffect as useEffect8, useRef as useRef4, useState as useState12 } from "react";
|
|
1148
|
+
import { Button as Button7, Card as Card5, CardContent as CardContent5, CardDescription as CardDescription5, CardFooter as CardFooter5, CardHeader as CardHeader5, CardTitle as CardTitle5, Input as Input5, Label as Label5 } from "@hachej/boring-ui-kit";
|
|
1149
|
+
import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1062
1150
|
function getCookie(name) {
|
|
1063
1151
|
const match = document.cookie.match(new RegExp(`(?:^|; )${name}=([^;]*)`));
|
|
1064
1152
|
return match ? decodeURIComponent(match[1]) : null;
|
|
@@ -1071,11 +1159,11 @@ function VerifyEmailPage() {
|
|
|
1071
1159
|
const verifyEmail = useVerifyEmail();
|
|
1072
1160
|
const sendVerificationEmail = useSendVerificationEmail();
|
|
1073
1161
|
const token = typeof window !== "undefined" ? new URLSearchParams(window.location.search).get("token") : null;
|
|
1074
|
-
const [status, setStatus] =
|
|
1075
|
-
const [inviteWarning, setInviteWarning] =
|
|
1076
|
-
const [cooldown, setCooldown] =
|
|
1077
|
-
const [resendEmail, setResendEmail] =
|
|
1078
|
-
const [resendSent, setResendSent] =
|
|
1162
|
+
const [status, setStatus] = useState12(token ? "verifying" : "no-token");
|
|
1163
|
+
const [inviteWarning, setInviteWarning] = useState12(null);
|
|
1164
|
+
const [cooldown, setCooldown] = useState12(0);
|
|
1165
|
+
const [resendEmail, setResendEmail] = useState12("");
|
|
1166
|
+
const [resendSent, setResendSent] = useState12(false);
|
|
1079
1167
|
const verifiedRef = useRef4(false);
|
|
1080
1168
|
const sessionEmail = session.data?.user?.email ?? null;
|
|
1081
1169
|
useEffect8(() => {
|
|
@@ -1130,8 +1218,8 @@ function VerifyEmailPage() {
|
|
|
1130
1218
|
setResendSent(true);
|
|
1131
1219
|
setCooldown(60);
|
|
1132
1220
|
}, [sessionEmail, resendEmail, cooldown, sendVerificationEmail]);
|
|
1133
|
-
const resendButton = /* @__PURE__ */
|
|
1134
|
-
|
|
1221
|
+
const resendButton = /* @__PURE__ */ jsx12(
|
|
1222
|
+
Button7,
|
|
1135
1223
|
{
|
|
1136
1224
|
variant: "outline",
|
|
1137
1225
|
className: "w-full",
|
|
@@ -1142,8 +1230,8 @@ function VerifyEmailPage() {
|
|
|
1142
1230
|
);
|
|
1143
1231
|
const resendSection = /* @__PURE__ */ jsxs5("div", { className: "space-y-3", children: [
|
|
1144
1232
|
!sessionEmail && /* @__PURE__ */ jsxs5("div", { className: "space-y-2", children: [
|
|
1145
|
-
/* @__PURE__ */
|
|
1146
|
-
/* @__PURE__ */
|
|
1233
|
+
/* @__PURE__ */ jsx12(Label5, { htmlFor: "resend-email", children: "Email" }),
|
|
1234
|
+
/* @__PURE__ */ jsx12(
|
|
1147
1235
|
Input5,
|
|
1148
1236
|
{
|
|
1149
1237
|
id: "resend-email",
|
|
@@ -1155,48 +1243,48 @@ function VerifyEmailPage() {
|
|
|
1155
1243
|
)
|
|
1156
1244
|
] }),
|
|
1157
1245
|
resendButton,
|
|
1158
|
-
resendSent && /* @__PURE__ */
|
|
1246
|
+
resendSent && /* @__PURE__ */ jsx12("p", { className: "text-sm text-muted-foreground text-center", children: "If an account exists with that email, we sent a new verification link." })
|
|
1159
1247
|
] });
|
|
1160
1248
|
if (status === "verifying") {
|
|
1161
|
-
return /* @__PURE__ */
|
|
1162
|
-
/* @__PURE__ */
|
|
1163
|
-
/* @__PURE__ */
|
|
1249
|
+
return /* @__PURE__ */ jsx12("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsx12(Card5, { className: "w-full max-w-sm", children: /* @__PURE__ */ jsxs5(CardHeader5, { children: [
|
|
1250
|
+
/* @__PURE__ */ jsx12(CardTitle5, { children: "Verifying your email" }),
|
|
1251
|
+
/* @__PURE__ */ jsx12(CardDescription5, { children: "Please wait\u2026" })
|
|
1164
1252
|
] }) }) });
|
|
1165
1253
|
}
|
|
1166
1254
|
if (status === "verified") {
|
|
1167
|
-
return /* @__PURE__ */
|
|
1168
|
-
inviteWarning && /* @__PURE__ */
|
|
1255
|
+
return /* @__PURE__ */ jsx12("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs5(Card5, { className: "w-full max-w-sm", children: [
|
|
1256
|
+
inviteWarning && /* @__PURE__ */ jsx12("div", { role: "status", className: "px-6 pt-4", children: /* @__PURE__ */ jsx12("div", { className: "rounded-md bg-muted px-3 py-2 text-sm text-muted-foreground", children: inviteWarning }) }),
|
|
1169
1257
|
/* @__PURE__ */ jsxs5(CardHeader5, { children: [
|
|
1170
|
-
/* @__PURE__ */
|
|
1171
|
-
/* @__PURE__ */
|
|
1258
|
+
/* @__PURE__ */ jsx12(CardTitle5, { children: "Email verified" }),
|
|
1259
|
+
/* @__PURE__ */ jsx12(CardDescription5, { children: "Your email has been verified. You can now continue." })
|
|
1172
1260
|
] }),
|
|
1173
|
-
/* @__PURE__ */
|
|
1261
|
+
/* @__PURE__ */ jsx12(CardFooter5, { children: /* @__PURE__ */ jsx12("a", { href: "/", className: "w-full", children: /* @__PURE__ */ jsx12(Button7, { className: "w-full", children: "Continue" }) }) })
|
|
1174
1262
|
] }) });
|
|
1175
1263
|
}
|
|
1176
1264
|
if (status === "expired") {
|
|
1177
|
-
return /* @__PURE__ */
|
|
1178
|
-
inviteWarning && /* @__PURE__ */
|
|
1265
|
+
return /* @__PURE__ */ jsx12("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs5(Card5, { className: "w-full max-w-sm", children: [
|
|
1266
|
+
inviteWarning && /* @__PURE__ */ jsx12("div", { role: "status", className: "px-6 pt-4", children: /* @__PURE__ */ jsx12("div", { className: "rounded-md bg-muted px-3 py-2 text-sm text-muted-foreground", children: inviteWarning }) }),
|
|
1179
1267
|
/* @__PURE__ */ jsxs5(CardHeader5, { children: [
|
|
1180
|
-
/* @__PURE__ */
|
|
1181
|
-
/* @__PURE__ */
|
|
1268
|
+
/* @__PURE__ */ jsx12(CardTitle5, { children: "Link expired" }),
|
|
1269
|
+
/* @__PURE__ */ jsx12(CardDescription5, { children: "This verification link is no longer valid. Request a new one below." })
|
|
1182
1270
|
] }),
|
|
1183
|
-
/* @__PURE__ */
|
|
1184
|
-
/* @__PURE__ */
|
|
1271
|
+
/* @__PURE__ */ jsx12(CardContent5, { children: resendSection }),
|
|
1272
|
+
/* @__PURE__ */ jsx12(CardFooter5, { children: /* @__PURE__ */ jsx12("a", { href: routes.signin, className: "text-sm text-muted-foreground hover:underline", children: "Back to sign in" }) })
|
|
1185
1273
|
] }) });
|
|
1186
1274
|
}
|
|
1187
|
-
return /* @__PURE__ */
|
|
1188
|
-
inviteWarning && /* @__PURE__ */
|
|
1275
|
+
return /* @__PURE__ */ jsx12("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs5(Card5, { className: "w-full max-w-sm", children: [
|
|
1276
|
+
inviteWarning && /* @__PURE__ */ jsx12("div", { role: "status", className: "px-6 pt-4", children: /* @__PURE__ */ jsx12("div", { className: "rounded-md bg-muted px-3 py-2 text-sm text-muted-foreground", children: inviteWarning }) }),
|
|
1189
1277
|
/* @__PURE__ */ jsxs5(CardHeader5, { children: [
|
|
1190
|
-
/* @__PURE__ */
|
|
1191
|
-
/* @__PURE__ */
|
|
1278
|
+
/* @__PURE__ */ jsx12(CardTitle5, { children: "Invalid verification link" }),
|
|
1279
|
+
/* @__PURE__ */ jsx12(CardDescription5, { children: status === "no-token" ? "No verification token found. Check the link in your email." : "This verification link is invalid. Request a new one below." })
|
|
1192
1280
|
] }),
|
|
1193
|
-
/* @__PURE__ */
|
|
1194
|
-
/* @__PURE__ */
|
|
1281
|
+
/* @__PURE__ */ jsx12(CardContent5, { children: resendSection }),
|
|
1282
|
+
/* @__PURE__ */ jsx12(CardFooter5, { children: /* @__PURE__ */ jsx12("a", { href: routes.signin, className: "text-sm text-muted-foreground hover:underline", children: "Back to sign in" }) })
|
|
1195
1283
|
] }) });
|
|
1196
1284
|
}
|
|
1197
1285
|
|
|
1198
1286
|
// src/front/auth/UserSettingsPage.tsx
|
|
1199
|
-
import { useCallback as useCallback4, useState as
|
|
1287
|
+
import { useCallback as useCallback4, useState as useState13 } from "react";
|
|
1200
1288
|
import { useForm as useForm5 } from "react-hook-form";
|
|
1201
1289
|
import { zodResolver as zodResolver5 } from "@hookform/resolvers/zod";
|
|
1202
1290
|
import { z as z5 } from "zod";
|
|
@@ -1209,7 +1297,7 @@ import {
|
|
|
1209
1297
|
AlertDialogHeader,
|
|
1210
1298
|
AlertDialogTitle,
|
|
1211
1299
|
AlertDialogTrigger,
|
|
1212
|
-
Button as
|
|
1300
|
+
Button as Button8,
|
|
1213
1301
|
DetailLine as UiDetailLine,
|
|
1214
1302
|
DetailList,
|
|
1215
1303
|
Input as Input6,
|
|
@@ -1228,7 +1316,7 @@ import {
|
|
|
1228
1316
|
Trash2,
|
|
1229
1317
|
UserRound
|
|
1230
1318
|
} from "lucide-react";
|
|
1231
|
-
import { jsx as
|
|
1319
|
+
import { jsx as jsx13, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1232
1320
|
var changePasswordSchema = z5.object({
|
|
1233
1321
|
currentPassword: z5.string().min(1, "Current password is required"),
|
|
1234
1322
|
newPassword: z5.string().min(8, "Password must be at least 8 characters"),
|
|
@@ -1251,13 +1339,13 @@ function formatMemberSince(value) {
|
|
|
1251
1339
|
});
|
|
1252
1340
|
}
|
|
1253
1341
|
function SettingsTopBar() {
|
|
1254
|
-
return /* @__PURE__ */
|
|
1342
|
+
return /* @__PURE__ */ jsx13(
|
|
1255
1343
|
"header",
|
|
1256
1344
|
{
|
|
1257
1345
|
className: "relative flex h-[52px] items-center justify-between gap-3 border-b border-border/40 bg-background px-4",
|
|
1258
1346
|
"aria-label": "App top bar",
|
|
1259
1347
|
children: /* @__PURE__ */ jsxs6("div", { className: "flex min-w-0 flex-1 items-center gap-2.5", children: [
|
|
1260
|
-
/* @__PURE__ */
|
|
1348
|
+
/* @__PURE__ */ jsx13(
|
|
1261
1349
|
"div",
|
|
1262
1350
|
{
|
|
1263
1351
|
"aria-hidden": "true",
|
|
@@ -1265,9 +1353,9 @@ function SettingsTopBar() {
|
|
|
1265
1353
|
children: "B"
|
|
1266
1354
|
}
|
|
1267
1355
|
),
|
|
1268
|
-
/* @__PURE__ */
|
|
1269
|
-
/* @__PURE__ */
|
|
1270
|
-
/* @__PURE__ */
|
|
1356
|
+
/* @__PURE__ */ jsx13("span", { className: "truncate text-[13px] font-medium tracking-tight text-foreground", children: "Boring" }),
|
|
1357
|
+
/* @__PURE__ */ jsx13("span", { "aria-hidden": "true", className: "text-muted-foreground/30", children: "/" }),
|
|
1358
|
+
/* @__PURE__ */ jsx13("span", { className: "truncate text-[13px] text-muted-foreground", children: "Account settings" })
|
|
1271
1359
|
] })
|
|
1272
1360
|
}
|
|
1273
1361
|
);
|
|
@@ -1279,7 +1367,7 @@ function SettingsPageHeader({
|
|
|
1279
1367
|
}) {
|
|
1280
1368
|
return /* @__PURE__ */ jsxs6("header", { className: "boring-settings-page-header", children: [
|
|
1281
1369
|
/* @__PURE__ */ jsxs6("div", { className: "boring-settings-context", children: [
|
|
1282
|
-
/* @__PURE__ */
|
|
1370
|
+
/* @__PURE__ */ jsx13("div", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-foreground text-[12px] font-semibold text-background", children: initials }),
|
|
1283
1371
|
/* @__PURE__ */ jsxs6("div", { className: "min-w-0", children: [
|
|
1284
1372
|
/* @__PURE__ */ jsxs6("p", { className: "truncate text-[13px] font-medium text-foreground", children: [
|
|
1285
1373
|
"Signed in as ",
|
|
@@ -1292,9 +1380,9 @@ function SettingsPageHeader({
|
|
|
1292
1380
|
] })
|
|
1293
1381
|
] }),
|
|
1294
1382
|
/* @__PURE__ */ jsxs6("div", { className: "max-w-2xl", children: [
|
|
1295
|
-
/* @__PURE__ */
|
|
1296
|
-
/* @__PURE__ */
|
|
1297
|
-
/* @__PURE__ */
|
|
1383
|
+
/* @__PURE__ */ jsx13("p", { className: "text-[11px] font-medium uppercase leading-4 text-muted-foreground", children: "Account" }),
|
|
1384
|
+
/* @__PURE__ */ jsx13("h1", { className: "mt-1 text-[20px] font-semibold leading-7 tracking-tight text-foreground", children: "Account settings" }),
|
|
1385
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-2 text-[13px] leading-5 text-muted-foreground", children: "Review your profile, change your password, and manage account-level actions." })
|
|
1298
1386
|
] })
|
|
1299
1387
|
] });
|
|
1300
1388
|
}
|
|
@@ -1309,13 +1397,13 @@ function UserSettingsPage({ topBar } = {}) {
|
|
|
1309
1397
|
const signOut = useSignOut();
|
|
1310
1398
|
const changePassword = useChangePassword();
|
|
1311
1399
|
const user = identity?.user ?? session.data?.user ?? null;
|
|
1312
|
-
const [passwordError, setPasswordError] =
|
|
1313
|
-
const [passwordSuccess, setPasswordSuccess] =
|
|
1314
|
-
const [isChangingPassword, setIsChangingPassword] =
|
|
1315
|
-
const [deleteConfirm, setDeleteConfirm] =
|
|
1316
|
-
const [deleteError, setDeleteError] =
|
|
1317
|
-
const [isDeleting, setIsDeleting] =
|
|
1318
|
-
const [deleteDialogOpen, setDeleteDialogOpen] =
|
|
1400
|
+
const [passwordError, setPasswordError] = useState13(null);
|
|
1401
|
+
const [passwordSuccess, setPasswordSuccess] = useState13(false);
|
|
1402
|
+
const [isChangingPassword, setIsChangingPassword] = useState13(false);
|
|
1403
|
+
const [deleteConfirm, setDeleteConfirm] = useState13("");
|
|
1404
|
+
const [deleteError, setDeleteError] = useState13(null);
|
|
1405
|
+
const [isDeleting, setIsDeleting] = useState13(false);
|
|
1406
|
+
const [deleteDialogOpen, setDeleteDialogOpen] = useState13(false);
|
|
1319
1407
|
const {
|
|
1320
1408
|
register,
|
|
1321
1409
|
handleSubmit,
|
|
@@ -1373,23 +1461,23 @@ function UserSettingsPage({ topBar } = {}) {
|
|
|
1373
1461
|
setIsDeleting(false);
|
|
1374
1462
|
}
|
|
1375
1463
|
}, [user?.email, signOut]);
|
|
1376
|
-
const topBarNode = topBar === void 0 ? /* @__PURE__ */
|
|
1464
|
+
const topBarNode = topBar === void 0 ? /* @__PURE__ */ jsx13(SettingsTopBar, {}) : topBar;
|
|
1377
1465
|
if (!user) {
|
|
1378
1466
|
return /* @__PURE__ */ jsxs6("main", { className: "boring-settings-shell", children: [
|
|
1379
1467
|
topBarNode,
|
|
1380
|
-
/* @__PURE__ */
|
|
1381
|
-
/* @__PURE__ */
|
|
1382
|
-
/* @__PURE__ */
|
|
1468
|
+
/* @__PURE__ */ jsx13("div", { className: "boring-settings-scroll", children: /* @__PURE__ */ jsx13("div", { className: "mx-auto flex min-h-full w-full max-w-5xl items-center justify-center px-4", children: /* @__PURE__ */ jsxs6("div", { className: "w-full max-w-sm rounded-lg border border-border/60 bg-background p-4", children: [
|
|
1469
|
+
/* @__PURE__ */ jsx13("h1", { className: "text-[13px] font-medium", children: "Account settings" }),
|
|
1470
|
+
/* @__PURE__ */ jsx13("p", { className: "mt-1 text-[12px] text-muted-foreground", children: "Loading your account..." })
|
|
1383
1471
|
] }) }) })
|
|
1384
1472
|
] });
|
|
1385
1473
|
}
|
|
1386
1474
|
const initials = initialsFor(user.name, user.email);
|
|
1387
1475
|
return /* @__PURE__ */ jsxs6("main", { className: "boring-settings-shell", children: [
|
|
1388
1476
|
topBarNode,
|
|
1389
|
-
/* @__PURE__ */
|
|
1390
|
-
/* @__PURE__ */
|
|
1477
|
+
/* @__PURE__ */ jsx13("div", { className: "boring-settings-scroll", children: /* @__PURE__ */ jsxs6("div", { className: "boring-settings-layout", children: [
|
|
1478
|
+
/* @__PURE__ */ jsx13("aside", { className: "boring-settings-sidebar", children: /* @__PURE__ */ jsx13(UiSettingsNav, { label: "Account settings", items: ACCOUNT_NAV_ITEMS }) }),
|
|
1391
1479
|
/* @__PURE__ */ jsxs6("div", { className: "boring-settings-content space-y-4", children: [
|
|
1392
|
-
/* @__PURE__ */
|
|
1480
|
+
/* @__PURE__ */ jsx13(
|
|
1393
1481
|
SettingsPageHeader,
|
|
1394
1482
|
{
|
|
1395
1483
|
initials,
|
|
@@ -1397,64 +1485,64 @@ function UserSettingsPage({ topBar } = {}) {
|
|
|
1397
1485
|
email: user.email
|
|
1398
1486
|
}
|
|
1399
1487
|
),
|
|
1400
|
-
/* @__PURE__ */
|
|
1488
|
+
/* @__PURE__ */ jsx13(
|
|
1401
1489
|
UiSettingsPanel,
|
|
1402
1490
|
{
|
|
1403
1491
|
id: "profile",
|
|
1404
|
-
icon: /* @__PURE__ */
|
|
1492
|
+
icon: /* @__PURE__ */ jsx13(UserRound, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
1405
1493
|
title: "Profile",
|
|
1406
1494
|
description: "The identity shown inside this app.",
|
|
1407
1495
|
children: /* @__PURE__ */ jsxs6(DetailList, { children: [
|
|
1408
|
-
/* @__PURE__ */
|
|
1496
|
+
/* @__PURE__ */ jsx13(
|
|
1409
1497
|
UiDetailLine,
|
|
1410
1498
|
{
|
|
1411
|
-
icon: /* @__PURE__ */
|
|
1499
|
+
icon: /* @__PURE__ */ jsx13(Mail, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
1412
1500
|
label: "Email",
|
|
1413
|
-
children: /* @__PURE__ */
|
|
1501
|
+
children: /* @__PURE__ */ jsx13("p", { className: "truncate", children: user.email })
|
|
1414
1502
|
}
|
|
1415
1503
|
),
|
|
1416
|
-
/* @__PURE__ */
|
|
1504
|
+
/* @__PURE__ */ jsx13(
|
|
1417
1505
|
UiDetailLine,
|
|
1418
1506
|
{
|
|
1419
|
-
icon: /* @__PURE__ */
|
|
1507
|
+
icon: /* @__PURE__ */ jsx13(UserRound, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
1420
1508
|
label: "Name",
|
|
1421
|
-
children: /* @__PURE__ */
|
|
1509
|
+
children: /* @__PURE__ */ jsx13("p", { className: "truncate", children: user.name ?? "Not set" })
|
|
1422
1510
|
}
|
|
1423
1511
|
),
|
|
1424
|
-
/* @__PURE__ */
|
|
1512
|
+
/* @__PURE__ */ jsx13(
|
|
1425
1513
|
UiDetailLine,
|
|
1426
1514
|
{
|
|
1427
|
-
icon: /* @__PURE__ */
|
|
1515
|
+
icon: /* @__PURE__ */ jsx13(CalendarDays, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
1428
1516
|
label: "Member since",
|
|
1429
|
-
children: /* @__PURE__ */
|
|
1517
|
+
children: /* @__PURE__ */ jsx13("p", { children: formatMemberSince(user.createdAt) })
|
|
1430
1518
|
}
|
|
1431
1519
|
),
|
|
1432
|
-
/* @__PURE__ */
|
|
1520
|
+
/* @__PURE__ */ jsx13(
|
|
1433
1521
|
UiDetailLine,
|
|
1434
1522
|
{
|
|
1435
|
-
icon: /* @__PURE__ */
|
|
1523
|
+
icon: /* @__PURE__ */ jsx13(CheckCircle2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
1436
1524
|
label: "Email status",
|
|
1437
|
-
children: /* @__PURE__ */
|
|
1525
|
+
children: /* @__PURE__ */ jsx13("p", { children: user.emailVerified ? "Verified" : "Not verified" })
|
|
1438
1526
|
}
|
|
1439
1527
|
)
|
|
1440
1528
|
] })
|
|
1441
1529
|
}
|
|
1442
1530
|
),
|
|
1443
|
-
/* @__PURE__ */
|
|
1531
|
+
/* @__PURE__ */ jsx13("form", { onSubmit: handleSubmit(onChangePassword), noValidate: true, children: /* @__PURE__ */ jsx13(
|
|
1444
1532
|
UiSettingsPanel,
|
|
1445
1533
|
{
|
|
1446
1534
|
id: "password",
|
|
1447
|
-
icon: /* @__PURE__ */
|
|
1535
|
+
icon: /* @__PURE__ */ jsx13(KeyRound, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
1448
1536
|
title: "Change password",
|
|
1449
1537
|
description: "Update the password used for email sign-in.",
|
|
1450
|
-
footer: /* @__PURE__ */
|
|
1538
|
+
footer: /* @__PURE__ */ jsx13(Button8, { type: "submit", size: "sm", disabled: isChangingPassword, children: isChangingPassword ? "Changing..." : "Change password" }),
|
|
1451
1539
|
children: /* @__PURE__ */ jsxs6("div", { className: "space-y-4", children: [
|
|
1452
|
-
passwordError && /* @__PURE__ */
|
|
1453
|
-
passwordSuccess && /* @__PURE__ */
|
|
1540
|
+
passwordError && /* @__PURE__ */ jsx13(Notice, { role: "alert", tone: "error", description: passwordError }),
|
|
1541
|
+
passwordSuccess && /* @__PURE__ */ jsx13(Notice, { role: "status", tone: "success", description: "Password changed successfully." }),
|
|
1454
1542
|
/* @__PURE__ */ jsxs6("div", { className: "grid gap-3 sm:grid-cols-2", children: [
|
|
1455
1543
|
/* @__PURE__ */ jsxs6("div", { className: "space-y-2 sm:col-span-2", children: [
|
|
1456
|
-
/* @__PURE__ */
|
|
1457
|
-
/* @__PURE__ */
|
|
1544
|
+
/* @__PURE__ */ jsx13(Label6, { htmlFor: "currentPassword", className: "text-[12px]", children: "Current password" }),
|
|
1545
|
+
/* @__PURE__ */ jsx13(
|
|
1458
1546
|
Input6,
|
|
1459
1547
|
{
|
|
1460
1548
|
id: "currentPassword",
|
|
@@ -1465,11 +1553,11 @@ function UserSettingsPage({ topBar } = {}) {
|
|
|
1465
1553
|
...register("currentPassword")
|
|
1466
1554
|
}
|
|
1467
1555
|
),
|
|
1468
|
-
errors.currentPassword && /* @__PURE__ */
|
|
1556
|
+
errors.currentPassword && /* @__PURE__ */ jsx13("p", { className: "text-[12px] text-destructive", children: errors.currentPassword.message })
|
|
1469
1557
|
] }),
|
|
1470
1558
|
/* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
|
|
1471
|
-
/* @__PURE__ */
|
|
1472
|
-
/* @__PURE__ */
|
|
1559
|
+
/* @__PURE__ */ jsx13(Label6, { htmlFor: "newPassword", className: "text-[12px]", children: "New password" }),
|
|
1560
|
+
/* @__PURE__ */ jsx13(
|
|
1473
1561
|
Input6,
|
|
1474
1562
|
{
|
|
1475
1563
|
id: "newPassword",
|
|
@@ -1481,11 +1569,11 @@ function UserSettingsPage({ topBar } = {}) {
|
|
|
1481
1569
|
...register("newPassword")
|
|
1482
1570
|
}
|
|
1483
1571
|
),
|
|
1484
|
-
errors.newPassword && /* @__PURE__ */
|
|
1572
|
+
errors.newPassword && /* @__PURE__ */ jsx13("p", { className: "text-[12px] text-destructive", children: errors.newPassword.message })
|
|
1485
1573
|
] }),
|
|
1486
1574
|
/* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
|
|
1487
|
-
/* @__PURE__ */
|
|
1488
|
-
/* @__PURE__ */
|
|
1575
|
+
/* @__PURE__ */ jsx13(Label6, { htmlFor: "confirmPassword", className: "text-[12px]", children: "Confirm new password" }),
|
|
1576
|
+
/* @__PURE__ */ jsx13(
|
|
1489
1577
|
Input6,
|
|
1490
1578
|
{
|
|
1491
1579
|
id: "confirmPassword",
|
|
@@ -1496,44 +1584,44 @@ function UserSettingsPage({ topBar } = {}) {
|
|
|
1496
1584
|
...register("confirmPassword")
|
|
1497
1585
|
}
|
|
1498
1586
|
),
|
|
1499
|
-
errors.confirmPassword && /* @__PURE__ */
|
|
1587
|
+
errors.confirmPassword && /* @__PURE__ */ jsx13("p", { className: "text-[12px] text-destructive", children: errors.confirmPassword.message })
|
|
1500
1588
|
] })
|
|
1501
1589
|
] })
|
|
1502
1590
|
] })
|
|
1503
1591
|
}
|
|
1504
1592
|
) }),
|
|
1505
|
-
/* @__PURE__ */
|
|
1593
|
+
/* @__PURE__ */ jsx13(
|
|
1506
1594
|
UiSettingsPanel,
|
|
1507
1595
|
{
|
|
1508
1596
|
id: "danger-zone",
|
|
1509
|
-
icon: /* @__PURE__ */
|
|
1597
|
+
icon: /* @__PURE__ */ jsx13(ShieldAlert, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
1510
1598
|
title: "Danger zone",
|
|
1511
1599
|
description: "Permanently delete this account and remove its workspace access.",
|
|
1512
1600
|
danger: true,
|
|
1513
|
-
children: /* @__PURE__ */
|
|
1601
|
+
children: /* @__PURE__ */ jsx13(
|
|
1514
1602
|
UiSettingsActionRow,
|
|
1515
1603
|
{
|
|
1516
1604
|
title: "Delete account",
|
|
1517
1605
|
description: "Delete your account, user settings, and workspace memberships after confirmation.",
|
|
1518
1606
|
action: /* @__PURE__ */ jsxs6(AlertDialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: [
|
|
1519
|
-
/* @__PURE__ */
|
|
1520
|
-
/* @__PURE__ */
|
|
1607
|
+
/* @__PURE__ */ jsx13(AlertDialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs6(Button8, { variant: "destructive", size: "sm", children: [
|
|
1608
|
+
/* @__PURE__ */ jsx13(Trash2, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
1521
1609
|
"Delete account"
|
|
1522
1610
|
] }) }),
|
|
1523
1611
|
/* @__PURE__ */ jsxs6(AlertDialogContent, { children: [
|
|
1524
1612
|
/* @__PURE__ */ jsxs6(AlertDialogHeader, { children: [
|
|
1525
|
-
/* @__PURE__ */
|
|
1526
|
-
/* @__PURE__ */
|
|
1613
|
+
/* @__PURE__ */ jsx13(AlertDialogTitle, { children: "Delete your account?" }),
|
|
1614
|
+
/* @__PURE__ */ jsx13(AlertDialogDescription, { children: "This action cannot be undone. All your data, workspaces, and settings will be permanently deleted." })
|
|
1527
1615
|
] }),
|
|
1528
1616
|
/* @__PURE__ */ jsxs6("div", { className: "space-y-3 py-2", children: [
|
|
1529
|
-
deleteError && /* @__PURE__ */
|
|
1617
|
+
deleteError && /* @__PURE__ */ jsx13(Notice, { role: "alert", tone: "error", description: deleteError }),
|
|
1530
1618
|
/* @__PURE__ */ jsxs6("div", { className: "space-y-2", children: [
|
|
1531
1619
|
/* @__PURE__ */ jsxs6(Label6, { htmlFor: "delete-confirm", children: [
|
|
1532
1620
|
"Type ",
|
|
1533
|
-
/* @__PURE__ */
|
|
1621
|
+
/* @__PURE__ */ jsx13("span", { className: "font-mono font-bold", children: "DELETE" }),
|
|
1534
1622
|
" to confirm"
|
|
1535
1623
|
] }),
|
|
1536
|
-
/* @__PURE__ */
|
|
1624
|
+
/* @__PURE__ */ jsx13(
|
|
1537
1625
|
Input6,
|
|
1538
1626
|
{
|
|
1539
1627
|
id: "delete-confirm",
|
|
@@ -1547,7 +1635,7 @@ function UserSettingsPage({ topBar } = {}) {
|
|
|
1547
1635
|
] })
|
|
1548
1636
|
] }),
|
|
1549
1637
|
/* @__PURE__ */ jsxs6(AlertDialogFooter, { children: [
|
|
1550
|
-
/* @__PURE__ */
|
|
1638
|
+
/* @__PURE__ */ jsx13(
|
|
1551
1639
|
AlertDialogCancel,
|
|
1552
1640
|
{
|
|
1553
1641
|
onClick: () => {
|
|
@@ -1557,8 +1645,8 @@ function UserSettingsPage({ topBar } = {}) {
|
|
|
1557
1645
|
children: "Cancel"
|
|
1558
1646
|
}
|
|
1559
1647
|
),
|
|
1560
|
-
/* @__PURE__ */
|
|
1561
|
-
|
|
1648
|
+
/* @__PURE__ */ jsx13(
|
|
1649
|
+
Button8,
|
|
1562
1650
|
{
|
|
1563
1651
|
variant: "destructive",
|
|
1564
1652
|
size: "sm",
|
|
@@ -1580,11 +1668,11 @@ function UserSettingsPage({ topBar } = {}) {
|
|
|
1580
1668
|
}
|
|
1581
1669
|
|
|
1582
1670
|
// src/front/auth/InviteAcceptPage.tsx
|
|
1583
|
-
import { useCallback as useCallback5, useState as
|
|
1671
|
+
import { useCallback as useCallback5, useState as useState14 } from "react";
|
|
1584
1672
|
import { useParams as useParams2, useNavigate } from "react-router-dom";
|
|
1585
1673
|
import { useQuery as useQuery3, useMutation, useQueryClient as useQueryClient2 } from "@tanstack/react-query";
|
|
1586
1674
|
import {
|
|
1587
|
-
Button as
|
|
1675
|
+
Button as Button9,
|
|
1588
1676
|
Card as Card6,
|
|
1589
1677
|
CardContent as CardContent6,
|
|
1590
1678
|
CardDescription as CardDescription6,
|
|
@@ -1594,13 +1682,13 @@ import {
|
|
|
1594
1682
|
LoadingState,
|
|
1595
1683
|
Notice as Notice2
|
|
1596
1684
|
} from "@hachej/boring-ui-kit";
|
|
1597
|
-
import { jsx as
|
|
1685
|
+
import { jsx as jsx14, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1598
1686
|
function InviteAcceptPage() {
|
|
1599
1687
|
const { token } = useParams2();
|
|
1600
1688
|
const session = useSession();
|
|
1601
1689
|
const navigate = useNavigate();
|
|
1602
1690
|
const queryClient = useQueryClient2();
|
|
1603
|
-
const [acceptError, setAcceptError] =
|
|
1691
|
+
const [acceptError, setAcceptError] = useState14(null);
|
|
1604
1692
|
const isSignedIn = Boolean(session.data);
|
|
1605
1693
|
const isSessionPending = session.isPending;
|
|
1606
1694
|
const resolveQuery = useQuery3({
|
|
@@ -1644,20 +1732,20 @@ function InviteAcceptPage() {
|
|
|
1644
1732
|
navigate("/");
|
|
1645
1733
|
}, [navigate]);
|
|
1646
1734
|
if (isSessionPending) {
|
|
1647
|
-
return /* @__PURE__ */
|
|
1735
|
+
return /* @__PURE__ */ jsx14("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsx14(Card6, { className: "w-full max-w-md", children: /* @__PURE__ */ jsx14(CardContent6, { className: "py-8 text-center", children: /* @__PURE__ */ jsx14(LoadingState, { "data-testid": "loading", className: "justify-center" }) }) }) });
|
|
1648
1736
|
}
|
|
1649
1737
|
if (!isSignedIn) {
|
|
1650
1738
|
const signinUrl = `${routes.signin}?redirect=${encodeURIComponent(`/invites/${token}`)}`;
|
|
1651
|
-
return /* @__PURE__ */
|
|
1739
|
+
return /* @__PURE__ */ jsx14("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs7(Card6, { className: "w-full max-w-md", children: [
|
|
1652
1740
|
/* @__PURE__ */ jsxs7(CardHeader6, { children: [
|
|
1653
|
-
/* @__PURE__ */
|
|
1654
|
-
/* @__PURE__ */
|
|
1741
|
+
/* @__PURE__ */ jsx14(CardTitle6, { children: "Sign in to accept this invite" }),
|
|
1742
|
+
/* @__PURE__ */ jsx14(CardDescription6, { children: "You need to sign in before you can accept a workspace invite." })
|
|
1655
1743
|
] }),
|
|
1656
|
-
/* @__PURE__ */
|
|
1744
|
+
/* @__PURE__ */ jsx14(CardFooter6, { children: /* @__PURE__ */ jsx14(Button9, { className: "w-full", onClick: () => navigate(signinUrl), "data-testid": "signin-redirect", children: "Sign in" }) })
|
|
1657
1745
|
] }) });
|
|
1658
1746
|
}
|
|
1659
1747
|
if (resolveQuery.isLoading) {
|
|
1660
|
-
return /* @__PURE__ */
|
|
1748
|
+
return /* @__PURE__ */ jsx14("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsx14(Card6, { className: "w-full max-w-md", children: /* @__PURE__ */ jsx14(CardContent6, { className: "py-8 text-center", children: /* @__PURE__ */ jsx14(LoadingState, { "data-testid": "loading", className: "justify-center" }) }) }) });
|
|
1661
1749
|
}
|
|
1662
1750
|
if (resolveQuery.error) {
|
|
1663
1751
|
const detail = getHttpErrorDetail(resolveQuery.error);
|
|
@@ -1671,26 +1759,26 @@ function InviteAcceptPage() {
|
|
|
1671
1759
|
} else {
|
|
1672
1760
|
message = detail.message;
|
|
1673
1761
|
}
|
|
1674
|
-
return /* @__PURE__ */
|
|
1675
|
-
/* @__PURE__ */
|
|
1676
|
-
/* @__PURE__ */
|
|
1677
|
-
/* @__PURE__ */
|
|
1762
|
+
return /* @__PURE__ */ jsx14("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs7(Card6, { className: "w-full max-w-md", children: [
|
|
1763
|
+
/* @__PURE__ */ jsx14(CardHeader6, { children: /* @__PURE__ */ jsx14(CardTitle6, { children: "Invite unavailable" }) }),
|
|
1764
|
+
/* @__PURE__ */ jsx14(CardContent6, { children: /* @__PURE__ */ jsx14(Notice2, { "data-testid": "resolve-error", tone: "error", description: message }) }),
|
|
1765
|
+
/* @__PURE__ */ jsx14(CardFooter6, { children: /* @__PURE__ */ jsx14(Button9, { variant: "outline", className: "w-full", onClick: () => navigate("/"), children: "Go home" }) })
|
|
1678
1766
|
] }) });
|
|
1679
1767
|
}
|
|
1680
1768
|
const preview = resolveQuery.data;
|
|
1681
1769
|
if (!preview) return null;
|
|
1682
|
-
return /* @__PURE__ */
|
|
1770
|
+
return /* @__PURE__ */ jsx14("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs7(Card6, { className: "w-full max-w-md", children: [
|
|
1683
1771
|
/* @__PURE__ */ jsxs7(CardHeader6, { children: [
|
|
1684
|
-
/* @__PURE__ */
|
|
1772
|
+
/* @__PURE__ */ jsx14(CardTitle6, { children: "You've been invited" }),
|
|
1685
1773
|
/* @__PURE__ */ jsxs7(CardDescription6, { children: [
|
|
1686
1774
|
"Join ",
|
|
1687
|
-
/* @__PURE__ */
|
|
1775
|
+
/* @__PURE__ */ jsx14("strong", { children: preview.workspaceName }),
|
|
1688
1776
|
" as ",
|
|
1689
|
-
/* @__PURE__ */
|
|
1777
|
+
/* @__PURE__ */ jsx14("strong", { children: preview.role })
|
|
1690
1778
|
] })
|
|
1691
1779
|
] }),
|
|
1692
1780
|
/* @__PURE__ */ jsxs7(CardContent6, { className: "space-y-3", children: [
|
|
1693
|
-
acceptError && /* @__PURE__ */
|
|
1781
|
+
acceptError && /* @__PURE__ */ jsx14(Notice2, { role: "alert", "data-testid": "accept-error", tone: "error", description: acceptError }),
|
|
1694
1782
|
/* @__PURE__ */ jsxs7("div", { className: "text-sm text-muted-foreground", children: [
|
|
1695
1783
|
"This invite expires on",
|
|
1696
1784
|
" ",
|
|
@@ -1702,8 +1790,8 @@ function InviteAcceptPage() {
|
|
|
1702
1790
|
] })
|
|
1703
1791
|
] }),
|
|
1704
1792
|
/* @__PURE__ */ jsxs7(CardFooter6, { className: "flex gap-3", children: [
|
|
1705
|
-
/* @__PURE__ */
|
|
1706
|
-
|
|
1793
|
+
/* @__PURE__ */ jsx14(
|
|
1794
|
+
Button9,
|
|
1707
1795
|
{
|
|
1708
1796
|
variant: "outline",
|
|
1709
1797
|
className: "flex-1",
|
|
@@ -1712,8 +1800,8 @@ function InviteAcceptPage() {
|
|
|
1712
1800
|
children: "Decline"
|
|
1713
1801
|
}
|
|
1714
1802
|
),
|
|
1715
|
-
/* @__PURE__ */
|
|
1716
|
-
|
|
1803
|
+
/* @__PURE__ */ jsx14(
|
|
1804
|
+
Button9,
|
|
1717
1805
|
{
|
|
1718
1806
|
className: "flex-1",
|
|
1719
1807
|
disabled: acceptMutation.isPending,
|
|
@@ -1728,7 +1816,7 @@ function InviteAcceptPage() {
|
|
|
1728
1816
|
|
|
1729
1817
|
// src/front/AuthGate.tsx
|
|
1730
1818
|
import { useEffect as useEffect9, useMemo as useMemo3, useRef as useRef5 } from "react";
|
|
1731
|
-
import { Fragment, jsx as
|
|
1819
|
+
import { Fragment as Fragment3, jsx as jsx15 } from "react/jsx-runtime";
|
|
1732
1820
|
var DEFAULT_GRACE_MS = 3e4;
|
|
1733
1821
|
var UNSAFE_REDIRECT_RE = /[\0\r\n<>"'`]/;
|
|
1734
1822
|
function normalizePath(pathname) {
|
|
@@ -1846,7 +1934,7 @@ function AuthGate({
|
|
|
1846
1934
|
}, [currentLocation, goTo, graceMs, normalizedPublicPaths, readNow, session.data, session.isPending]);
|
|
1847
1935
|
const pathname = normalizePath(currentLocation.pathname);
|
|
1848
1936
|
if (session.isPending && !isPublicPath(pathname, normalizedPublicPaths)) return null;
|
|
1849
|
-
return /* @__PURE__ */
|
|
1937
|
+
return /* @__PURE__ */ jsx15(Fragment3, { children });
|
|
1850
1938
|
}
|
|
1851
1939
|
|
|
1852
1940
|
// src/front/CoreFront.tsx
|
|
@@ -1856,9 +1944,9 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
|
1856
1944
|
import { Helmet, HelmetProvider } from "react-helmet-async";
|
|
1857
1945
|
|
|
1858
1946
|
// src/front/components/UserMenu.tsx
|
|
1859
|
-
import { useMemo as useMemo4, useState as
|
|
1947
|
+
import { useMemo as useMemo4, useState as useState15 } from "react";
|
|
1860
1948
|
import {
|
|
1861
|
-
Button as
|
|
1949
|
+
Button as Button10,
|
|
1862
1950
|
DropdownMenu,
|
|
1863
1951
|
DropdownMenuContent,
|
|
1864
1952
|
DropdownMenuItem,
|
|
@@ -1876,7 +1964,7 @@ import {
|
|
|
1876
1964
|
Sun
|
|
1877
1965
|
} from "lucide-react";
|
|
1878
1966
|
import { useNavigate as useNavigate2 } from "react-router-dom";
|
|
1879
|
-
import { jsx as
|
|
1967
|
+
import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1880
1968
|
var THEME_ORDER = ["light", "dark", "system"];
|
|
1881
1969
|
function labelForTheme(preference) {
|
|
1882
1970
|
if (preference === "light") return "Light";
|
|
@@ -1899,7 +1987,7 @@ function UserMenu() {
|
|
|
1899
1987
|
const signOut = useSignOut();
|
|
1900
1988
|
const navigate = useNavigate2();
|
|
1901
1989
|
const { preference, setTheme } = useTheme();
|
|
1902
|
-
const [isSigningOut, setIsSigningOut] =
|
|
1990
|
+
const [isSigningOut, setIsSigningOut] = useState15(false);
|
|
1903
1991
|
const user = identity?.user;
|
|
1904
1992
|
const userName = user?.name ?? "Unknown user";
|
|
1905
1993
|
const userEmail = user?.email ?? "unknown@example.com";
|
|
@@ -1915,16 +2003,16 @@ function UserMenu() {
|
|
|
1915
2003
|
}
|
|
1916
2004
|
}
|
|
1917
2005
|
return /* @__PURE__ */ jsxs8(DropdownMenu, { children: [
|
|
1918
|
-
/* @__PURE__ */
|
|
1919
|
-
|
|
2006
|
+
/* @__PURE__ */ jsx16(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs8(
|
|
2007
|
+
Button10,
|
|
1920
2008
|
{
|
|
1921
2009
|
type: "button",
|
|
1922
2010
|
variant: "ghost",
|
|
1923
2011
|
"aria-label": "User menu",
|
|
1924
2012
|
className: "h-8 rounded-md border border-transparent bg-transparent px-1 pr-1.5 text-foreground shadow-none hover:bg-foreground/5 focus-visible:ring-1 focus-visible:ring-ring",
|
|
1925
2013
|
children: [
|
|
1926
|
-
/* @__PURE__ */
|
|
1927
|
-
/* @__PURE__ */
|
|
2014
|
+
/* @__PURE__ */ jsx16("span", { className: "inline-flex h-7 w-7 items-center justify-center rounded-md bg-foreground text-[11px] font-semibold text-background", children: initials }),
|
|
2015
|
+
/* @__PURE__ */ jsx16(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground", "aria-hidden": "true" })
|
|
1928
2016
|
]
|
|
1929
2017
|
}
|
|
1930
2018
|
) }),
|
|
@@ -1935,15 +2023,15 @@ function UserMenu() {
|
|
|
1935
2023
|
sideOffset: 8,
|
|
1936
2024
|
className: "w-80 rounded-lg border-border/70 bg-[color:var(--surface-workbench-left)] p-2 shadow-2xl",
|
|
1937
2025
|
children: [
|
|
1938
|
-
/* @__PURE__ */
|
|
1939
|
-
/* @__PURE__ */
|
|
2026
|
+
/* @__PURE__ */ jsx16(DropdownMenuLabel, { className: "p-2", children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3", children: [
|
|
2027
|
+
/* @__PURE__ */ jsx16("span", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-foreground text-[12px] font-semibold text-background", children: initials }),
|
|
1940
2028
|
/* @__PURE__ */ jsxs8("span", { className: "min-w-0 space-y-1", children: [
|
|
1941
|
-
/* @__PURE__ */
|
|
1942
|
-
/* @__PURE__ */
|
|
2029
|
+
/* @__PURE__ */ jsx16("span", { className: "block truncate text-sm font-medium leading-none", children: userName }),
|
|
2030
|
+
/* @__PURE__ */ jsx16("span", { className: "block truncate text-xs font-normal text-muted-foreground", children: userEmail })
|
|
1943
2031
|
] })
|
|
1944
2032
|
] }) }),
|
|
1945
|
-
/* @__PURE__ */
|
|
1946
|
-
/* @__PURE__ */
|
|
2033
|
+
/* @__PURE__ */ jsx16(DropdownMenuSeparator, { className: "-mx-2" }),
|
|
2034
|
+
/* @__PURE__ */ jsx16(DropdownMenuLabel, { className: "px-2 pb-1 pt-2 text-[11px] font-medium text-muted-foreground", children: "Theme" }),
|
|
1947
2035
|
THEME_ORDER.map((theme) => {
|
|
1948
2036
|
const Icon = iconForTheme(theme);
|
|
1949
2037
|
const selected = preference === theme;
|
|
@@ -1958,15 +2046,15 @@ function UserMenu() {
|
|
|
1958
2046
|
},
|
|
1959
2047
|
className: "gap-3 rounded-md py-2 text-[13px] focus:bg-foreground/[0.06] focus:text-foreground",
|
|
1960
2048
|
children: [
|
|
1961
|
-
/* @__PURE__ */
|
|
1962
|
-
/* @__PURE__ */
|
|
1963
|
-
selected ? /* @__PURE__ */
|
|
2049
|
+
/* @__PURE__ */ jsx16(Icon, { className: "h-4 w-4 text-muted-foreground", "aria-hidden": "true" }),
|
|
2050
|
+
/* @__PURE__ */ jsx16("span", { className: "flex-1", children: labelForTheme(theme) }),
|
|
2051
|
+
selected ? /* @__PURE__ */ jsx16(Check, { className: "h-4 w-4 text-foreground", "aria-hidden": "true" }) : null
|
|
1964
2052
|
]
|
|
1965
2053
|
},
|
|
1966
2054
|
theme
|
|
1967
2055
|
);
|
|
1968
2056
|
}),
|
|
1969
|
-
/* @__PURE__ */
|
|
2057
|
+
/* @__PURE__ */ jsx16(DropdownMenuSeparator, { className: "-mx-2" }),
|
|
1970
2058
|
/* @__PURE__ */ jsxs8(
|
|
1971
2059
|
DropdownMenuItem,
|
|
1972
2060
|
{
|
|
@@ -1974,15 +2062,15 @@ function UserMenu() {
|
|
|
1974
2062
|
onSelect: () => navigate(routes.me),
|
|
1975
2063
|
className: "gap-3 rounded-md py-2 text-[13px] focus:bg-foreground/[0.06] focus:text-foreground",
|
|
1976
2064
|
children: [
|
|
1977
|
-
/* @__PURE__ */
|
|
2065
|
+
/* @__PURE__ */ jsx16(Settings, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
1978
2066
|
/* @__PURE__ */ jsxs8("span", { className: "flex min-w-0 flex-col", children: [
|
|
1979
|
-
/* @__PURE__ */
|
|
1980
|
-
/* @__PURE__ */
|
|
2067
|
+
/* @__PURE__ */ jsx16("span", { children: "User settings" }),
|
|
2068
|
+
/* @__PURE__ */ jsx16("span", { className: "text-xs text-muted-foreground", children: "Password and account controls" })
|
|
1981
2069
|
] })
|
|
1982
2070
|
]
|
|
1983
2071
|
}
|
|
1984
2072
|
),
|
|
1985
|
-
/* @__PURE__ */
|
|
2073
|
+
/* @__PURE__ */ jsx16(DropdownMenuSeparator, { className: "-mx-2" }),
|
|
1986
2074
|
/* @__PURE__ */ jsxs8(
|
|
1987
2075
|
DropdownMenuItem,
|
|
1988
2076
|
{
|
|
@@ -1994,7 +2082,7 @@ function UserMenu() {
|
|
|
1994
2082
|
disabled: isSigningOut,
|
|
1995
2083
|
className: "gap-3 rounded-md py-2 text-[13px]",
|
|
1996
2084
|
children: [
|
|
1997
|
-
/* @__PURE__ */
|
|
2085
|
+
/* @__PURE__ */ jsx16(LogOut, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
1998
2086
|
isSigningOut ? "Signing out..." : "Sign out"
|
|
1999
2087
|
]
|
|
2000
2088
|
}
|
|
@@ -2006,10 +2094,10 @@ function UserMenu() {
|
|
|
2006
2094
|
}
|
|
2007
2095
|
|
|
2008
2096
|
// src/front/components/WorkspaceSwitcher.tsx
|
|
2009
|
-
import { useMemo as useMemo5, useState as
|
|
2097
|
+
import { useMemo as useMemo5, useState as useState16 } from "react";
|
|
2010
2098
|
import { useQuery as useQuery4, useQueryClient as useQueryClient3 } from "@tanstack/react-query";
|
|
2011
2099
|
import {
|
|
2012
|
-
Button as
|
|
2100
|
+
Button as Button11,
|
|
2013
2101
|
Dialog,
|
|
2014
2102
|
DialogContent,
|
|
2015
2103
|
DialogDescription,
|
|
@@ -2029,7 +2117,7 @@ import {
|
|
|
2029
2117
|
import { Check as Check2, ChevronsUpDown, LayoutGrid, Plus, Settings as Settings2 } from "lucide-react";
|
|
2030
2118
|
import { useNavigate as useNavigate3 } from "react-router-dom";
|
|
2031
2119
|
import { z as z6 } from "zod";
|
|
2032
|
-
import { Fragment as
|
|
2120
|
+
import { Fragment as Fragment4, jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2033
2121
|
var workspaceNameSchema = z6.object({
|
|
2034
2122
|
name: z6.string().trim().min(1, "Workspace name is required").max(100, "Workspace name must be 100 characters or fewer")
|
|
2035
2123
|
});
|
|
@@ -2075,11 +2163,11 @@ function WorkspaceSwitcher({
|
|
|
2075
2163
|
const currentWorkspace = useCurrentWorkspace();
|
|
2076
2164
|
const workspacesQuery = useWorkspaces();
|
|
2077
2165
|
const workspaces = workspacesQuery.data ?? [];
|
|
2078
|
-
const [isModalOpen, setIsModalOpen] =
|
|
2079
|
-
const [name, setName] =
|
|
2080
|
-
const [attemptedSubmit, setAttemptedSubmit] =
|
|
2081
|
-
const [isSubmitting, setIsSubmitting] =
|
|
2082
|
-
const [serverError, setServerError] =
|
|
2166
|
+
const [isModalOpen, setIsModalOpen] = useState16(false);
|
|
2167
|
+
const [name, setName] = useState16("");
|
|
2168
|
+
const [attemptedSubmit, setAttemptedSubmit] = useState16(false);
|
|
2169
|
+
const [isSubmitting, setIsSubmitting] = useState16(false);
|
|
2170
|
+
const [serverError, setServerError] = useState16(null);
|
|
2083
2171
|
const nameValidation = useMemo5(() => validateWorkspaceName(name), [name]);
|
|
2084
2172
|
const shouldShowNameError = name.length > 100 || attemptedSubmit && nameValidation.message !== null;
|
|
2085
2173
|
const nameError = shouldShowNameError ? nameValidation.message : null;
|
|
@@ -2136,16 +2224,16 @@ function WorkspaceSwitcher({
|
|
|
2136
2224
|
}
|
|
2137
2225
|
}
|
|
2138
2226
|
const switcherLabel = currentWorkspace?.name ?? "Select workspace";
|
|
2139
|
-
return /* @__PURE__ */ jsxs9(
|
|
2227
|
+
return /* @__PURE__ */ jsxs9(Fragment4, { children: [
|
|
2140
2228
|
workspaces.length === 0 ? /* @__PURE__ */ jsxs9(
|
|
2141
|
-
|
|
2229
|
+
Button11,
|
|
2142
2230
|
{
|
|
2143
2231
|
type: "button",
|
|
2144
2232
|
variant: "ghost",
|
|
2145
2233
|
onClick: openCreateWorkspace,
|
|
2146
2234
|
className: "-ml-1 h-8 gap-2 rounded-md px-1 pr-2.5 hover:bg-foreground/5 focus-visible:ring-1 focus-visible:ring-ring",
|
|
2147
2235
|
children: [
|
|
2148
|
-
/* @__PURE__ */
|
|
2236
|
+
/* @__PURE__ */ jsx17(
|
|
2149
2237
|
"span",
|
|
2150
2238
|
{
|
|
2151
2239
|
"aria-hidden": "true",
|
|
@@ -2153,19 +2241,19 @@ function WorkspaceSwitcher({
|
|
|
2153
2241
|
children: appTitle.charAt(0).toUpperCase()
|
|
2154
2242
|
}
|
|
2155
2243
|
),
|
|
2156
|
-
/* @__PURE__ */
|
|
2244
|
+
/* @__PURE__ */ jsx17("span", { className: "text-[13px] font-medium text-foreground", children: "Create your first workspace" })
|
|
2157
2245
|
]
|
|
2158
2246
|
}
|
|
2159
2247
|
) : /* @__PURE__ */ jsxs9(DropdownMenu2, { children: [
|
|
2160
|
-
/* @__PURE__ */
|
|
2161
|
-
|
|
2248
|
+
/* @__PURE__ */ jsx17(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs9(
|
|
2249
|
+
Button11,
|
|
2162
2250
|
{
|
|
2163
2251
|
type: "button",
|
|
2164
2252
|
variant: "ghost",
|
|
2165
2253
|
"aria-label": `Workspace menu: ${switcherLabel}`,
|
|
2166
2254
|
className: "-ml-1 h-8 min-w-0 justify-start gap-2.5 border border-transparent px-1 py-1 text-left",
|
|
2167
2255
|
children: [
|
|
2168
|
-
/* @__PURE__ */
|
|
2256
|
+
/* @__PURE__ */ jsx17(
|
|
2169
2257
|
"span",
|
|
2170
2258
|
{
|
|
2171
2259
|
"aria-hidden": "true",
|
|
@@ -2174,11 +2262,11 @@ function WorkspaceSwitcher({
|
|
|
2174
2262
|
}
|
|
2175
2263
|
),
|
|
2176
2264
|
/* @__PURE__ */ jsxs9("span", { className: "flex min-w-0 items-center gap-1.5", children: [
|
|
2177
|
-
/* @__PURE__ */
|
|
2178
|
-
/* @__PURE__ */
|
|
2179
|
-
/* @__PURE__ */
|
|
2265
|
+
/* @__PURE__ */ jsx17("span", { className: "truncate text-[13px] font-medium text-foreground", children: appTitle }),
|
|
2266
|
+
/* @__PURE__ */ jsx17("span", { "aria-hidden": "true", className: "text-muted-foreground/30", children: "/" }),
|
|
2267
|
+
/* @__PURE__ */ jsx17("span", { className: "truncate text-[13px] font-normal text-muted-foreground", children: switcherLabel })
|
|
2180
2268
|
] }),
|
|
2181
|
-
/* @__PURE__ */
|
|
2269
|
+
/* @__PURE__ */ jsx17(ChevronsUpDown, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground/55", "aria-hidden": "true" })
|
|
2182
2270
|
]
|
|
2183
2271
|
}
|
|
2184
2272
|
) }),
|
|
@@ -2189,11 +2277,11 @@ function WorkspaceSwitcher({
|
|
|
2189
2277
|
sideOffset: 8,
|
|
2190
2278
|
className: "w-80 rounded-lg border-border/70 bg-[color:var(--surface-workbench-left)] p-2 shadow-2xl",
|
|
2191
2279
|
children: [
|
|
2192
|
-
/* @__PURE__ */
|
|
2193
|
-
/* @__PURE__ */
|
|
2280
|
+
/* @__PURE__ */ jsx17(DropdownMenuLabel2, { className: "px-2 pb-2 pt-1", children: /* @__PURE__ */ jsxs9("span", { className: "flex items-center gap-2 text-xs font-medium text-muted-foreground", children: [
|
|
2281
|
+
/* @__PURE__ */ jsx17(LayoutGrid, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
2194
2282
|
"Workspaces"
|
|
2195
2283
|
] }) }),
|
|
2196
|
-
/* @__PURE__ */
|
|
2284
|
+
/* @__PURE__ */ jsx17("div", { className: "max-h-72 overflow-y-auto pr-1", children: workspaces.map((workspace) => {
|
|
2197
2285
|
const isCurrent = currentWorkspace?.id === workspace.id;
|
|
2198
2286
|
return /* @__PURE__ */ jsxs9(
|
|
2199
2287
|
DropdownMenuItem2,
|
|
@@ -2203,15 +2291,15 @@ function WorkspaceSwitcher({
|
|
|
2203
2291
|
onSelect: () => navigate(hrefForWorkspace(workspacePathPrefix, workspace.id)),
|
|
2204
2292
|
className: "gap-3 rounded-md py-2 text-[13px] focus:bg-foreground/[0.06] focus:text-foreground",
|
|
2205
2293
|
children: [
|
|
2206
|
-
/* @__PURE__ */
|
|
2207
|
-
/* @__PURE__ */
|
|
2208
|
-
isCurrent ? /* @__PURE__ */
|
|
2294
|
+
/* @__PURE__ */ jsx17("span", { className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-md border border-border/60 bg-background text-xs font-semibold text-muted-foreground", children: workspaceInitial(workspace.name) }),
|
|
2295
|
+
/* @__PURE__ */ jsx17("span", { className: "min-w-0 flex-1 truncate text-sm", children: workspace.name }),
|
|
2296
|
+
isCurrent ? /* @__PURE__ */ jsx17(Check2, { className: "h-4 w-4 text-foreground", "aria-hidden": "true" }) : null
|
|
2209
2297
|
]
|
|
2210
2298
|
},
|
|
2211
2299
|
workspace.id
|
|
2212
2300
|
);
|
|
2213
2301
|
}) }),
|
|
2214
|
-
/* @__PURE__ */
|
|
2302
|
+
/* @__PURE__ */ jsx17(DropdownMenuSeparator2, { className: "-mx-2" }),
|
|
2215
2303
|
/* @__PURE__ */ jsxs9(
|
|
2216
2304
|
DropdownMenuItem2,
|
|
2217
2305
|
{
|
|
@@ -2222,10 +2310,10 @@ function WorkspaceSwitcher({
|
|
|
2222
2310
|
},
|
|
2223
2311
|
className: "gap-3 rounded-md py-2 text-[13px] focus:bg-foreground/[0.06] focus:text-foreground",
|
|
2224
2312
|
children: [
|
|
2225
|
-
/* @__PURE__ */
|
|
2313
|
+
/* @__PURE__ */ jsx17(Plus, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
2226
2314
|
/* @__PURE__ */ jsxs9("span", { className: "flex min-w-0 flex-col", children: [
|
|
2227
|
-
/* @__PURE__ */
|
|
2228
|
-
/* @__PURE__ */
|
|
2315
|
+
/* @__PURE__ */ jsx17("span", { children: "Create workspace" }),
|
|
2316
|
+
/* @__PURE__ */ jsx17("span", { className: "text-xs text-muted-foreground", children: "Start a clean project space" })
|
|
2229
2317
|
] })
|
|
2230
2318
|
]
|
|
2231
2319
|
}
|
|
@@ -2237,10 +2325,10 @@ function WorkspaceSwitcher({
|
|
|
2237
2325
|
onSelect: () => navigate(hrefForWorkspace(workspacePathPrefix, currentWorkspace.id, "/settings")),
|
|
2238
2326
|
className: "gap-3 rounded-md py-2 text-[13px] focus:bg-foreground/[0.06] focus:text-foreground",
|
|
2239
2327
|
children: [
|
|
2240
|
-
/* @__PURE__ */
|
|
2328
|
+
/* @__PURE__ */ jsx17(Settings2, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
2241
2329
|
/* @__PURE__ */ jsxs9("span", { className: "flex min-w-0 flex-col", children: [
|
|
2242
|
-
/* @__PURE__ */
|
|
2243
|
-
/* @__PURE__ */
|
|
2330
|
+
/* @__PURE__ */ jsx17("span", { children: "Workspace settings" }),
|
|
2331
|
+
/* @__PURE__ */ jsx17("span", { className: "text-xs text-muted-foreground", children: "Rename, runtime, deletion" })
|
|
2244
2332
|
] })
|
|
2245
2333
|
]
|
|
2246
2334
|
}
|
|
@@ -2249,21 +2337,21 @@ function WorkspaceSwitcher({
|
|
|
2249
2337
|
}
|
|
2250
2338
|
)
|
|
2251
2339
|
] }),
|
|
2252
|
-
/* @__PURE__ */
|
|
2340
|
+
/* @__PURE__ */ jsx17(Dialog, { open: isModalOpen, onOpenChange: onModalChange, children: /* @__PURE__ */ jsxs9(DialogContent, { children: [
|
|
2253
2341
|
/* @__PURE__ */ jsxs9(DialogHeader, { children: [
|
|
2254
|
-
/* @__PURE__ */
|
|
2255
|
-
/* @__PURE__ */
|
|
2342
|
+
/* @__PURE__ */ jsx17(DialogTitle, { children: "Create workspace" }),
|
|
2343
|
+
/* @__PURE__ */ jsx17(DialogDescription, { children: "Choose a name for your new workspace." })
|
|
2256
2344
|
] }),
|
|
2257
2345
|
/* @__PURE__ */ jsxs9("form", { onSubmit: (event) => void handleCreateWorkspace(event), className: "space-y-4", children: [
|
|
2258
2346
|
/* @__PURE__ */ jsxs9("div", { className: "space-y-2", children: [
|
|
2259
2347
|
/* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between gap-3", children: [
|
|
2260
|
-
/* @__PURE__ */
|
|
2348
|
+
/* @__PURE__ */ jsx17(Label7, { htmlFor: "workspace-name", children: "Name" }),
|
|
2261
2349
|
/* @__PURE__ */ jsxs9("span", { className: "text-xs text-muted-foreground", children: [
|
|
2262
2350
|
name.length,
|
|
2263
2351
|
"/100"
|
|
2264
2352
|
] })
|
|
2265
2353
|
] }),
|
|
2266
|
-
/* @__PURE__ */
|
|
2354
|
+
/* @__PURE__ */ jsx17(
|
|
2267
2355
|
Input7,
|
|
2268
2356
|
{
|
|
2269
2357
|
id: "workspace-name",
|
|
@@ -2279,12 +2367,12 @@ function WorkspaceSwitcher({
|
|
|
2279
2367
|
autoFocus: true
|
|
2280
2368
|
}
|
|
2281
2369
|
),
|
|
2282
|
-
nameError ? /* @__PURE__ */
|
|
2283
|
-
serverError ? /* @__PURE__ */
|
|
2370
|
+
nameError ? /* @__PURE__ */ jsx17("p", { role: "alert", className: "text-sm text-destructive", children: nameError }) : null,
|
|
2371
|
+
serverError ? /* @__PURE__ */ jsx17("p", { role: "alert", className: "text-sm text-destructive", children: serverError }) : null
|
|
2284
2372
|
] }),
|
|
2285
2373
|
/* @__PURE__ */ jsxs9(DialogFooter, { children: [
|
|
2286
|
-
/* @__PURE__ */
|
|
2287
|
-
|
|
2374
|
+
/* @__PURE__ */ jsx17(
|
|
2375
|
+
Button11,
|
|
2288
2376
|
{
|
|
2289
2377
|
type: "button",
|
|
2290
2378
|
variant: "ghost",
|
|
@@ -2293,8 +2381,8 @@ function WorkspaceSwitcher({
|
|
|
2293
2381
|
children: "Cancel"
|
|
2294
2382
|
}
|
|
2295
2383
|
),
|
|
2296
|
-
/* @__PURE__ */
|
|
2297
|
-
|
|
2384
|
+
/* @__PURE__ */ jsx17(
|
|
2385
|
+
Button11,
|
|
2298
2386
|
{
|
|
2299
2387
|
type: "submit",
|
|
2300
2388
|
disabled: isSubmitting || nameValidation.parsedName === null,
|
|
@@ -2308,7 +2396,7 @@ function WorkspaceSwitcher({
|
|
|
2308
2396
|
}
|
|
2309
2397
|
|
|
2310
2398
|
// src/front/components/ThemeToggle.tsx
|
|
2311
|
-
import { Button as
|
|
2399
|
+
import { Button as Button12 } from "@hachej/boring-ui-kit";
|
|
2312
2400
|
import { jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2313
2401
|
var THEME_ORDER2 = ["light", "dark", "system"];
|
|
2314
2402
|
function nextTheme(preference) {
|
|
@@ -2324,7 +2412,7 @@ function labelForTheme2(preference) {
|
|
|
2324
2412
|
function ThemeToggle() {
|
|
2325
2413
|
const { preference, setTheme } = useTheme();
|
|
2326
2414
|
return /* @__PURE__ */ jsxs10(
|
|
2327
|
-
|
|
2415
|
+
Button12,
|
|
2328
2416
|
{
|
|
2329
2417
|
type: "button",
|
|
2330
2418
|
variant: "outline",
|
|
@@ -2339,17 +2427,42 @@ function ThemeToggle() {
|
|
|
2339
2427
|
);
|
|
2340
2428
|
}
|
|
2341
2429
|
|
|
2430
|
+
// src/front/auth/AuthErrorPage.tsx
|
|
2431
|
+
import { Card as Card7, CardContent as CardContent7, CardDescription as CardDescription7, CardFooter as CardFooter7, CardHeader as CardHeader7, CardTitle as CardTitle7 } from "@hachej/boring-ui-kit";
|
|
2432
|
+
import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2433
|
+
function readAuthErrorCode() {
|
|
2434
|
+
if (typeof window === "undefined") return null;
|
|
2435
|
+
return new URLSearchParams(window.location.search).get("error");
|
|
2436
|
+
}
|
|
2437
|
+
function AuthErrorPage() {
|
|
2438
|
+
const errorCode = readAuthErrorCode();
|
|
2439
|
+
return /* @__PURE__ */ jsx18("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs11(Card7, { className: "w-full max-w-sm", children: [
|
|
2440
|
+
/* @__PURE__ */ jsxs11(CardHeader7, { children: [
|
|
2441
|
+
/* @__PURE__ */ jsx18(CardTitle7, { children: "Authentication error" }),
|
|
2442
|
+
/* @__PURE__ */ jsx18(CardDescription7, { children: "We could not complete that authentication flow. Please try again." })
|
|
2443
|
+
] }),
|
|
2444
|
+
errorCode && /* @__PURE__ */ jsx18(CardContent7, { children: /* @__PURE__ */ jsxs11("p", { className: "text-sm text-muted-foreground break-all", children: [
|
|
2445
|
+
"Error: ",
|
|
2446
|
+
errorCode
|
|
2447
|
+
] }) }),
|
|
2448
|
+
/* @__PURE__ */ jsxs11(CardFooter7, { className: "flex justify-between gap-4 text-sm", children: [
|
|
2449
|
+
/* @__PURE__ */ jsx18("a", { href: routes.signin, className: "text-muted-foreground hover:underline", children: "Back to sign in" }),
|
|
2450
|
+
/* @__PURE__ */ jsx18("a", { href: routes.signup, className: "text-muted-foreground hover:underline", children: "Create account" })
|
|
2451
|
+
] })
|
|
2452
|
+
] }) });
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2342
2455
|
// src/front/workspace/InvitesPage.tsx
|
|
2343
|
-
import { useCallback as useCallback6, useState as
|
|
2456
|
+
import { useCallback as useCallback6, useState as useState17 } from "react";
|
|
2344
2457
|
import { useQuery as useQuery5, useMutation as useMutation2, useQueryClient as useQueryClient4 } from "@tanstack/react-query";
|
|
2345
2458
|
import {
|
|
2346
|
-
Button as
|
|
2347
|
-
Card as
|
|
2348
|
-
CardContent as
|
|
2349
|
-
CardDescription as
|
|
2350
|
-
CardFooter as
|
|
2351
|
-
CardHeader as
|
|
2352
|
-
CardTitle as
|
|
2459
|
+
Button as Button13,
|
|
2460
|
+
Card as Card8,
|
|
2461
|
+
CardContent as CardContent8,
|
|
2462
|
+
CardDescription as CardDescription8,
|
|
2463
|
+
CardFooter as CardFooter8,
|
|
2464
|
+
CardHeader as CardHeader8,
|
|
2465
|
+
CardTitle as CardTitle8,
|
|
2353
2466
|
Input as Input8,
|
|
2354
2467
|
Label as Label8,
|
|
2355
2468
|
LoadingState as LoadingState2,
|
|
@@ -2361,7 +2474,7 @@ import {
|
|
|
2361
2474
|
SelectValue,
|
|
2362
2475
|
StatusBadge
|
|
2363
2476
|
} from "@hachej/boring-ui-kit";
|
|
2364
|
-
import { jsx as
|
|
2477
|
+
import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2365
2478
|
function invitesQueryKey(workspaceId) {
|
|
2366
2479
|
return ["invites", workspaceId];
|
|
2367
2480
|
}
|
|
@@ -2382,10 +2495,10 @@ function InvitesPage() {
|
|
|
2382
2495
|
const workspace = useCurrentWorkspace();
|
|
2383
2496
|
const role = useWorkspaceRole();
|
|
2384
2497
|
const queryClient = useQueryClient4();
|
|
2385
|
-
const [email, setEmail] =
|
|
2386
|
-
const [inviteRole, setInviteRole] =
|
|
2387
|
-
const [formError, setFormError] =
|
|
2388
|
-
const [successMessage, setSuccessMessage] =
|
|
2498
|
+
const [email, setEmail] = useState17("");
|
|
2499
|
+
const [inviteRole, setInviteRole] = useState17("editor");
|
|
2500
|
+
const [formError, setFormError] = useState17(null);
|
|
2501
|
+
const [successMessage, setSuccessMessage] = useState17(null);
|
|
2389
2502
|
const workspaceId = workspace?.id ?? "";
|
|
2390
2503
|
const encodedWorkspaceId = encodeURIComponent(workspaceId);
|
|
2391
2504
|
const invitesQuery = useQuery5({
|
|
@@ -2421,7 +2534,7 @@ function InvitesPage() {
|
|
|
2421
2534
|
setFormError(detail.message);
|
|
2422
2535
|
}
|
|
2423
2536
|
});
|
|
2424
|
-
const [revokeError, setRevokeError] =
|
|
2537
|
+
const [revokeError, setRevokeError] = useState17(null);
|
|
2425
2538
|
const revokeMutation = useMutation2({
|
|
2426
2539
|
mutationFn: async (inviteId) => {
|
|
2427
2540
|
await apiFetch(
|
|
@@ -2453,28 +2566,28 @@ function InvitesPage() {
|
|
|
2453
2566
|
[email, inviteRole, createMutation]
|
|
2454
2567
|
);
|
|
2455
2568
|
if (role !== "owner") {
|
|
2456
|
-
return /* @__PURE__ */
|
|
2457
|
-
/* @__PURE__ */
|
|
2458
|
-
/* @__PURE__ */
|
|
2569
|
+
return /* @__PURE__ */ jsx19("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsx19(Card8, { className: "w-full max-w-md", children: /* @__PURE__ */ jsxs12(CardHeader8, { children: [
|
|
2570
|
+
/* @__PURE__ */ jsx19(CardTitle8, { children: "Access denied" }),
|
|
2571
|
+
/* @__PURE__ */ jsx19(CardDescription8, { children: "Only workspace owners can manage invites." })
|
|
2459
2572
|
] }) }) });
|
|
2460
2573
|
}
|
|
2461
|
-
return /* @__PURE__ */
|
|
2462
|
-
/* @__PURE__ */
|
|
2463
|
-
/* @__PURE__ */
|
|
2464
|
-
/* @__PURE__ */
|
|
2465
|
-
/* @__PURE__ */
|
|
2574
|
+
return /* @__PURE__ */ jsx19("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs12("div", { className: "w-full max-w-2xl space-y-6", children: [
|
|
2575
|
+
/* @__PURE__ */ jsxs12(Card8, { children: [
|
|
2576
|
+
/* @__PURE__ */ jsxs12(CardHeader8, { children: [
|
|
2577
|
+
/* @__PURE__ */ jsx19(CardTitle8, { children: "Invite a member" }),
|
|
2578
|
+
/* @__PURE__ */ jsxs12(CardDescription8, { children: [
|
|
2466
2579
|
"Send an invite to join ",
|
|
2467
2580
|
workspace?.name ?? "this workspace",
|
|
2468
2581
|
"."
|
|
2469
2582
|
] })
|
|
2470
2583
|
] }),
|
|
2471
|
-
/* @__PURE__ */
|
|
2472
|
-
/* @__PURE__ */
|
|
2473
|
-
formError && /* @__PURE__ */
|
|
2474
|
-
successMessage && /* @__PURE__ */
|
|
2475
|
-
/* @__PURE__ */
|
|
2476
|
-
/* @__PURE__ */
|
|
2477
|
-
/* @__PURE__ */
|
|
2584
|
+
/* @__PURE__ */ jsxs12("form", { onSubmit: handleSubmit, "data-testid": "invite-form", children: [
|
|
2585
|
+
/* @__PURE__ */ jsxs12(CardContent8, { className: "space-y-4", children: [
|
|
2586
|
+
formError && /* @__PURE__ */ jsx19(Notice3, { role: "alert", tone: "error", description: formError }),
|
|
2587
|
+
successMessage && /* @__PURE__ */ jsx19(Notice3, { role: "status", tone: "success", description: successMessage }),
|
|
2588
|
+
/* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
|
|
2589
|
+
/* @__PURE__ */ jsx19(Label8, { htmlFor: "invite-email", children: "Email address" }),
|
|
2590
|
+
/* @__PURE__ */ jsx19(
|
|
2478
2591
|
Input8,
|
|
2479
2592
|
{
|
|
2480
2593
|
id: "invite-email",
|
|
@@ -2486,20 +2599,20 @@ function InvitesPage() {
|
|
|
2486
2599
|
}
|
|
2487
2600
|
)
|
|
2488
2601
|
] }),
|
|
2489
|
-
/* @__PURE__ */
|
|
2490
|
-
/* @__PURE__ */
|
|
2491
|
-
/* @__PURE__ */
|
|
2492
|
-
/* @__PURE__ */
|
|
2493
|
-
/* @__PURE__ */
|
|
2494
|
-
/* @__PURE__ */
|
|
2495
|
-
/* @__PURE__ */
|
|
2496
|
-
/* @__PURE__ */
|
|
2602
|
+
/* @__PURE__ */ jsxs12("div", { className: "space-y-2", children: [
|
|
2603
|
+
/* @__PURE__ */ jsx19(Label8, { htmlFor: "invite-role", children: "Role" }),
|
|
2604
|
+
/* @__PURE__ */ jsxs12(Select, { value: inviteRole, onValueChange: (value) => setInviteRole(value), children: [
|
|
2605
|
+
/* @__PURE__ */ jsx19(SelectTrigger, { id: "invite-role", "data-testid": "invite-role-select", children: /* @__PURE__ */ jsx19(SelectValue, { placeholder: "Select role" }) }),
|
|
2606
|
+
/* @__PURE__ */ jsxs12(SelectContent, { children: [
|
|
2607
|
+
/* @__PURE__ */ jsx19(SelectItem, { value: "editor", children: "Editor" }),
|
|
2608
|
+
/* @__PURE__ */ jsx19(SelectItem, { value: "viewer", children: "Viewer" }),
|
|
2609
|
+
/* @__PURE__ */ jsx19(SelectItem, { value: "owner", children: "Owner" })
|
|
2497
2610
|
] })
|
|
2498
2611
|
] })
|
|
2499
2612
|
] })
|
|
2500
2613
|
] }),
|
|
2501
|
-
/* @__PURE__ */
|
|
2502
|
-
|
|
2614
|
+
/* @__PURE__ */ jsx19(CardFooter8, { children: /* @__PURE__ */ jsx19(
|
|
2615
|
+
Button13,
|
|
2503
2616
|
{
|
|
2504
2617
|
type: "submit",
|
|
2505
2618
|
className: "w-full",
|
|
@@ -2509,37 +2622,37 @@ function InvitesPage() {
|
|
|
2509
2622
|
) })
|
|
2510
2623
|
] })
|
|
2511
2624
|
] }),
|
|
2512
|
-
/* @__PURE__ */
|
|
2513
|
-
/* @__PURE__ */
|
|
2514
|
-
/* @__PURE__ */
|
|
2515
|
-
/* @__PURE__ */
|
|
2625
|
+
/* @__PURE__ */ jsxs12(Card8, { children: [
|
|
2626
|
+
/* @__PURE__ */ jsxs12(CardHeader8, { children: [
|
|
2627
|
+
/* @__PURE__ */ jsx19(CardTitle8, { children: "Pending invites" }),
|
|
2628
|
+
/* @__PURE__ */ jsx19(CardDescription8, { children: invitesQuery.data?.length ? `${invitesQuery.data.length} invite${invitesQuery.data.length === 1 ? "" : "s"}` : "No invites yet" })
|
|
2516
2629
|
] }),
|
|
2517
|
-
/* @__PURE__ */
|
|
2518
|
-
revokeError && /* @__PURE__ */
|
|
2519
|
-
invitesQuery.isLoading && /* @__PURE__ */
|
|
2520
|
-
invitesQuery.isError && /* @__PURE__ */
|
|
2521
|
-
invitesQuery.data && invitesQuery.data.length > 0 && /* @__PURE__ */
|
|
2630
|
+
/* @__PURE__ */ jsxs12(CardContent8, { children: [
|
|
2631
|
+
revokeError && /* @__PURE__ */ jsx19(Notice3, { role: "alert", tone: "error", className: "mb-4", description: revokeError }),
|
|
2632
|
+
invitesQuery.isLoading && /* @__PURE__ */ jsx19(LoadingState2, {}),
|
|
2633
|
+
invitesQuery.isError && /* @__PURE__ */ jsx19(Notice3, { tone: "error", description: "Failed to load invites." }),
|
|
2634
|
+
invitesQuery.data && invitesQuery.data.length > 0 && /* @__PURE__ */ jsx19("div", { className: "divide-y", "data-testid": "invites-list", children: invitesQuery.data.map((invite) => {
|
|
2522
2635
|
const status = getInviteStatus(invite);
|
|
2523
|
-
return /* @__PURE__ */
|
|
2636
|
+
return /* @__PURE__ */ jsxs12(
|
|
2524
2637
|
"div",
|
|
2525
2638
|
{
|
|
2526
2639
|
className: "flex items-center justify-between py-3",
|
|
2527
2640
|
"data-testid": `invite-row-${invite.id}`,
|
|
2528
2641
|
children: [
|
|
2529
|
-
/* @__PURE__ */
|
|
2530
|
-
/* @__PURE__ */
|
|
2531
|
-
/* @__PURE__ */
|
|
2532
|
-
/* @__PURE__ */
|
|
2533
|
-
/* @__PURE__ */
|
|
2534
|
-
/* @__PURE__ */
|
|
2642
|
+
/* @__PURE__ */ jsxs12("div", { className: "space-y-1", children: [
|
|
2643
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sm font-medium", children: invite.email }),
|
|
2644
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
2645
|
+
/* @__PURE__ */ jsx19("span", { children: invite.role }),
|
|
2646
|
+
/* @__PURE__ */ jsx19(StatusBadge, { "data-testid": `status-${status}`, tone: STATUS_TONES[status] ?? "neutral", children: status }),
|
|
2647
|
+
/* @__PURE__ */ jsxs12("span", { children: [
|
|
2535
2648
|
"expires",
|
|
2536
2649
|
" ",
|
|
2537
2650
|
new Date(invite.expiresAt).toLocaleDateString()
|
|
2538
2651
|
] })
|
|
2539
2652
|
] })
|
|
2540
2653
|
] }),
|
|
2541
|
-
status === "pending" && /* @__PURE__ */
|
|
2542
|
-
|
|
2654
|
+
status === "pending" && /* @__PURE__ */ jsx19(
|
|
2655
|
+
Button13,
|
|
2543
2656
|
{
|
|
2544
2657
|
variant: "destructive",
|
|
2545
2658
|
size: "sm",
|
|
@@ -2560,7 +2673,7 @@ function InvitesPage() {
|
|
|
2560
2673
|
}
|
|
2561
2674
|
|
|
2562
2675
|
// src/front/workspace/MembersPage.tsx
|
|
2563
|
-
import { useCallback as useCallback7, useState as
|
|
2676
|
+
import { useCallback as useCallback7, useState as useState18 } from "react";
|
|
2564
2677
|
import { useMutation as useMutation3, useQueryClient as useQueryClient5 } from "@tanstack/react-query";
|
|
2565
2678
|
import {
|
|
2566
2679
|
AlertDialog as AlertDialog2,
|
|
@@ -2570,12 +2683,12 @@ import {
|
|
|
2570
2683
|
AlertDialogFooter as AlertDialogFooter2,
|
|
2571
2684
|
AlertDialogHeader as AlertDialogHeader2,
|
|
2572
2685
|
AlertDialogTitle as AlertDialogTitle2,
|
|
2573
|
-
Button as
|
|
2574
|
-
Card as
|
|
2575
|
-
CardContent as
|
|
2576
|
-
CardDescription as
|
|
2577
|
-
CardHeader as
|
|
2578
|
-
CardTitle as
|
|
2686
|
+
Button as Button14,
|
|
2687
|
+
Card as Card9,
|
|
2688
|
+
CardContent as CardContent9,
|
|
2689
|
+
CardDescription as CardDescription9,
|
|
2690
|
+
CardHeader as CardHeader9,
|
|
2691
|
+
CardTitle as CardTitle9,
|
|
2579
2692
|
Select as Select2,
|
|
2580
2693
|
SelectContent as SelectContent2,
|
|
2581
2694
|
SelectItem as SelectItem2,
|
|
@@ -2585,7 +2698,7 @@ import {
|
|
|
2585
2698
|
LoadingState as LoadingState3,
|
|
2586
2699
|
Notice as Notice4
|
|
2587
2700
|
} from "@hachej/boring-ui-kit";
|
|
2588
|
-
import { jsx as
|
|
2701
|
+
import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2589
2702
|
var ROLE_OPTIONS = ["owner", "editor", "viewer"];
|
|
2590
2703
|
function MembersPage() {
|
|
2591
2704
|
const workspace = useCurrentWorkspace();
|
|
@@ -2596,8 +2709,8 @@ function MembersPage() {
|
|
|
2596
2709
|
const currentUserId = session.data?.user?.id ?? "";
|
|
2597
2710
|
const encodedWorkspaceId = encodeURIComponent(workspaceId);
|
|
2598
2711
|
const membersQuery = useWorkspaceMembers(workspaceId);
|
|
2599
|
-
const [toast, setToast] =
|
|
2600
|
-
const [confirmTarget, setConfirmTarget] =
|
|
2712
|
+
const [toast, setToast] = useState18(null);
|
|
2713
|
+
const [confirmTarget, setConfirmTarget] = useState18(null);
|
|
2601
2714
|
const showToast = useCallback7((msg) => {
|
|
2602
2715
|
setToast(msg);
|
|
2603
2716
|
setTimeout(() => setToast(null), 4e3);
|
|
@@ -2658,11 +2771,11 @@ function MembersPage() {
|
|
|
2658
2771
|
removeMutation.mutate(confirmTarget.userId);
|
|
2659
2772
|
}, [confirmTarget, removeMutation]);
|
|
2660
2773
|
const isOwner = myRole === "owner";
|
|
2661
|
-
return /* @__PURE__ */
|
|
2662
|
-
/* @__PURE__ */
|
|
2663
|
-
/* @__PURE__ */
|
|
2664
|
-
/* @__PURE__ */
|
|
2665
|
-
/* @__PURE__ */
|
|
2774
|
+
return /* @__PURE__ */ jsx20("div", { className: "flex min-h-screen items-center justify-center p-4", children: /* @__PURE__ */ jsxs13("div", { className: "w-full max-w-2xl space-y-6", children: [
|
|
2775
|
+
/* @__PURE__ */ jsxs13(Card9, { children: [
|
|
2776
|
+
/* @__PURE__ */ jsxs13(CardHeader9, { children: [
|
|
2777
|
+
/* @__PURE__ */ jsx20(CardTitle9, { children: "Members" }),
|
|
2778
|
+
/* @__PURE__ */ jsxs13(CardDescription9, { children: [
|
|
2666
2779
|
workspace?.name ?? "Workspace",
|
|
2667
2780
|
" \xB7",
|
|
2668
2781
|
" ",
|
|
@@ -2671,45 +2784,45 @@ function MembersPage() {
|
|
|
2671
2784
|
(membersQuery.data?.length ?? 0) !== 1 ? "s" : ""
|
|
2672
2785
|
] })
|
|
2673
2786
|
] }),
|
|
2674
|
-
/* @__PURE__ */
|
|
2675
|
-
toast && /* @__PURE__ */
|
|
2676
|
-
membersQuery.isLoading && /* @__PURE__ */
|
|
2677
|
-
membersQuery.isError && /* @__PURE__ */
|
|
2678
|
-
membersQuery.data && membersQuery.data.length > 0 && /* @__PURE__ */
|
|
2787
|
+
/* @__PURE__ */ jsxs13(CardContent9, { children: [
|
|
2788
|
+
toast && /* @__PURE__ */ jsx20(Notice4, { role: "alert", "data-testid": "toast", tone: "error", className: "mb-4", description: toast }),
|
|
2789
|
+
membersQuery.isLoading && /* @__PURE__ */ jsx20(LoadingState3, {}),
|
|
2790
|
+
membersQuery.isError && /* @__PURE__ */ jsx20(Notice4, { tone: "error", description: "Failed to load members." }),
|
|
2791
|
+
membersQuery.data && membersQuery.data.length > 0 && /* @__PURE__ */ jsx20("div", { className: "divide-y", "data-testid": "members-list", children: membersQuery.data.map((member) => {
|
|
2679
2792
|
const isSelf = member.userId === currentUserId;
|
|
2680
2793
|
const canChangeRole = isOwner && !isSelf;
|
|
2681
2794
|
const canRemove = isOwner || isSelf;
|
|
2682
|
-
return /* @__PURE__ */
|
|
2795
|
+
return /* @__PURE__ */ jsxs13(
|
|
2683
2796
|
"div",
|
|
2684
2797
|
{
|
|
2685
2798
|
className: "flex items-center justify-between py-3",
|
|
2686
2799
|
"data-testid": `member-row-${member.userId}`,
|
|
2687
2800
|
children: [
|
|
2688
|
-
/* @__PURE__ */
|
|
2689
|
-
/* @__PURE__ */
|
|
2690
|
-
/* @__PURE__ */
|
|
2691
|
-
/* @__PURE__ */
|
|
2801
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-3", children: [
|
|
2802
|
+
/* @__PURE__ */ jsx20(InitialsAvatar, { initials: (member.user.name?.[0] ?? member.user.email[0]).toUpperCase() }),
|
|
2803
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
2804
|
+
/* @__PURE__ */ jsxs13("p", { className: "text-sm font-medium", children: [
|
|
2692
2805
|
member.user.name ?? member.user.email,
|
|
2693
|
-
isSelf && /* @__PURE__ */
|
|
2806
|
+
isSelf && /* @__PURE__ */ jsx20("span", { className: "ml-1 text-xs text-muted-foreground", children: "(you)" })
|
|
2694
2807
|
] }),
|
|
2695
|
-
/* @__PURE__ */
|
|
2808
|
+
/* @__PURE__ */ jsx20("p", { className: "text-xs text-muted-foreground", children: member.user.email })
|
|
2696
2809
|
] })
|
|
2697
2810
|
] }),
|
|
2698
|
-
/* @__PURE__ */
|
|
2699
|
-
/* @__PURE__ */
|
|
2811
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
|
|
2812
|
+
/* @__PURE__ */ jsxs13(
|
|
2700
2813
|
Select2,
|
|
2701
2814
|
{
|
|
2702
2815
|
value: member.role,
|
|
2703
2816
|
disabled: !canChangeRole,
|
|
2704
2817
|
onValueChange: (value) => handleRoleChange(member.userId, value),
|
|
2705
2818
|
children: [
|
|
2706
|
-
/* @__PURE__ */
|
|
2707
|
-
/* @__PURE__ */
|
|
2819
|
+
/* @__PURE__ */ jsx20(SelectTrigger2, { "data-testid": `role-select-${member.userId}`, className: "h-8 w-28 text-xs", children: /* @__PURE__ */ jsx20(SelectValue2, { placeholder: "Role" }) }),
|
|
2820
|
+
/* @__PURE__ */ jsx20(SelectContent2, { children: ROLE_OPTIONS.map((r) => /* @__PURE__ */ jsx20(SelectItem2, { value: r, children: r }, r)) })
|
|
2708
2821
|
]
|
|
2709
2822
|
}
|
|
2710
2823
|
),
|
|
2711
|
-
canRemove && /* @__PURE__ */
|
|
2712
|
-
|
|
2824
|
+
canRemove && /* @__PURE__ */ jsx20(
|
|
2825
|
+
Button14,
|
|
2713
2826
|
{
|
|
2714
2827
|
variant: "destructive",
|
|
2715
2828
|
size: "sm",
|
|
@@ -2726,22 +2839,22 @@ function MembersPage() {
|
|
|
2726
2839
|
}) })
|
|
2727
2840
|
] })
|
|
2728
2841
|
] }),
|
|
2729
|
-
/* @__PURE__ */
|
|
2842
|
+
/* @__PURE__ */ jsx20(
|
|
2730
2843
|
AlertDialog2,
|
|
2731
2844
|
{
|
|
2732
2845
|
open: confirmTarget !== null,
|
|
2733
2846
|
onOpenChange: (open) => {
|
|
2734
2847
|
if (!open) setConfirmTarget(null);
|
|
2735
2848
|
},
|
|
2736
|
-
children: /* @__PURE__ */
|
|
2737
|
-
/* @__PURE__ */
|
|
2738
|
-
/* @__PURE__ */
|
|
2739
|
-
/* @__PURE__ */
|
|
2849
|
+
children: /* @__PURE__ */ jsxs13(AlertDialogContent2, { children: [
|
|
2850
|
+
/* @__PURE__ */ jsxs13(AlertDialogHeader2, { children: [
|
|
2851
|
+
/* @__PURE__ */ jsx20(AlertDialogTitle2, { children: confirmTarget?.userId === currentUserId ? "Leave workspace?" : `Remove ${confirmTarget?.user.name ?? confirmTarget?.user.email}?` }),
|
|
2852
|
+
/* @__PURE__ */ jsx20(AlertDialogDescription2, { children: confirmTarget?.userId === currentUserId ? "You will lose access to this workspace." : "This member will lose access to the workspace." })
|
|
2740
2853
|
] }),
|
|
2741
|
-
/* @__PURE__ */
|
|
2742
|
-
/* @__PURE__ */
|
|
2743
|
-
/* @__PURE__ */
|
|
2744
|
-
|
|
2854
|
+
/* @__PURE__ */ jsxs13(AlertDialogFooter2, { children: [
|
|
2855
|
+
/* @__PURE__ */ jsx20(AlertDialogCancel2, { children: "Cancel" }),
|
|
2856
|
+
/* @__PURE__ */ jsx20(
|
|
2857
|
+
Button14,
|
|
2745
2858
|
{
|
|
2746
2859
|
variant: "destructive",
|
|
2747
2860
|
disabled: removeMutation.isPending,
|
|
@@ -2758,7 +2871,7 @@ function MembersPage() {
|
|
|
2758
2871
|
}
|
|
2759
2872
|
|
|
2760
2873
|
// src/front/workspace/WorkspaceSettingsPage.tsx
|
|
2761
|
-
import { useCallback as useCallback8, useEffect as useEffect10, useState as
|
|
2874
|
+
import { useCallback as useCallback8, useEffect as useEffect10, useState as useState19 } from "react";
|
|
2762
2875
|
import { useQuery as useQuery6, useMutation as useMutation4, useQueryClient as useQueryClient6 } from "@tanstack/react-query";
|
|
2763
2876
|
import { useNavigate as useNavigate4 } from "react-router-dom";
|
|
2764
2877
|
import {
|
|
@@ -2769,7 +2882,7 @@ import {
|
|
|
2769
2882
|
AlertDialogFooter as AlertDialogFooter3,
|
|
2770
2883
|
AlertDialogHeader as AlertDialogHeader3,
|
|
2771
2884
|
AlertDialogTitle as AlertDialogTitle3,
|
|
2772
|
-
Button as
|
|
2885
|
+
Button as Button15,
|
|
2773
2886
|
IconButton,
|
|
2774
2887
|
SettingsActionRow as UiSettingsActionRow2,
|
|
2775
2888
|
SettingsNav as UiSettingsNav2,
|
|
@@ -2788,7 +2901,7 @@ import {
|
|
|
2788
2901
|
ShieldAlert as ShieldAlert2,
|
|
2789
2902
|
Trash2 as Trash22
|
|
2790
2903
|
} from "lucide-react";
|
|
2791
|
-
import { Fragment as
|
|
2904
|
+
import { Fragment as Fragment5, jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2792
2905
|
var STATE_TONES = {
|
|
2793
2906
|
pending: "info",
|
|
2794
2907
|
ready: "success",
|
|
@@ -2797,13 +2910,13 @@ var STATE_TONES = {
|
|
|
2797
2910
|
function SettingsTopBar2({ workspaceId, workspaceName }) {
|
|
2798
2911
|
const navigate = useNavigate4();
|
|
2799
2912
|
const workspaceHref = workspaceId ? `/workspace/${encodeURIComponent(workspaceId)}` : "/";
|
|
2800
|
-
return /* @__PURE__ */
|
|
2913
|
+
return /* @__PURE__ */ jsx21(
|
|
2801
2914
|
"header",
|
|
2802
2915
|
{
|
|
2803
2916
|
className: "relative flex h-[52px] items-center justify-between gap-3 border-b border-border/40 bg-background px-4",
|
|
2804
2917
|
"aria-label": "App top bar",
|
|
2805
|
-
children: /* @__PURE__ */
|
|
2806
|
-
/* @__PURE__ */
|
|
2918
|
+
children: /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-1 items-center gap-2.5", children: [
|
|
2919
|
+
/* @__PURE__ */ jsx21(
|
|
2807
2920
|
IconButton,
|
|
2808
2921
|
{
|
|
2809
2922
|
type: "button",
|
|
@@ -2816,11 +2929,11 @@ function SettingsTopBar2({ workspaceId, workspaceName }) {
|
|
|
2816
2929
|
children: "B"
|
|
2817
2930
|
}
|
|
2818
2931
|
),
|
|
2819
|
-
/* @__PURE__ */
|
|
2820
|
-
/* @__PURE__ */
|
|
2821
|
-
/* @__PURE__ */
|
|
2822
|
-
/* @__PURE__ */
|
|
2823
|
-
/* @__PURE__ */
|
|
2932
|
+
/* @__PURE__ */ jsx21("span", { className: "truncate text-[13px] font-medium tracking-tight text-foreground", children: "Boring" }),
|
|
2933
|
+
/* @__PURE__ */ jsx21("span", { "aria-hidden": "true", className: "text-muted-foreground/30", children: "/" }),
|
|
2934
|
+
/* @__PURE__ */ jsx21("span", { className: "truncate text-[13px] text-muted-foreground", children: workspaceName }),
|
|
2935
|
+
/* @__PURE__ */ jsx21("span", { "aria-hidden": "true", className: "text-muted-foreground/30", children: "/" }),
|
|
2936
|
+
/* @__PURE__ */ jsx21("span", { className: "truncate text-[13px] text-muted-foreground", children: "Settings" })
|
|
2824
2937
|
] })
|
|
2825
2938
|
}
|
|
2826
2939
|
);
|
|
@@ -2831,26 +2944,26 @@ function SettingsPageHeader2({
|
|
|
2831
2944
|
role,
|
|
2832
2945
|
isDefault
|
|
2833
2946
|
}) {
|
|
2834
|
-
return /* @__PURE__ */
|
|
2835
|
-
/* @__PURE__ */
|
|
2836
|
-
/* @__PURE__ */
|
|
2837
|
-
/* @__PURE__ */
|
|
2838
|
-
/* @__PURE__ */
|
|
2839
|
-
/* @__PURE__ */
|
|
2840
|
-
/* @__PURE__ */
|
|
2841
|
-
isDefault ? /* @__PURE__ */
|
|
2947
|
+
return /* @__PURE__ */ jsxs14("header", { className: "boring-settings-page-header", children: [
|
|
2948
|
+
/* @__PURE__ */ jsxs14("div", { className: "boring-settings-context", children: [
|
|
2949
|
+
/* @__PURE__ */ jsx21("div", { className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-md bg-foreground text-[12px] font-semibold text-background", children: workspaceInitial2 }),
|
|
2950
|
+
/* @__PURE__ */ jsxs14("div", { className: "min-w-0 flex-1", children: [
|
|
2951
|
+
/* @__PURE__ */ jsx21("p", { className: "truncate text-[13px] font-medium text-foreground", children: workspaceName }),
|
|
2952
|
+
/* @__PURE__ */ jsxs14("div", { className: "mt-1 flex flex-wrap items-center gap-1.5", children: [
|
|
2953
|
+
/* @__PURE__ */ jsx21("span", { className: "inline-flex h-5 items-center rounded border border-border/60 px-1.5 text-[11px] text-muted-foreground", children: roleLabel(role) }),
|
|
2954
|
+
isDefault ? /* @__PURE__ */ jsx21("span", { className: "inline-flex h-5 items-center rounded border border-border/60 px-1.5 text-[11px] text-muted-foreground", children: "Default" }) : null
|
|
2842
2955
|
] })
|
|
2843
2956
|
] })
|
|
2844
2957
|
] }),
|
|
2845
|
-
/* @__PURE__ */
|
|
2846
|
-
/* @__PURE__ */
|
|
2847
|
-
/* @__PURE__ */
|
|
2848
|
-
/* @__PURE__ */
|
|
2958
|
+
/* @__PURE__ */ jsxs14("div", { className: "max-w-2xl", children: [
|
|
2959
|
+
/* @__PURE__ */ jsx21("p", { className: "text-[11px] font-medium uppercase leading-4 text-muted-foreground", children: "Workspace" }),
|
|
2960
|
+
/* @__PURE__ */ jsx21("h1", { className: "mt-1 text-[20px] font-semibold leading-7 tracking-tight text-foreground", children: "Workspace settings" }),
|
|
2961
|
+
/* @__PURE__ */ jsx21("p", { className: "mt-2 text-[13px] leading-5 text-muted-foreground", children: "Manage workspace identity, runtime recovery, and irreversible workspace actions." })
|
|
2849
2962
|
] })
|
|
2850
2963
|
] });
|
|
2851
2964
|
}
|
|
2852
2965
|
function FieldNote({ children }) {
|
|
2853
|
-
return /* @__PURE__ */
|
|
2966
|
+
return /* @__PURE__ */ jsx21("p", { className: "text-[12px] leading-5 text-muted-foreground", children });
|
|
2854
2967
|
}
|
|
2855
2968
|
function roleLabel(role) {
|
|
2856
2969
|
if (!role) return "Loading role";
|
|
@@ -2868,14 +2981,14 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
2868
2981
|
const queryClient = useQueryClient6();
|
|
2869
2982
|
const navigate = useNavigate4();
|
|
2870
2983
|
const workspaceId = workspace?.id ?? "";
|
|
2871
|
-
const [nameValue, setNameValue] =
|
|
2872
|
-
const [nameError, setNameError] =
|
|
2873
|
-
const [retryError, setRetryError] =
|
|
2874
|
-
const [deleteConfirmName, setDeleteConfirmName] =
|
|
2875
|
-
const [deleteDialogOpen, setDeleteDialogOpen] =
|
|
2876
|
-
const [deleteError, setDeleteError] =
|
|
2877
|
-
const [imageUploadDirValue, setImageUploadDirValue] =
|
|
2878
|
-
const [fileSettingsError, setFileSettingsError] =
|
|
2984
|
+
const [nameValue, setNameValue] = useState19(null);
|
|
2985
|
+
const [nameError, setNameError] = useState19(null);
|
|
2986
|
+
const [retryError, setRetryError] = useState19(null);
|
|
2987
|
+
const [deleteConfirmName, setDeleteConfirmName] = useState19("");
|
|
2988
|
+
const [deleteDialogOpen, setDeleteDialogOpen] = useState19(false);
|
|
2989
|
+
const [deleteError, setDeleteError] = useState19(null);
|
|
2990
|
+
const [imageUploadDirValue, setImageUploadDirValue] = useState19(null);
|
|
2991
|
+
const [fileSettingsError, setFileSettingsError] = useState19(null);
|
|
2879
2992
|
const displayName = nameValue ?? workspace?.name ?? "";
|
|
2880
2993
|
const encodedWorkspaceId = encodeURIComponent(workspaceId);
|
|
2881
2994
|
const requestHeaders = workspaceId ? { "x-boring-workspace-id": workspaceId } : void 0;
|
|
@@ -3021,18 +3134,18 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3021
3134
|
const canDeleteWorkspace = role === "owner" || role === null;
|
|
3022
3135
|
const workspaceName = workspace?.name ?? "Workspace";
|
|
3023
3136
|
const workspaceInitial2 = (workspace?.name?.trim()?.[0] ?? "W").toUpperCase();
|
|
3024
|
-
const topBarNode = topBar === void 0 ? /* @__PURE__ */
|
|
3137
|
+
const topBarNode = topBar === void 0 ? /* @__PURE__ */ jsx21(SettingsTopBar2, { workspaceId, workspaceName }) : topBar;
|
|
3025
3138
|
const navItems = WORKSPACE_NAV_ITEMS.filter((item) => {
|
|
3026
3139
|
if (item.href === "#runtime") return hasRuntime;
|
|
3027
3140
|
if (item.href === "#files") return hasFileSettings;
|
|
3028
3141
|
return true;
|
|
3029
3142
|
});
|
|
3030
|
-
return /* @__PURE__ */
|
|
3143
|
+
return /* @__PURE__ */ jsxs14("main", { className: "boring-settings-shell", children: [
|
|
3031
3144
|
topBarNode,
|
|
3032
|
-
/* @__PURE__ */
|
|
3033
|
-
/* @__PURE__ */
|
|
3034
|
-
/* @__PURE__ */
|
|
3035
|
-
/* @__PURE__ */
|
|
3145
|
+
/* @__PURE__ */ jsx21("div", { className: "boring-settings-scroll", children: /* @__PURE__ */ jsxs14("div", { className: "boring-settings-layout", children: [
|
|
3146
|
+
/* @__PURE__ */ jsx21("aside", { className: "boring-settings-sidebar", children: /* @__PURE__ */ jsx21(UiSettingsNav2, { label: "Workspace settings", items: navItems }) }),
|
|
3147
|
+
/* @__PURE__ */ jsxs14("div", { className: "boring-settings-content space-y-4", children: [
|
|
3148
|
+
/* @__PURE__ */ jsx21(
|
|
3036
3149
|
SettingsPageHeader2,
|
|
3037
3150
|
{
|
|
3038
3151
|
workspaceName,
|
|
@@ -3041,16 +3154,16 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3041
3154
|
isDefault: Boolean(workspace?.isDefault)
|
|
3042
3155
|
}
|
|
3043
3156
|
),
|
|
3044
|
-
/* @__PURE__ */
|
|
3157
|
+
/* @__PURE__ */ jsx21(
|
|
3045
3158
|
UiSettingsPanel2,
|
|
3046
3159
|
{
|
|
3047
3160
|
id: "general",
|
|
3048
|
-
icon: /* @__PURE__ */
|
|
3161
|
+
icon: /* @__PURE__ */ jsx21(Settings22, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
3049
3162
|
title: "General",
|
|
3050
3163
|
description: "Keep the workspace name clear enough to scan in menus.",
|
|
3051
|
-
footer: /* @__PURE__ */
|
|
3052
|
-
nameChanged ? /* @__PURE__ */
|
|
3053
|
-
|
|
3164
|
+
footer: /* @__PURE__ */ jsxs14(Fragment5, { children: [
|
|
3165
|
+
nameChanged ? /* @__PURE__ */ jsx21(
|
|
3166
|
+
Button15,
|
|
3054
3167
|
{
|
|
3055
3168
|
type: "button",
|
|
3056
3169
|
variant: "ghost",
|
|
@@ -3063,8 +3176,8 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3063
3176
|
children: "Reset"
|
|
3064
3177
|
}
|
|
3065
3178
|
) : null,
|
|
3066
|
-
/* @__PURE__ */
|
|
3067
|
-
|
|
3179
|
+
/* @__PURE__ */ jsx21(
|
|
3180
|
+
Button15,
|
|
3068
3181
|
{
|
|
3069
3182
|
"data-testid": "save-name",
|
|
3070
3183
|
size: "sm",
|
|
@@ -3074,11 +3187,11 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3074
3187
|
}
|
|
3075
3188
|
)
|
|
3076
3189
|
] }),
|
|
3077
|
-
children: /* @__PURE__ */
|
|
3078
|
-
nameError && /* @__PURE__ */
|
|
3079
|
-
/* @__PURE__ */
|
|
3080
|
-
/* @__PURE__ */
|
|
3081
|
-
/* @__PURE__ */
|
|
3190
|
+
children: /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
|
|
3191
|
+
nameError && /* @__PURE__ */ jsx21(Notice5, { "data-testid": "name-error", role: "alert", tone: "error", description: nameError }),
|
|
3192
|
+
/* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
|
|
3193
|
+
/* @__PURE__ */ jsx21(Label9, { htmlFor: "workspace-name", className: "text-[12px]", children: "Workspace name" }),
|
|
3194
|
+
/* @__PURE__ */ jsx21(
|
|
3082
3195
|
Input9,
|
|
3083
3196
|
{
|
|
3084
3197
|
id: "workspace-name",
|
|
@@ -3090,50 +3203,50 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3090
3203
|
"aria-invalid": nameError ? "true" : "false"
|
|
3091
3204
|
}
|
|
3092
3205
|
),
|
|
3093
|
-
/* @__PURE__ */
|
|
3206
|
+
/* @__PURE__ */ jsx21(FieldNote, { children: canEditName ? "Editors and owners can rename a workspace." : "Viewers can inspect settings, but cannot rename this workspace." })
|
|
3094
3207
|
] })
|
|
3095
3208
|
] })
|
|
3096
3209
|
}
|
|
3097
3210
|
),
|
|
3098
|
-
hasRuntime && /* @__PURE__ */
|
|
3211
|
+
hasRuntime && /* @__PURE__ */ jsx21(
|
|
3099
3212
|
UiSettingsPanel2,
|
|
3100
3213
|
{
|
|
3101
3214
|
id: "runtime",
|
|
3102
3215
|
testId: "runtime-card",
|
|
3103
|
-
icon: /* @__PURE__ */
|
|
3216
|
+
icon: /* @__PURE__ */ jsx21(HardDrive, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
3104
3217
|
title: "Runtime",
|
|
3105
3218
|
description: "Provisioning status for this workspace.",
|
|
3106
|
-
children: /* @__PURE__ */
|
|
3107
|
-
/* @__PURE__ */
|
|
3108
|
-
/* @__PURE__ */
|
|
3109
|
-
/* @__PURE__ */
|
|
3219
|
+
children: /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
|
|
3220
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex min-h-10 flex-wrap items-center justify-between gap-3 rounded-md border border-border/50 bg-muted/10 px-3 py-2", children: [
|
|
3221
|
+
/* @__PURE__ */ jsx21("span", { className: "text-[13px] font-medium", children: "State" }),
|
|
3222
|
+
/* @__PURE__ */ jsx21(StatusBadge2, { "data-testid": `runtime-state-${runtime.state}`, tone: STATE_TONES[runtime.state] ?? "neutral", children: runtime.state })
|
|
3110
3223
|
] }),
|
|
3111
|
-
runtime.state === "ready" && runtime.volumePath && /* @__PURE__ */
|
|
3224
|
+
runtime.state === "ready" && runtime.volumePath && /* @__PURE__ */ jsxs14(
|
|
3112
3225
|
"div",
|
|
3113
3226
|
{
|
|
3114
3227
|
"data-testid": "volume-path",
|
|
3115
3228
|
className: "space-y-1 rounded-md border border-border/50 bg-muted/10 px-3 py-2",
|
|
3116
3229
|
children: [
|
|
3117
|
-
/* @__PURE__ */
|
|
3118
|
-
/* @__PURE__ */
|
|
3230
|
+
/* @__PURE__ */ jsx21("p", { className: "text-[13px] font-medium", children: "Volume" }),
|
|
3231
|
+
/* @__PURE__ */ jsx21("code", { className: "block overflow-x-auto whitespace-nowrap text-[12px] text-muted-foreground", children: runtime.volumePath })
|
|
3119
3232
|
]
|
|
3120
3233
|
}
|
|
3121
3234
|
),
|
|
3122
|
-
runtime.state === "error" && runtime.lastError && /* @__PURE__ */
|
|
3235
|
+
runtime.state === "error" && runtime.lastError && /* @__PURE__ */ jsxs14(
|
|
3123
3236
|
"div",
|
|
3124
3237
|
{
|
|
3125
3238
|
"data-testid": "runtime-error",
|
|
3126
3239
|
role: "alert",
|
|
3127
3240
|
className: "flex gap-2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-[13px] leading-5 text-destructive",
|
|
3128
3241
|
children: [
|
|
3129
|
-
/* @__PURE__ */
|
|
3242
|
+
/* @__PURE__ */ jsx21(AlertCircle, { className: "mt-0.5 h-4 w-4 shrink-0", "aria-hidden": "true" }),
|
|
3130
3243
|
runtime.lastError
|
|
3131
3244
|
]
|
|
3132
3245
|
}
|
|
3133
3246
|
),
|
|
3134
|
-
runtime.state === "error" && runtime.lastErrorOp === "provision" && /* @__PURE__ */
|
|
3135
|
-
/* @__PURE__ */
|
|
3136
|
-
|
|
3247
|
+
runtime.state === "error" && runtime.lastErrorOp === "provision" && /* @__PURE__ */ jsxs14("div", { className: "space-y-3", children: [
|
|
3248
|
+
/* @__PURE__ */ jsxs14(
|
|
3249
|
+
Button15,
|
|
3137
3250
|
{
|
|
3138
3251
|
"data-testid": "retry-provision",
|
|
3139
3252
|
variant: "outline",
|
|
@@ -3141,14 +3254,14 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3141
3254
|
disabled: retryMutation.isPending,
|
|
3142
3255
|
onClick: () => retryMutation.mutate(),
|
|
3143
3256
|
children: [
|
|
3144
|
-
/* @__PURE__ */
|
|
3257
|
+
/* @__PURE__ */ jsx21(RefreshCw, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
3145
3258
|
retryMutation.isPending ? "Retrying..." : "Retry provisioning"
|
|
3146
3259
|
]
|
|
3147
3260
|
}
|
|
3148
3261
|
),
|
|
3149
|
-
retryError && /* @__PURE__ */
|
|
3262
|
+
retryError && /* @__PURE__ */ jsx21(Notice5, { "data-testid": "retry-error", role: "alert", tone: "error", description: retryError })
|
|
3150
3263
|
] }),
|
|
3151
|
-
runtime.state === "error" && runtime.lastErrorOp === "destroy" && /* @__PURE__ */
|
|
3264
|
+
runtime.state === "error" && runtime.lastErrorOp === "destroy" && /* @__PURE__ */ jsx21(
|
|
3152
3265
|
"p",
|
|
3153
3266
|
{
|
|
3154
3267
|
"data-testid": "destroy-guidance",
|
|
@@ -3159,16 +3272,16 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3159
3272
|
] })
|
|
3160
3273
|
}
|
|
3161
3274
|
),
|
|
3162
|
-
hasFileSettings && /* @__PURE__ */
|
|
3275
|
+
hasFileSettings && /* @__PURE__ */ jsx21(
|
|
3163
3276
|
UiSettingsPanel2,
|
|
3164
3277
|
{
|
|
3165
3278
|
id: "files",
|
|
3166
3279
|
testId: "file-settings-card",
|
|
3167
|
-
icon: /* @__PURE__ */
|
|
3280
|
+
icon: /* @__PURE__ */ jsx21(FileImage, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
3168
3281
|
title: "Files",
|
|
3169
3282
|
description: "Configure where markdown editor image uploads are stored. Direct/local workspaces can also edit .boring/settings.",
|
|
3170
|
-
footer: /* @__PURE__ */
|
|
3171
|
-
|
|
3283
|
+
footer: /* @__PURE__ */ jsx21(
|
|
3284
|
+
Button15,
|
|
3172
3285
|
{
|
|
3173
3286
|
"data-testid": "save-file-settings",
|
|
3174
3287
|
size: "sm",
|
|
@@ -3177,11 +3290,11 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3177
3290
|
children: fileSettingsMutation.isPending ? "Saving..." : "Save file settings"
|
|
3178
3291
|
}
|
|
3179
3292
|
),
|
|
3180
|
-
children: /* @__PURE__ */
|
|
3181
|
-
fileSettingsError && /* @__PURE__ */
|
|
3182
|
-
/* @__PURE__ */
|
|
3183
|
-
/* @__PURE__ */
|
|
3184
|
-
/* @__PURE__ */
|
|
3293
|
+
children: /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
|
|
3294
|
+
fileSettingsError && /* @__PURE__ */ jsx21(Notice5, { "data-testid": "file-settings-error", role: "alert", tone: "error", description: fileSettingsError }),
|
|
3295
|
+
/* @__PURE__ */ jsxs14("div", { className: "space-y-2", children: [
|
|
3296
|
+
/* @__PURE__ */ jsx21(Label9, { htmlFor: "markdown-image-upload-dir", className: "text-[12px]", children: "Markdown image upload path" }),
|
|
3297
|
+
/* @__PURE__ */ jsx21(
|
|
3185
3298
|
Input9,
|
|
3186
3299
|
{
|
|
3187
3300
|
id: "markdown-image-upload-dir",
|
|
@@ -3192,35 +3305,35 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3192
3305
|
disabled: !canEditName
|
|
3193
3306
|
}
|
|
3194
3307
|
),
|
|
3195
|
-
/* @__PURE__ */
|
|
3308
|
+
/* @__PURE__ */ jsxs14(FieldNote, { children: [
|
|
3196
3309
|
"Relative workspace path used by markdown image uploads. Stored in ",
|
|
3197
|
-
/* @__PURE__ */
|
|
3310
|
+
/* @__PURE__ */ jsx21("code", { children: ".boring/settings" }),
|
|
3198
3311
|
"."
|
|
3199
3312
|
] })
|
|
3200
3313
|
] })
|
|
3201
3314
|
] })
|
|
3202
3315
|
}
|
|
3203
3316
|
),
|
|
3204
|
-
/* @__PURE__ */
|
|
3317
|
+
/* @__PURE__ */ jsx21(
|
|
3205
3318
|
UiSettingsPanel2,
|
|
3206
3319
|
{
|
|
3207
3320
|
id: "danger-zone",
|
|
3208
3321
|
testId: "danger-zone",
|
|
3209
|
-
icon: /* @__PURE__ */
|
|
3322
|
+
icon: /* @__PURE__ */ jsx21(ShieldAlert2, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
3210
3323
|
title: "Danger zone",
|
|
3211
3324
|
description: "Permanently delete this workspace and all provisioned data.",
|
|
3212
3325
|
danger: true,
|
|
3213
|
-
children: /* @__PURE__ */
|
|
3214
|
-
deleteError && /* @__PURE__ */
|
|
3215
|
-
!canDeleteWorkspace ? /* @__PURE__ */
|
|
3216
|
-
/* @__PURE__ */
|
|
3326
|
+
children: /* @__PURE__ */ jsxs14("div", { className: "space-y-4", children: [
|
|
3327
|
+
deleteError && /* @__PURE__ */ jsx21(Notice5, { "data-testid": "delete-error", role: "alert", tone: "error", description: deleteError }),
|
|
3328
|
+
!canDeleteWorkspace ? /* @__PURE__ */ jsx21("div", { className: "rounded-md border border-border/50 bg-muted/10 px-3 py-2 text-[13px] leading-5 text-muted-foreground", children: "Only workspace owners can delete this workspace." }) : null,
|
|
3329
|
+
/* @__PURE__ */ jsx21(
|
|
3217
3330
|
UiSettingsActionRow2,
|
|
3218
3331
|
{
|
|
3219
3332
|
title: "Delete workspace",
|
|
3220
3333
|
description: "Delete the workspace record and re-issue cleanup for provisioned runtime data.",
|
|
3221
|
-
action: /* @__PURE__ */
|
|
3222
|
-
/* @__PURE__ */
|
|
3223
|
-
|
|
3334
|
+
action: /* @__PURE__ */ jsxs14(AlertDialog3, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: [
|
|
3335
|
+
/* @__PURE__ */ jsxs14(
|
|
3336
|
+
Button15,
|
|
3224
3337
|
{
|
|
3225
3338
|
variant: "destructive",
|
|
3226
3339
|
size: "sm",
|
|
@@ -3231,21 +3344,21 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3231
3344
|
setDeleteConfirmName("");
|
|
3232
3345
|
},
|
|
3233
3346
|
children: [
|
|
3234
|
-
/* @__PURE__ */
|
|
3347
|
+
/* @__PURE__ */ jsx21(Trash22, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
3235
3348
|
"Delete workspace"
|
|
3236
3349
|
]
|
|
3237
3350
|
}
|
|
3238
3351
|
),
|
|
3239
|
-
/* @__PURE__ */
|
|
3240
|
-
/* @__PURE__ */
|
|
3241
|
-
/* @__PURE__ */
|
|
3242
|
-
/* @__PURE__ */
|
|
3352
|
+
/* @__PURE__ */ jsxs14(AlertDialogContent3, { children: [
|
|
3353
|
+
/* @__PURE__ */ jsxs14(AlertDialogHeader3, { children: [
|
|
3354
|
+
/* @__PURE__ */ jsx21(AlertDialogTitle3, { children: "Delete workspace?" }),
|
|
3355
|
+
/* @__PURE__ */ jsxs14(AlertDialogDescription3, { children: [
|
|
3243
3356
|
"This action cannot be undone. Type ",
|
|
3244
|
-
/* @__PURE__ */
|
|
3357
|
+
/* @__PURE__ */ jsx21("strong", { children: workspace?.name }),
|
|
3245
3358
|
" to confirm."
|
|
3246
3359
|
] })
|
|
3247
3360
|
] }),
|
|
3248
|
-
/* @__PURE__ */
|
|
3361
|
+
/* @__PURE__ */ jsx21("div", { className: "px-6 pb-2", children: /* @__PURE__ */ jsx21(
|
|
3249
3362
|
Input9,
|
|
3250
3363
|
{
|
|
3251
3364
|
"data-testid": "delete-confirm-input",
|
|
@@ -3256,10 +3369,10 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3256
3369
|
autoComplete: "off"
|
|
3257
3370
|
}
|
|
3258
3371
|
) }),
|
|
3259
|
-
/* @__PURE__ */
|
|
3260
|
-
/* @__PURE__ */
|
|
3261
|
-
/* @__PURE__ */
|
|
3262
|
-
|
|
3372
|
+
/* @__PURE__ */ jsxs14(AlertDialogFooter3, { children: [
|
|
3373
|
+
/* @__PURE__ */ jsx21(AlertDialogCancel3, { children: "Cancel" }),
|
|
3374
|
+
/* @__PURE__ */ jsx21(
|
|
3375
|
+
Button15,
|
|
3263
3376
|
{
|
|
3264
3377
|
variant: "destructive",
|
|
3265
3378
|
size: "sm",
|
|
@@ -3283,10 +3396,10 @@ function WorkspaceSettingsPage({ topBar } = {}) {
|
|
|
3283
3396
|
}
|
|
3284
3397
|
|
|
3285
3398
|
// src/front/CoreFront.tsx
|
|
3286
|
-
import { Fragment as
|
|
3399
|
+
import { Fragment as Fragment6, jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3287
3400
|
var CSP_NONCE_META_NAME = "boring-csp-nonce";
|
|
3288
3401
|
function PlaceholderPage({ name }) {
|
|
3289
|
-
return /* @__PURE__ */
|
|
3402
|
+
return /* @__PURE__ */ jsxs15("div", { "data-testid": `placeholder-${name}`, children: [
|
|
3290
3403
|
name,
|
|
3291
3404
|
" (not yet implemented)"
|
|
3292
3405
|
] });
|
|
@@ -3318,11 +3431,12 @@ function CoreFront({ children, authPages, cspNonce }) {
|
|
|
3318
3431
|
const ForgotPasswordPage2 = authPages?.forgotPassword ?? ForgotPasswordPage;
|
|
3319
3432
|
const ResetPasswordPage2 = authPages?.resetPassword ?? ResetPasswordPage;
|
|
3320
3433
|
const VerifyEmailPage2 = authPages?.verifyEmail ?? VerifyEmailPage;
|
|
3434
|
+
const AuthErrorPage2 = authPages?.authError ?? AuthErrorPage;
|
|
3321
3435
|
const UserSettingsPage2 = authPages?.userSettings ?? UserSettingsPage;
|
|
3322
|
-
return /* @__PURE__ */
|
|
3323
|
-
/* @__PURE__ */
|
|
3324
|
-
/* @__PURE__ */
|
|
3325
|
-
/* @__PURE__ */
|
|
3436
|
+
return /* @__PURE__ */ jsx22(HelmetProvider, { children: /* @__PURE__ */ jsx22(AppErrorBoundary, { children: /* @__PURE__ */ jsx22(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx22(ConfigProvider, { children: /* @__PURE__ */ jsx22(ThemeProvider, { children: /* @__PURE__ */ jsx22(AuthProvider, { queryClient, children: /* @__PURE__ */ jsx22(UserIdentityProvider, { children: /* @__PURE__ */ jsx22(BrowserRouter, { children: /* @__PURE__ */ jsx22(WorkspaceAuthProvider, { children: /* @__PURE__ */ jsxs15(TopBarSlotProvider, { slot: /* @__PURE__ */ jsx22(UserMenu, {}), children: [
|
|
3437
|
+
/* @__PURE__ */ jsx22(Helmet, { children: resolvedCspNonce ? /* @__PURE__ */ jsxs15(Fragment6, { children: [
|
|
3438
|
+
/* @__PURE__ */ jsx22("meta", { name: CSP_NONCE_META_NAME, content: resolvedCspNonce }),
|
|
3439
|
+
/* @__PURE__ */ jsx22(
|
|
3326
3440
|
"script",
|
|
3327
3441
|
{
|
|
3328
3442
|
type: "application/json",
|
|
@@ -3332,28 +3446,30 @@ function CoreFront({ children, authPages, cspNonce }) {
|
|
|
3332
3446
|
}
|
|
3333
3447
|
)
|
|
3334
3448
|
] }) : null }),
|
|
3335
|
-
/* @__PURE__ */
|
|
3336
|
-
/* @__PURE__ */
|
|
3337
|
-
/* @__PURE__ */
|
|
3338
|
-
/* @__PURE__ */
|
|
3339
|
-
/* @__PURE__ */
|
|
3340
|
-
/* @__PURE__ */
|
|
3341
|
-
/* @__PURE__ */
|
|
3342
|
-
/* @__PURE__ */
|
|
3343
|
-
/* @__PURE__ */
|
|
3344
|
-
/* @__PURE__ */
|
|
3345
|
-
/* @__PURE__ */
|
|
3346
|
-
/* @__PURE__ */
|
|
3347
|
-
/* @__PURE__ */
|
|
3348
|
-
/* @__PURE__ */
|
|
3349
|
-
/* @__PURE__ */
|
|
3449
|
+
/* @__PURE__ */ jsx22(AuthGate, { publicPaths: ["/invites"], children: /* @__PURE__ */ jsx22(Suspense, { fallback: null, children: /* @__PURE__ */ jsxs15(Routes, { children: [
|
|
3450
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.signin, element: /* @__PURE__ */ jsx22(SignInPage2, {}) }),
|
|
3451
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.signup, element: /* @__PURE__ */ jsx22(SignUpPage2, {}) }),
|
|
3452
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.forgotPassword, element: /* @__PURE__ */ jsx22(ForgotPasswordPage2, {}) }),
|
|
3453
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.resetPassword, element: /* @__PURE__ */ jsx22(ResetPasswordPage2, {}) }),
|
|
3454
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.verifyEmail, element: /* @__PURE__ */ jsx22(VerifyEmailPage2, {}) }),
|
|
3455
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.authError, element: /* @__PURE__ */ jsx22(AuthErrorPage2, {}) }),
|
|
3456
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.callbackGithub, element: /* @__PURE__ */ jsx22(PlaceholderPage, { name: "github-callback" }) }),
|
|
3457
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.callbackGoogle, element: /* @__PURE__ */ jsx22(PlaceholderPage, { name: "google-callback" }) }),
|
|
3458
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.me, element: /* @__PURE__ */ jsx22(UserSettingsPage2, {}) }),
|
|
3459
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.workspaceMembers, element: /* @__PURE__ */ jsx22(MembersPage, {}) }),
|
|
3460
|
+
/* @__PURE__ */ jsx22(Route, { path: "/workspace/:id/members", element: /* @__PURE__ */ jsx22(MembersPage, {}) }),
|
|
3461
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.workspaceInvites, element: /* @__PURE__ */ jsx22(InvitesPage, {}) }),
|
|
3462
|
+
/* @__PURE__ */ jsx22(Route, { path: "/workspace/:id/invites", element: /* @__PURE__ */ jsx22(InvitesPage, {}) }),
|
|
3463
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.workspaceSettings, element: /* @__PURE__ */ jsx22(WorkspaceSettingsPage, {}) }),
|
|
3464
|
+
/* @__PURE__ */ jsx22(Route, { path: "/workspace/:id/settings", element: /* @__PURE__ */ jsx22(WorkspaceSettingsPage, {}) }),
|
|
3465
|
+
/* @__PURE__ */ jsx22(Route, { path: routes.inviteAccept, element: /* @__PURE__ */ jsx22(InviteAcceptPage, {}) }),
|
|
3350
3466
|
children
|
|
3351
3467
|
] }) }) })
|
|
3352
3468
|
] }) }) }) }) }) }) }) }) }) });
|
|
3353
3469
|
}
|
|
3354
3470
|
|
|
3355
3471
|
// src/front/commands/CoreCommandContributions.tsx
|
|
3356
|
-
import { useMemo as useMemo7, useState as
|
|
3472
|
+
import { useMemo as useMemo7, useState as useState20 } from "react";
|
|
3357
3473
|
import { useNavigate as useNavigate5 } from "react-router-dom";
|
|
3358
3474
|
|
|
3359
3475
|
// src/front/workspace/commands.ts
|
|
@@ -3395,7 +3511,7 @@ function useCoreCommands() {
|
|
|
3395
3511
|
const navigate = useNavigate5();
|
|
3396
3512
|
const signOut = useSignOut();
|
|
3397
3513
|
const workspace = useCurrentWorkspace();
|
|
3398
|
-
const [isSigningOut, setIsSigningOut] =
|
|
3514
|
+
const [isSigningOut, setIsSigningOut] = useState20(false);
|
|
3399
3515
|
return useMemo7(() => {
|
|
3400
3516
|
const result = [
|
|
3401
3517
|
{
|
|
@@ -3530,6 +3646,7 @@ export {
|
|
|
3530
3646
|
useSignOut,
|
|
3531
3647
|
UserIdentityProvider,
|
|
3532
3648
|
useUser,
|
|
3649
|
+
GoogleAuthButton,
|
|
3533
3650
|
SignInPage,
|
|
3534
3651
|
SignUpPage,
|
|
3535
3652
|
ForgotPasswordPage,
|