123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- 'use client'
- import {
- useMemo,
- useState,
- } from 'react'
- import { useTranslation } from 'react-i18next'
- import { RiExternalLinkLine } from '@remixicon/react'
- import {
- useRouter,
- useSearchParams,
- } from 'next/navigation'
- import UserInfo from './user-info'
- import SearchInput from './search-input'
- import RoleSelector from './role-selector'
- import Confirm from './verify-state-modal'
- import Button from '@/app/components/base/button'
- import Checkbox from '@/app/components/base/checkbox'
- import {
- useEducationAdd,
- useInvalidateEducationStatus,
- } from '@/service/use-education'
- import { useProviderContext } from '@/context/provider-context'
- import { useToastContext } from '@/app/components/base/toast'
- import { EDUCATION_VERIFYING_LOCALSTORAGE_ITEM } from '@/app/education-apply/constants'
- import { getLocaleOnClient } from '@/i18n'
- const EducationApplyAge = () => {
- const { t } = useTranslation()
- const locale = getLocaleOnClient()
- const [schoolName, setSchoolName] = useState('')
- const [role, setRole] = useState('Student')
- const [ageChecked, setAgeChecked] = useState(false)
- const [inSchoolChecked, setInSchoolChecked] = useState(false)
- const {
- isPending,
- mutateAsync: educationAdd,
- } = useEducationAdd({ onSuccess: () => {} })
- const [modalShow, setShowModal] = useState<undefined | { title: string; desc: string; onConfirm?: () => void }>(undefined)
- const { onPlanInfoChanged } = useProviderContext()
- const updateEducationStatus = useInvalidateEducationStatus()
- const { notify } = useToastContext()
- const router = useRouter()
- const docLink = useMemo(() => {
- if (locale === 'zh-Hans')
- return 'https://docs.dify.ai/zh-hans/getting-started/dify-for-education'
- if (locale === 'ja-JP')
- return 'https://docs.dify.ai/ja-jp/getting-started/dify-for-education'
- return 'https://docs.dify.ai/getting-started/dify-for-education'
- }, [locale])
- const handleModalConfirm = () => {
- setShowModal(undefined)
- onPlanInfoChanged()
- updateEducationStatus()
- localStorage.removeItem(EDUCATION_VERIFYING_LOCALSTORAGE_ITEM)
- router.replace('/')
- }
- const searchParams = useSearchParams()
- const token = searchParams.get('token')
- const handleSubmit = () => {
- educationAdd({
- token: token || '',
- role,
- institution: schoolName,
- }).then((res) => {
- if (res.message === 'success') {
- setShowModal({
- title: t('education.successTitle'),
- desc: t('education.successContent'),
- onConfirm: handleModalConfirm,
- })
- }
- else {
- notify({
- type: 'error',
- message: t('education.submitError'),
- })
- }
- })
- }
- return (
- <div className='fixed inset-0 z-[31] overflow-y-auto bg-background-body p-6'>
- <div className='mx-auto w-full max-w-[1408px] rounded-2xl border border-effects-highlight bg-background-default-subtle'>
- <div
- className="h-[349px] w-full overflow-hidden rounded-t-2xl bg-cover bg-center bg-no-repeat"
- style={{
- backgroundImage: 'url(/education/bg.png)',
- }}
- >
- </div>
- <div className='mt-[-349px] flex h-[88px] items-center justify-between px-8 py-6'>
- <img
- src='/logo/logo-site-dark.png'
- alt='dify logo'
- className='h-10'
- />
- </div>
- <div className='mx-auto max-w-[720px] px-8 pb-[180px]'>
- <div className='mb-2 flex h-[192px] flex-col justify-end pb-4 pt-3 text-text-primary-on-surface'>
- <div className='title-5xl-bold mb-2 shadow-xs'>{t('education.toVerified')}</div>
- <div className='system-md-medium shadow-xs'>
- {t('education.toVerifiedTip.front')}
- <span className='system-md-semibold underline'>{t('education.toVerifiedTip.coupon')}</span>
- {t('education.toVerifiedTip.end')}
- </div>
- </div>
- <div className='mb-7'>
- <UserInfo />
- </div>
- <div className='mb-7'>
- <div className='system-md-semibold mb-1 flex h-6 items-center text-text-secondary'>
- {t('education.form.schoolName.title')}
- </div>
- <SearchInput
- value={schoolName}
- onChange={setSchoolName}
- />
- </div>
- <div className='mb-7'>
- <div className='system-md-semibold mb-1 flex h-6 items-center text-text-secondary'>
- {t('education.form.schoolRole.title')}
- </div>
- <RoleSelector
- value={role}
- onChange={setRole}
- />
- </div>
- <div className='mb-7'>
- <div className='system-md-semibold mb-1 flex h-6 items-center text-text-secondary'>
- {t('education.form.terms.title')}
- </div>
- <div className='system-md-regular mb-1 text-text-tertiary'>
- {t('education.form.terms.desc.front')}
- <a href='https://dify.ai/terms' target='_blank' className='text-text-secondary hover:underline'>{t('education.form.terms.desc.termsOfService')}</a>
- {t('education.form.terms.desc.and')}
- <a href='https://dify.ai/privacy' target='_blank' className='text-text-secondary hover:underline'>{t('education.form.terms.desc.privacyPolicy')}</a>
- {t('education.form.terms.desc.end')}
- </div>
- <div className='system-md-regular py-2 text-text-primary'>
- <div className='mb-2 flex'>
- <Checkbox
- className='mr-2 shrink-0'
- checked={ageChecked}
- onCheck={() => setAgeChecked(!ageChecked)}
- />
- {t('education.form.terms.option.age')}
- </div>
- <div className='flex'>
- <Checkbox
- className='mr-2 shrink-0'
- checked={inSchoolChecked}
- onCheck={() => setInSchoolChecked(!inSchoolChecked)}
- />
- {t('education.form.terms.option.inSchool')}
- </div>
- </div>
- </div>
- <Button
- variant='primary'
- disabled={!ageChecked || !inSchoolChecked || !schoolName || !role || isPending}
- onClick={handleSubmit}
- >
- {t('education.submit')}
- </Button>
- <div className='mb-4 mt-5 h-[1px] bg-gradient-to-r from-[rgba(16,24,40,0.08)]'></div>
- <a
- className='system-xs-regular flex items-center text-text-accent'
- href={docLink}
- target='_blank'
- >
- {t('education.learn')}
- <RiExternalLinkLine className='ml-1 h-3 w-3' />
- </a>
- </div>
- </div>
- <Confirm
- isShow={!!modalShow}
- title={modalShow?.title || ''}
- content={modalShow?.desc}
- onConfirm={modalShow?.onConfirm || (() => {})}
- onCancel={modalShow?.onConfirm || (() => {})}
- />
- </div>
- )
- }
- export default EducationApplyAge
|