{header}
-
+
-
- {isRoot ? null : (
-
-
- {t("title")}
-
- )}
- {children}
-
+
{children}
{footer}
diff --git a/packages/vitnode/src/views/auth/sign-in/form/sign-in-form-content.tsx b/packages/vitnode/src/views/auth/sign-in/form/sign-in-form-content.tsx
index abe19af99..e891cc04b 100644
--- a/packages/vitnode/src/views/auth/sign-in/form/sign-in-form-content.tsx
+++ b/packages/vitnode/src/views/auth/sign-in/form/sign-in-form-content.tsx
@@ -1,10 +1,13 @@
import { Link } from "@tanstack/react-router";
+import { LockIcon, MailIcon } from "lucide-react";
import { AnimatePresence, motion, useReducedMotion } from "motion/react";
import { useTranslations } from "use-intl";
import { AutoForm } from "@/components/form/auto-form";
import { AutoFormInput } from "@/components/form/fields/input";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
+import { useFormApi } from "@/components/ui/form";
+import { InputGroupAddon } from "@/components/ui/input-group";
import { Skeleton } from "@/components/ui/skeleton";
import {
REVEAL_EXIT_TRANSITION,
@@ -16,10 +19,28 @@ import {
} from "@/lib/motion";
import { AUTH_HREF } from "../../auth-link";
+import { rememberEmail } from "../../remembered-email";
import { type SignInSubmit, useSignInForm } from "./use-sign-in-form";
export type { SignInSubmit };
+const ResetPasswordLink = ({ href }: { href: string }) => {
+ const t = useTranslations("core.auth.sign_in");
+ const { form } = useFormApi();
+
+ return (
+
{
+ rememberEmail(form.getFieldValue("email"));
+ }}
+ to={href}
+ >
+ {t("password.reset")}
+
+ );
+};
+
export const SignInFormContent = ({
onSignIn,
resetPasswordHref = AUTH_HREF.resetPassword,
@@ -73,27 +94,36 @@ export const SignInFormContent = ({
{
id: "email",
component: props => (
-
+
+
+
+
+
),
},
{
id: "password",
component: props => (
- {t("password.reset")}
-
+
) : undefined
}
type="password"
{...props}
- />
+ >
+
+
+
+
),
},
]}
diff --git a/packages/vitnode/src/views/auth/sign-up/components/password-input.tsx b/packages/vitnode/src/views/auth/sign-up/components/password-input.tsx
index 56c427082..752e15e25 100644
--- a/packages/vitnode/src/views/auth/sign-up/components/password-input.tsx
+++ b/packages/vitnode/src/views/auth/sign-up/components/password-input.tsx
@@ -1,12 +1,17 @@
-import { CheckIcon, XIcon } from "lucide-react";
+import { CheckIcon, LockIcon, XIcon } from "lucide-react";
import React from "react";
import { useTranslations } from "use-intl";
import type { ItemAutoFormComponentProps } from "@/components/form/auto-form";
+import type { Input } from "@/components/ui/input";
import { AutoFormLabel } from "@/components/form/common/label";
import { FormControl, FormMessage } from "@/components/ui/form";
-import { Input } from "@/components/ui/input";
+import {
+ InputGroup,
+ InputGroupAddon,
+ InputGroupInput,
+} from "@/components/ui/input-group";
import {
Tooltip,
TooltipContent,
@@ -54,31 +59,37 @@ export const PasswordInput = ({
-
- {
- setOpenTooltip(false);
- field.onBlur();
- props.onBlur?.(e);
- }}
- onChange={e => {
- setOpenTooltip(true);
- field.onChange(e);
- props.onChange?.(e);
- }}
- pattern={pattern ?? props.pattern}
- value={field.value ?? ""}
- {...props}
- />
-
- }
- />
+
+
+ {
+ setOpenTooltip(false);
+ field.onBlur();
+ props.onBlur?.(e);
+ }}
+ onChange={e => {
+ setOpenTooltip(true);
+ field.onChange(e);
+ props.onChange?.(e);
+ }}
+ pattern={pattern ?? props.pattern}
+ value={field.value ?? ""}
+ {...props}
+ />
+
+ }
+ />
+
+
+
+
+ >
+
+
+
+
{value.length >= 3 && (
{t.rich("username.your_user_code", {
@@ -68,7 +76,16 @@ export const SignUpFormContent = ({
{
id: "email",
component: props => (
-
+
+
+
+
+
),
},
{
diff --git a/packages/vitnode/src/views/layouts/providers.tsx b/packages/vitnode/src/views/layouts/providers.tsx
index 6a607d2c6..3eac33675 100644
--- a/packages/vitnode/src/views/layouts/providers.tsx
+++ b/packages/vitnode/src/views/layouts/providers.tsx
@@ -6,6 +6,8 @@ import type { VitNodeConfig } from "@/vitnode.config";
import { EditWidgetsHost } from "@/blocks/edit-widgets-host";
import { EditorConfigProvider } from "@/components/editor-provider";
import { LanguagesProvider } from "@/components/languages-provider";
+import { LogoContext } from "@/components/logo-context";
+import { LogoVitNodeBrand } from "@/components/logo-vitnode";
import { ThemeProvider } from "@/components/theme-provider";
import { Toaster } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
@@ -15,7 +17,7 @@ import { RateLimitListener } from "./rate-limit-listener";
export interface VitNodeProvidersConfig extends Pick<
VitNodeConfig,
- "debug" | "editor" | "theme"
+ "debug" | "editor" | "logo" | "theme"
> {
locales: LocaleConfig[];
}
@@ -23,12 +25,14 @@ export interface VitNodeProvidersConfig extends Pick<
export const VitNodeProviders = ({
children,
toaster,
- config: { debug, editor, locales, theme },
+ config: { debug, editor, locales, logo: Logo = LogoVitNodeBrand, theme },
}: {
children: React.ReactNode;
config: VitNodeProvidersConfig;
toaster?: React.ComponentProps
;
}) => {
+ const logo = React.useMemo(() => , [Logo]);
+
React.useEffect(() => {
// eslint-disable-next-line react-you-might-not-need-an-effect/no-event-handler
if (!(debug && CONFIG.node_development)) return;
@@ -52,7 +56,9 @@ export const VitNodeProviders = ({
- {children}
+
+ {children}
+
diff --git a/packages/vitnode/src/vitnode.config.ts b/packages/vitnode/src/vitnode.config.ts
index 408e86dad..a39624f92 100644
--- a/packages/vitnode/src/vitnode.config.ts
+++ b/packages/vitnode/src/vitnode.config.ts
@@ -12,6 +12,7 @@ import type { SearchProviderApiPlugin } from "./api/models/search";
import type { SSOApiPlugin } from "./api/models/sso";
import type { StorageApiPlugin } from "./api/models/storage";
import type { VitNodeEditorConfig } from "./components/editor-provider";
+import type { VitNodeLogo } from "./components/logo-context";
import type { ThemeProviderProps } from "./components/theme-provider";
import type { DefaultTemplateEmailProps } from "./emails/default-template";
import type {
@@ -34,6 +35,7 @@ export interface VitNodeConfig<
/** Editor settings shared by every `Editor` in the app. */
editor?: VitNodeEditorConfig;
i18n: VitNodeI18nConfig;
+ logo?: VitNodeLogo;
metadata: VitNodeMetadata;
plugins: BuildPluginReturn[];
theme?: Omit<
diff --git a/turbo.json b/turbo.json
index 40f38b8c8..9a0f82827 100644
--- a/turbo.json
+++ b/turbo.json
@@ -66,21 +66,6 @@
},
"start": {
"dependsOn": ["^start"]
- },
- "i18n:create": {
- "dependsOn": ["^i18n:create"]
- },
- "i18n:check": {
- "dependsOn": ["^i18n:check"]
- },
- "i18n:delete": {
- "dependsOn": ["^i18n:delete"]
- },
- "i18n:update": {
- "dependsOn": ["^i18n:update"]
- },
- "i18n:update:ai": {
- "dependsOn": ["^i18n:update:ai"]
}
}
}