| 'use client' | 'use client' | ||||
| import React, { useEffect, useState } from 'react' | |||||
| import React, { useEffect, useRef, useState } from 'react' | |||||
| import copy from 'copy-to-clipboard' | import copy from 'copy-to-clipboard' | ||||
| import { t } from 'i18next' | import { t } from 'i18next' | ||||
| import s from './style.module.css' | import s from './style.module.css' | ||||
| import { randomString } from '@/app/components/app-sidebar/basic' | |||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| type IInputCopyProps = { | type IInputCopyProps = { | ||||
| } | } | ||||
| const InputCopy = ({ | const InputCopy = ({ | ||||
| value, | |||||
| value = '', | |||||
| className, | className, | ||||
| readOnly = true, | readOnly = true, | ||||
| children, | children, | ||||
| }: IInputCopyProps) => { | }: IInputCopyProps) => { | ||||
| const [isCopied, setIsCopied] = useState(false) | const [isCopied, setIsCopied] = useState(false) | ||||
| const selector = useRef(`input-tooltip-${randomString(4)}`) | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (isCopied) { | if (isCopied) { | ||||
| const timeout = setTimeout(() => { | const timeout = setTimeout(() => { | ||||
| {children} | {children} | ||||
| <div className='flex-grow bg-gray-50 text-[13px] relative h-full'> | <div className='flex-grow bg-gray-50 text-[13px] relative h-full'> | ||||
| <Tooltip | <Tooltip | ||||
| selector="top-uniq" | |||||
| selector={selector.current} | |||||
| content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} | content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} | ||||
| className='z-10' | className='z-10' | ||||
| > | > | ||||
| </div> | </div> | ||||
| <div className="flex-shrink-0 h-4 bg-gray-200 border" /> | <div className="flex-shrink-0 h-4 bg-gray-200 border" /> | ||||
| <Tooltip | <Tooltip | ||||
| selector="top-uniq" | |||||
| selector={selector.current} | |||||
| content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} | content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} | ||||
| className='z-10' | className='z-10' | ||||
| > | > |
| isShow = false, | isShow = false, | ||||
| onClose, | onClose, | ||||
| newKey, | newKey, | ||||
| className | |||||
| className, | |||||
| }: ISecretKeyGenerateModalProps) => { | }: ISecretKeyGenerateModalProps) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| return ( | return ( |
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { PlusIcon, XMarkIcon } from '@heroicons/react/20/solid' | import { PlusIcon, XMarkIcon } from '@heroicons/react/20/solid' | ||||
| import useSWR, { useSWRConfig } from 'swr' | import useSWR, { useSWRConfig } from 'swr' | ||||
| import { useContext } from 'use-context-selector' | |||||
| import SecretKeyGenerateModal from './secret-key-generate' | import SecretKeyGenerateModal from './secret-key-generate' | ||||
| import s from './style.module.css' | import s from './style.module.css' | ||||
| import Modal from '@/app/components/base/modal' | import Modal from '@/app/components/base/modal' | ||||
| import Loading from '@/app/components/base/loading' | import Loading from '@/app/components/base/loading' | ||||
| import Confirm from '@/app/components/base/confirm' | import Confirm from '@/app/components/base/confirm' | ||||
| import useCopyToClipboard from '@/hooks/use-copy-to-clipboard' | import useCopyToClipboard from '@/hooks/use-copy-to-clipboard' | ||||
| import { useContext } from 'use-context-selector' | |||||
| import I18n from '@/context/i18n' | import I18n from '@/context/i18n' | ||||
| type ISecretKeyModalProps = { | type ISecretKeyModalProps = { | ||||
| } | } | ||||
| }, [copyValue]) | }, [copyValue]) | ||||
| const onDel = async () => { | const onDel = async () => { | ||||
| setShowConfirmDelete(false) | setShowConfirmDelete(false) | ||||
| if (!delKeyID) { | |||||
| if (!delKeyID) | |||||
| return | return | ||||
| } | |||||
| await delApikey({ url: `/apps/${appId}/api-keys/${delKeyID}`, params: {} }) | await delApikey({ url: `/apps/${appId}/api-keys/${delKeyID}`, params: {} }) | ||||
| mutate(commonParams) | mutate(commonParams) | ||||
| } | } | ||||
| } | } | ||||
| const formatDate = (timestamp: any) => { | const formatDate = (timestamp: any) => { | ||||
| if (locale === 'en') { | |||||
| if (locale === 'en') | |||||
| return new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric' }).format((+timestamp) * 1000) | return new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', day: 'numeric' }).format((+timestamp) * 1000) | ||||
| } else { | |||||
| else | |||||
| return new Intl.DateTimeFormat('fr-CA', { year: 'numeric', month: '2-digit', day: '2-digit' }).format((+timestamp) * 1000) | return new Intl.DateTimeFormat('fr-CA', { year: 'numeric', month: '2-digit', day: '2-digit' }).format((+timestamp) * 1000) | ||||
| } | |||||
| } | } | ||||
| return ( | return ( | ||||
| <div className='flex-shrink-0 px-3 truncate w-28'>{api.last_used_at ? formatDate(api.last_used_at) : t('appApi.never')}</div> | <div className='flex-shrink-0 px-3 truncate w-28'>{api.last_used_at ? formatDate(api.last_used_at) : t('appApi.never')}</div> | ||||
| <div className='flex flex-grow px-3'> | <div className='flex flex-grow px-3'> | ||||
| <Tooltip | <Tooltip | ||||
| selector="top-uniq" | |||||
| selector={`key-${api.token}`} | |||||
| content={copyValue === api.token ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} | content={copyValue === api.token ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} | ||||
| className='z-10' | className='z-10' | ||||
| > | > |
| 'use client' | 'use client' | ||||
| import React, { useCallback, useEffect, useState } from 'react' | |||||
| import React, { useCallback, useEffect, useRef, useState } from 'react' | |||||
| import { t } from 'i18next' | import { t } from 'i18next' | ||||
| import s from './index.module.css' | import s from './index.module.css' | ||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import useCopyToClipboard from '@/hooks/use-copy-to-clipboard' | import useCopyToClipboard from '@/hooks/use-copy-to-clipboard' | ||||
| import { randomString } from '@/app/components/app-sidebar/basic' | |||||
| type IInvitationLinkProps = { | type IInvitationLinkProps = { | ||||
| value?: string | value?: string | ||||
| value = '', | value = '', | ||||
| }: IInvitationLinkProps) => { | }: IInvitationLinkProps) => { | ||||
| const [isCopied, setIsCopied] = useState(false) | const [isCopied, setIsCopied] = useState(false) | ||||
| const selector = useRef(`invite-link-${randomString(4)}`) | |||||
| const [_, copy] = useCopyToClipboard() | const [_, copy] = useCopyToClipboard() | ||||
| const copyHandle = useCallback(() => { | const copyHandle = useCallback(() => { | ||||
| <div className="flex items-center flex-grow h-5"> | <div className="flex items-center flex-grow h-5"> | ||||
| <div className='flex-grow bg-gray-100 text-[13px] relative h-full'> | <div className='flex-grow bg-gray-100 text-[13px] relative h-full'> | ||||
| <Tooltip | <Tooltip | ||||
| selector="top-uniq" | |||||
| selector={selector.current} | |||||
| content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} | content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} | ||||
| className='z-10' | className='z-10' | ||||
| > | > | ||||
| </div> | </div> | ||||
| <div className="flex-shrink-0 h-4 bg-gray-200 border" /> | <div className="flex-shrink-0 h-4 bg-gray-200 border" /> | ||||
| <Tooltip | <Tooltip | ||||
| selector="top-uniq" | |||||
| selector={selector.current} | |||||
| content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} | content={isCopied ? `${t('appApi.copied')}` : `${t('appApi.copy')}`} | ||||
| className='z-10' | className='z-10' | ||||
| > | > |