index.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. import { useEffect, useState } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import Link from 'next/link'
  4. import { ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline'
  5. import ProviderInput from '../provider-input'
  6. import type { ValidatedStatusState } from '../provider-input/useValidateToken'
  7. import useValidateToken, { ValidatedStatus } from '../provider-input/useValidateToken'
  8. import {
  9. ValidatedErrorIcon,
  10. ValidatedErrorOnOpenaiTip,
  11. ValidatedSuccessIcon,
  12. ValidatingTip,
  13. } from '../provider-input/Validate'
  14. import type { Provider, ProviderAnthropicToken } from '@/models/common'
  15. type AnthropicProviderProps = {
  16. provider: Provider
  17. onValidatedStatus: (status?: ValidatedStatusState) => void
  18. onTokenChange: (token: ProviderAnthropicToken) => void
  19. }
  20. const AnthropicProvider = ({
  21. provider,
  22. onValidatedStatus,
  23. onTokenChange,
  24. }: AnthropicProviderProps) => {
  25. const { t } = useTranslation()
  26. const [token, setToken] = useState<ProviderAnthropicToken>((provider.token as ProviderAnthropicToken) || { anthropic_api_key: '' })
  27. const [validating, validatedStatus, setValidatedStatus, validate] = useValidateToken(provider.provider_name)
  28. const handleFocus = () => {
  29. if (token.anthropic_api_key === (provider.token as ProviderAnthropicToken).anthropic_api_key) {
  30. setToken({ anthropic_api_key: '' })
  31. onTokenChange({ anthropic_api_key: '' })
  32. setValidatedStatus({})
  33. }
  34. }
  35. const handleChange = (v: string) => {
  36. const apiKey = { anthropic_api_key: v }
  37. setToken(apiKey)
  38. onTokenChange(apiKey)
  39. validate(apiKey, {
  40. beforeValidating: () => {
  41. if (!v) {
  42. setValidatedStatus({})
  43. return false
  44. }
  45. return true
  46. },
  47. })
  48. }
  49. useEffect(() => {
  50. if (typeof onValidatedStatus === 'function')
  51. onValidatedStatus(validatedStatus)
  52. }, [validatedStatus])
  53. const getValidatedIcon = () => {
  54. if (validatedStatus?.status === ValidatedStatus.Error || validatedStatus.status === ValidatedStatus.Exceed)
  55. return <ValidatedErrorIcon />
  56. if (validatedStatus.status === ValidatedStatus.Success)
  57. return <ValidatedSuccessIcon />
  58. }
  59. const getValidatedTip = () => {
  60. if (validating)
  61. return <ValidatingTip />
  62. if (validatedStatus?.status === ValidatedStatus.Error)
  63. return <ValidatedErrorOnOpenaiTip errorMessage={validatedStatus.message ?? ''} />
  64. }
  65. return (
  66. <div className='px-4 pt-3 pb-4'>
  67. <ProviderInput
  68. value={token.anthropic_api_key}
  69. name={t('common.provider.apiKey')}
  70. placeholder={t('common.provider.enterYourKey')}
  71. onChange={handleChange}
  72. onFocus={handleFocus}
  73. validatedIcon={getValidatedIcon()}
  74. validatedTip={getValidatedTip()}
  75. />
  76. <Link className="inline-flex items-center mt-3 text-xs font-normal cursor-pointer text-primary-600 w-fit" href="https://docs.anthropic.com/claude/reference/getting-started-with-the-api" target={'_blank'}>
  77. {t('common.provider.anthropic.keyFrom')}
  78. <ArrowTopRightOnSquareIcon className='w-3 h-3 ml-1 text-primary-600' aria-hidden="true" />
  79. </Link>
  80. </div>
  81. )
  82. }
  83. export default AnthropicProvider