Feat: dark mode for independent pages (#17045)

This commit is contained in:
KVOJJJin
2025-03-31 10:28:19 +08:00
committed by GitHub
parent 46d235bca0
commit e008faf729
16 changed files with 66 additions and 110 deletions

View File

@@ -50,8 +50,8 @@ const ActivateForm = () => {
{checkRes && !checkRes.is_valid && (
<div className="flex flex-col md:w-[400px]">
<div className="mx-auto w-full">
<div className="mb-3 flex h-20 w-20 items-center justify-center rounded-[20px] border border-gray-100 p-5 text-[40px] font-bold shadow-lg">🤷</div>
<h2 className="text-[32px] font-bold text-gray-900">{t('login.invalid')}</h2>
<div className="mb-3 flex h-20 w-20 items-center justify-center rounded-[20px] border border-divider-regular bg-components-option-card-option-bg p-5 text-[40px] font-bold shadow-lg">🤷</div>
<h2 className="text-[32px] font-bold text-text-primary">{t('login.invalid')}</h2>
</div>
<div className="mx-auto mt-6 w-full">
<Button variant='primary' className='w-full !text-sm'>

View File

@@ -7,6 +7,7 @@ import cn from '@/utils/classnames'
const Activate = () => {
return (
<div className={cn(
'bg-background-body',
style.background,
'flex min-h-screen w-full',
'sm:p-4 lg:p-8',
@@ -15,13 +16,13 @@ const Activate = () => {
)}>
<div className={
cn(
'flex w-full shrink-0 flex-col rounded-2xl bg-white shadow',
'flex w-full shrink-0 flex-col rounded-2xl bg-background-section-burn shadow',
'space-between',
)
}>
<Header />
<ActivateForm />
<div className='px-8 py-6 text-sm font-normal text-gray-500'>
<div className='px-8 py-6 text-sm font-normal text-text-tertiary'>
© {new Date().getFullYear()} LangGenius, Inc. All rights reserved.
</div>
</div>

View File

@@ -1,4 +0,0 @@
.logo {
background: #fff center no-repeat url(./team-28x28.png);
background-size: 56px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

View File

@@ -21,11 +21,7 @@ export default function Select({
<div className="w-56 text-right">
<Menu as="div" className="relative inline-block text-left">
<div>
<MenuButton className="h-[44px]justify-center inline-flex w-full items-center
rounded-lg border border-gray-200
px-[10px] py-[6px] text-[13px]
font-medium text-gray-900
hover:bg-gray-100">
<MenuButton className="h-[44px]justify-center inline-flex w-full items-center rounded-lg border border-components-button-secondary-border px-[10px] py-[6px] text-[13px] font-medium text-text-primary hover:bg-state-base-hover">
<GlobeAltIcon className="mr-1 h-5 w-5" aria-hidden="true" />
{item?.name}
</MenuButton>
@@ -39,12 +35,12 @@ export default function Select({
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<MenuItems className="absolute right-0 z-10 mt-2 w-[200px] origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
<MenuItems className="absolute right-0 z-10 mt-2 w-[200px] origin-top-right divide-y divide-divider-regular rounded-md bg-components-panel-bg shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
<div className="px-1 py-1 ">
{items.map((item) => {
return <MenuItem key={item.value}>
<button
className={'group flex w-full items-center rounded-lg px-3 py-2 text-sm text-gray-700 data-[active]:bg-gray-100'}
className={'group flex w-full items-center rounded-lg px-3 py-2 text-sm text-text-secondary data-[active]:bg-state-base-hover'}
onClick={(evt) => {
evt.preventDefault()
onChange && onChange(item.value)
@@ -63,50 +59,3 @@ export default function Select({
</div>
)
}
export function InputSelect({
items,
value,
onChange,
}: ISelectProps) {
const item = items.filter(item => item.value === value)[0]
return (
<div className="w-full">
<Menu as="div" className="w-full">
<div>
<MenuButton className="block h-[38px] w-full appearance-none rounded-md border border-gray-300 px-3 py-2 text-left shadow-sm placeholder:text-gray-400 sm:text-sm">
{item?.name}
</MenuButton>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<MenuItems className="absolute right-0 z-10 mt-2 w-full origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
<div className="px-1 py-1 ">
{items.map((item) => {
return <MenuItem key={item.value}>
<button
className={'group flex w-full items-center rounded-md px-2 py-2 text-sm data-[active]:bg-gray-100'}
onClick={() => {
onChange && onChange(item.value)
}}
>
{item.name}
</button>
</MenuItem>
})}
</div>
</MenuItems>
</Transition>
</Menu>
</div>
)
}

View File

@@ -86,8 +86,8 @@ const ChangePasswordForm = () => {
{verifyTokenRes && !verifyTokenRes.is_valid && (
<div className="flex flex-col md:w-[400px]">
<div className="mx-auto w-full">
<div className="mb-3 flex h-20 w-20 items-center justify-center rounded-[20px] border border-gray-100 p-5 text-[40px] font-bold shadow-lg">🤷</div>
<h2 className="text-[32px] font-bold text-gray-900">{t('login.invalid')}</h2>
<div className="mb-3 flex h-20 w-20 items-center justify-center rounded-[20px] border border-divider-regular bg-components-option-card-option-bg p-5 text-[40px] font-bold shadow-lg">🤷</div>
<h2 className="text-[32px] font-bold text-text-primary">{t('login.invalid')}</h2>
</div>
<div className="mx-auto mt-6 w-full">
<Button variant='primary' className='w-full !text-sm'>
@@ -99,19 +99,19 @@ const ChangePasswordForm = () => {
{verifyTokenRes && verifyTokenRes.is_valid && !showSuccess && (
<div className='flex flex-col md:w-[400px]'>
<div className="mx-auto w-full">
<h2 className="text-[32px] font-bold text-gray-900">
<h2 className="text-[32px] font-bold text-text-primary">
{t('login.changePassword')}
</h2>
<p className='mt-1 text-sm text-gray-600'>
<p className='mt-1 text-sm text-text-secondary'>
{t('login.changePasswordTip')}
</p>
</div>
<div className="mx-auto mt-6 w-full">
<div className="bg-white">
<div className="relative">
{/* Password */}
<div className='mb-5'>
<label htmlFor="password" className="my-2 flex items-center justify-between text-sm font-medium text-gray-900">
<label htmlFor="password" className="my-2 flex items-center justify-between text-sm font-medium text-text-primary">
{t('common.account.newPassword')}
</label>
<Input
@@ -126,7 +126,7 @@ const ChangePasswordForm = () => {
</div>
{/* Confirm Password */}
<div className='mb-5'>
<label htmlFor="confirmPassword" className="my-2 flex items-center justify-between text-sm font-medium text-gray-900">
<label htmlFor="confirmPassword" className="my-2 flex items-center justify-between text-sm font-medium text-text-primary">
{t('common.account.confirmPassword')}
</label>
<Input
@@ -154,10 +154,10 @@ const ChangePasswordForm = () => {
{verifyTokenRes && verifyTokenRes.is_valid && showSuccess && (
<div className="flex flex-col md:w-[400px]">
<div className="mx-auto w-full">
<div className="mb-3 flex h-20 w-20 items-center justify-center rounded-[20px] border border-gray-100 p-5 text-[40px] font-bold shadow-lg">
<div className="mb-3 flex h-20 w-20 items-center justify-center rounded-[20px] border border-divider-regular bg-components-option-card-option-bg p-5 text-[40px] font-bold shadow-lg">
<CheckCircleIcon className='h-10 w-10 text-[#039855]' />
</div>
<h2 className="text-[32px] font-bold text-gray-900">
<h2 className="text-[32px] font-bold text-text-primary">
{t('login.passwordChangedTip')}
</h2>
</div>

View File

@@ -82,20 +82,20 @@ const ForgotPasswordForm = () => {
? <Loading />
: <>
<div className="sm:mx-auto sm:w-full sm:max-w-md">
<h2 className="text-[32px] font-bold text-gray-900">
<h2 className="text-[32px] font-bold text-text-primary">
{isEmailSent ? t('login.resetLinkSent') : t('login.forgotPassword')}
</h2>
<p className='mt-1 text-sm text-gray-600'>
<p className='mt-1 text-sm text-text-secondary'>
{isEmailSent ? t('login.checkEmailForResetLink') : t('login.forgotPasswordDesc')}
</p>
</div>
<div className="mt-8 grow sm:mx-auto sm:w-full sm:max-w-md">
<div className="bg-white ">
<div className="relative">
<form>
{!isEmailSent && (
<div className='mb-5'>
<label htmlFor="email"
className="my-2 flex items-center justify-between text-sm font-medium text-gray-900">
className="my-2 flex items-center justify-between text-sm font-medium text-text-primary">
{t('login.email')}
</label>
<div className="mt-1">

View File

@@ -13,6 +13,7 @@ const ForgotPassword = () => {
return (
<div className={classNames(
'bg-background-body',
style.background,
'flex w-full min-h-screen',
'p-4 lg:p-8',
@@ -21,13 +22,13 @@ const ForgotPassword = () => {
)}>
<div className={
classNames(
'flex w-full flex-col bg-white shadow rounded-2xl shrink-0',
'flex w-full flex-col bg-background-section-burn shadow rounded-2xl shrink-0',
'md:w-[608px] space-between',
)
}>
<Header />
{token ? <ChangePasswordForm /> : <ForgotPasswordForm />}
<div className='px-8 py-6 text-sm font-normal text-gray-500'>
<div className='px-8 py-6 text-sm font-normal text-text-tertiary'>
© {new Date().getFullYear()} LangGenius, Inc. All rights reserved.
</div>
</div>

View File

@@ -54,7 +54,7 @@ const InitPasswordPopup = () => {
{!validated && (
<div className="mx-12 block min-w-28">
<div className="mb-4">
<label htmlFor="password" className="block text-sm font-medium text-gray-700">
<label htmlFor="password" className="block text-sm font-medium text-text-secondary">
{t('login.adminInitPassword')}
</label>
@@ -64,7 +64,7 @@ const InitPasswordPopup = () => {
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
className="block w-full appearance-none rounded-md border border-gray-300 px-3 py-2 shadow-sm placeholder:text-gray-400 focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm"
className="block w-full appearance-none rounded-md border border-divider-regular px-3 py-2 shadow-sm placeholder:text-text-quaternary focus:border-indigo-500 focus:outline-none focus:ring-indigo-500 sm:text-sm"
/>
</div>
</div>

View File

@@ -1,19 +1,27 @@
import React from 'react'
import style from '../signin/page.module.css'
import InitPasswordPopup from './InitPasswordPopup'
import classNames from '@/utils/classnames'
import cn from '@/utils/classnames'
const Install = () => {
return (
<div className={classNames(
<div className={cn(
'bg-background-body',
style.background,
'flex w-full min-h-screen',
'flex min-h-screen w-full',
'p-4 lg:p-8',
'gap-x-20',
'justify-center lg:justify-start',
)}>
<div className="m-auto block w-96">
<InitPasswordPopup />
<div className={
cn(
'flex w-full shrink-0 flex-col rounded-2xl bg-background-section-burn shadow',
'space-between',
)
}>
<div className="m-auto block w-96">
<InitPasswordPopup />
</div>
</div>
</div>
)

View File

@@ -97,23 +97,21 @@ const InstallForm = () => {
? <Loading />
: <>
<div className="sm:mx-auto sm:w-full sm:max-w-md">
<h2 className="text-[32px] font-bold text-gray-900">{t('login.setAdminAccount')}</h2>
<p className='
mt-1 text-sm text-gray-600
'>{t('login.setAdminAccountDesc')}</p>
<h2 className="text-[32px] font-bold text-text-primary">{t('login.setAdminAccount')}</h2>
<p className='mt-1 text-sm text-text-secondary'>{t('login.setAdminAccountDesc')}</p>
</div>
<div className="mt-8 grow sm:mx-auto sm:w-full sm:max-w-md">
<div className="bg-white ">
<div className="relative">
<form onSubmit={handleSubmit(onSubmit)} onKeyDown={handleKeyDown}>
<div className='mb-5'>
<label htmlFor="email" className="my-2 flex items-center justify-between text-sm font-medium text-gray-900">
<label htmlFor="email" className="my-2 flex items-center justify-between text-sm font-medium text-text-primary">
{t('login.email')}
</label>
<div className="mt-1">
<div className="mt-1 rounded-md shadow-sm">
<input
{...register('email')}
placeholder={t('login.emailPlaceholder') || ''}
className={'block w-full appearance-none rounded-lg border border-gray-200 px-3 py-2 pl-[14px] caret-primary-600 placeholder:text-gray-400 hover:border-gray-300 hover:shadow-sm focus:border-primary-500 focus:outline-none focus:ring-primary-500 sm:text-sm'}
className={'w-full appearance-none rounded-md border border-transparent bg-components-input-bg-normal py-[7px] pl-2 text-components-input-text-filled caret-primary-600 outline-none placeholder:text-components-input-text-placeholder hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active focus:bg-components-input-bg-active focus:shadow-xs'}
/>
{errors.email && <span className='text-sm text-red-400'>{t(`${errors.email?.message}`)}</span>}
</div>
@@ -121,21 +119,21 @@ const InstallForm = () => {
</div>
<div className='mb-5'>
<label htmlFor="name" className="my-2 flex items-center justify-between text-sm font-medium text-gray-900">
<label htmlFor="name" className="my-2 flex items-center justify-between text-sm font-medium text-text-primary">
{t('login.name')}
</label>
<div className="relative mt-1 rounded-md shadow-sm">
<input
{...register('name')}
placeholder={t('login.namePlaceholder') || ''}
className={'block w-full appearance-none rounded-lg border border-gray-200 px-3 py-2 pl-[14px] pr-10 caret-primary-600 placeholder:text-gray-400 hover:border-gray-300 hover:shadow-sm focus:border-primary-500 focus:outline-none focus:ring-primary-500 sm:text-sm'}
className={'w-full appearance-none rounded-md border border-transparent bg-components-input-bg-normal py-[7px] pl-2 text-components-input-text-filled caret-primary-600 outline-none placeholder:text-components-input-text-placeholder hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active focus:bg-components-input-bg-active focus:shadow-xs'}
/>
</div>
{errors.name && <span className='text-sm text-red-400'>{t(`${errors.name.message}`)}</span>}
</div>
<div className='mb-5'>
<label htmlFor="password" className="my-2 flex items-center justify-between text-sm font-medium text-gray-900">
<label htmlFor="password" className="my-2 flex items-center justify-between text-sm font-medium text-text-primary">
{t('login.password')}
</label>
<div className="relative mt-1 rounded-md shadow-sm">
@@ -143,21 +141,21 @@ const InstallForm = () => {
{...register('password')}
type={showPassword ? 'text' : 'password'}
placeholder={t('login.passwordPlaceholder') || ''}
className={'block w-full appearance-none rounded-lg border border-gray-200 px-3 py-2 pl-[14px] pr-10 caret-primary-600 placeholder:text-gray-400 hover:border-gray-300 hover:shadow-sm focus:border-primary-500 focus:outline-none focus:ring-primary-500 sm:text-sm'}
className={'w-full appearance-none rounded-md border border-transparent bg-components-input-bg-normal py-[7px] pl-2 text-components-input-text-filled caret-primary-600 outline-none placeholder:text-components-input-text-placeholder hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active focus:bg-components-input-bg-active focus:shadow-xs'}
/>
<div className="absolute inset-y-0 right-0 flex items-center pr-3">
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="text-gray-400 hover:text-gray-500 focus:text-gray-500 focus:outline-none"
className="text-text-quaternary hover:text-text-tertiary focus:text-text-tertiary focus:outline-none"
>
{showPassword ? '👀' : '😝'}
</button>
</div>
</div>
<div className={classNames('mt-1 text-xs text-gray-500', {
<div className={classNames('mt-1 text-xs text-text-tertiary', {
'text-red-400 !text-sm': errors.password,
})}>{t('login.error.passwordInvalid')}</div>
</div>
@@ -168,11 +166,11 @@ const InstallForm = () => {
</Button>
</div>
</form>
<div className="mt-2 block w-full text-xs text-gray-600">
<div className="mt-2 block w-full text-xs text-text-tertiary">
{t('login.license.tip')}
&nbsp;
<Link
className='text-primary-600'
className='text-text-accent'
target='_blank' rel='noopener noreferrer'
href={'https://docs.dify.ai/user-agreement/open-source'}
>{t('login.license.link')}</Link>

View File

@@ -7,6 +7,7 @@ import classNames from '@/utils/classnames'
const Install = () => {
return (
<div className={classNames(
'bg-background-body',
style.background,
'flex w-full min-h-screen',
'p-4 lg:p-8',
@@ -15,13 +16,13 @@ const Install = () => {
)}>
<div className={
classNames(
'flex w-full flex-col bg-white shadow rounded-2xl shrink-0',
'flex w-full flex-col bg-background-section-burn shadow rounded-2xl shrink-0',
'md:w-[608px] space-between',
)
}>
<Header />
<InstallForm />
<div className='px-8 py-6 text-sm font-normal text-gray-500'>
<div className='px-8 py-6 text-sm font-normal text-text-tertiary'>
© {new Date().getFullYear()} LangGenius, Inc. All rights reserved.
</div>
</div>

View File

@@ -6,6 +6,7 @@ import cn from '@/utils/classnames'
export default async function SignInLayout({ children }: any) {
return <>
<div className={cn(
'bg-background-body',
style.background,
'flex min-h-screen w-full',
'sm:p-4 lg:p-8',
@@ -14,7 +15,7 @@ export default async function SignInLayout({ children }: any) {
)}>
<div className={
cn(
'flex w-full shrink-0 flex-col rounded-2xl bg-white shadow',
'flex w-full shrink-0 flex-col rounded-2xl bg-background-section-burn shadow',
'space-between',
)
}>

View File

@@ -6,6 +6,7 @@ import cn from '@/utils/classnames'
export default async function SignInLayout({ children }: any) {
return <>
<div className={cn(
'bg-background-body',
style.background,
'flex min-h-screen w-full',
'sm:p-4 lg:p-8',
@@ -14,7 +15,7 @@ export default async function SignInLayout({ children }: any) {
)}>
<div className={
cn(
'flex w-full shrink-0 flex-col rounded-2xl bg-white shadow',
'flex w-full shrink-0 flex-col rounded-2xl bg-background-section-burn shadow',
'space-between',
)
}>

View File

@@ -85,7 +85,7 @@ const NormalForm = () => {
}
if (systemFeatures.license?.status === LicenseStatus.LOST) {
return <div className='mx-auto mt-8 w-full'>
<div className='bg-white'>
<div className='relative'>
<div className="rounded-lg bg-gradient-to-r from-workflow-workflow-progress-bg-1 to-workflow-workflow-progress-bg-2 p-4">
<div className='shadows-shadow-lg relative mb-2 flex h-10 w-10 items-center justify-center rounded-xl bg-components-card-bg shadow'>
<RiContractLine className='h-5 w-5' />
@@ -99,7 +99,7 @@ const NormalForm = () => {
}
if (systemFeatures.license?.status === LicenseStatus.EXPIRED) {
return <div className='mx-auto mt-8 w-full'>
<div className='bg-white'>
<div className='relative'>
<div className="rounded-lg bg-gradient-to-r from-workflow-workflow-progress-bg-1 to-workflow-workflow-progress-bg-2 p-4">
<div className='shadows-shadow-lg relative mb-2 flex h-10 w-10 items-center justify-center rounded-xl bg-components-card-bg shadow'>
<RiContractLine className='h-5 w-5' />
@@ -113,7 +113,7 @@ const NormalForm = () => {
}
if (systemFeatures.license?.status === LicenseStatus.INACTIVE) {
return <div className='mx-auto mt-8 w-full'>
<div className='bg-white'>
<div className='relative'>
<div className="rounded-lg bg-gradient-to-r from-workflow-workflow-progress-bg-1 to-workflow-workflow-progress-bg-2 p-4">
<div className='shadows-shadow-lg relative mb-2 flex h-10 w-10 items-center justify-center rounded-xl bg-components-card-bg shadow'>
<RiContractLine className='h-5 w-5' />
@@ -138,7 +138,7 @@ const NormalForm = () => {
<h2 className="title-4xl-semi-bold text-text-primary">{t('login.pageTitle')}</h2>
<p className='body-md-regular mt-2 text-text-tertiary'>{t('login.welcome')}</p>
</div>}
<div className="bg-white">
<div className="relative">
<div className="mt-6 flex flex-col gap-3">
{systemFeatures.enable_social_oauth_login && <SocialAuth />}
{systemFeatures.sso_enforced_for_signin && <div className='w-full'>
@@ -151,7 +151,7 @@ const NormalForm = () => {
<div className='h-px w-full bg-gradient-to-r from-background-gradient-mask-transparent via-divider-regular to-background-gradient-mask-transparent'></div>
</div>
<div className="relative flex justify-center">
<span className="system-xs-medium-uppercase bg-white px-2 text-text-tertiary">{t('login.or')}</span>
<span className="system-xs-medium-uppercase px-2 text-text-tertiary">{t('login.or')}</span>
</div>
</div>}
{

View File

@@ -81,7 +81,7 @@ const OneMoreStep = () => {
</div>
<div className="mx-auto mt-6 w-full">
<div className="bg-white">
<div className="relative">
<div className="mb-5">
<label className="system-md-semibold my-2 flex items-center justify-between text-text-secondary">
{t('login.invitationCode')}