'use client'; import { useModals } from '@mantine/modals'; import React, { FC, useCallback, useMemo } from 'react'; import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; import { Input } from '@gitroom/react/form/input'; import { FieldValues, FormProvider, useForm } from 'react-hook-form'; import { Button } from '@gitroom/react/form/button'; import { classValidatorResolver } from '@hookform/resolvers/class-validator'; import { ApiKeyDto } from '@gitroom/nestjs-libraries/dtos/integrations/api.key.dto'; import { useRouter } from 'next/navigation'; import { TopTitle } from '@gitroom/frontend/components/launches/helpers/top.title.component'; import { useVariables } from '@gitroom/react/helpers/variable.context'; import { useToaster } from '@gitroom/react/toaster/toaster'; import { object, string } from 'yup'; import { yupResolver } from '@hookform/resolvers/yup'; const resolver = classValidatorResolver(ApiKeyDto); export const useAddProvider = (update?: () => void) => { const modal = useModals(); const fetch = useFetch(); return useCallback(async () => { const data = await (await fetch('/integrations')).json(); modal.openModal({ title: '', withCloseButton: false, classNames: { modal: 'bg-transparent text-textColor', }, children: , size: 'auto', }); }, []); }; export const AddProviderButton: FC<{ update?: () => void }> = (props) => { const { update } = props; const add = useAddProvider(update); return ( ); }; export const ApiModal: FC<{ identifier: string; name: string; update?: () => void; close?: () => void; }> = (props) => { const { update, name, close: closePopup } = props; const fetch = useFetch(); const router = useRouter(); const modal = useModals(); const methods = useForm({ mode: 'onChange', resolver, }); const close = useCallback(() => { if (closePopup) { return closePopup(); } modal.closeAll(); }, []); const submit = useCallback(async (data: FieldValues) => { const add = await fetch( `/integrations/article/${props.identifier}/connect`, { method: 'POST', body: JSON.stringify({ api: data.api }), } ); if (add.ok) { if (closePopup) { closePopup(); } else { modal.closeAll(); } router.refresh(); if (update) update(); return; } methods.setError('api', { message: 'Invalid API key', }); }, []); return (
); }; export const UrlModal: FC<{ gotoUrl(url: string): void; }> = (props) => { const { gotoUrl } = props; const methods = useForm({ mode: 'onChange', }); const submit = useCallback(async (data: FieldValues) => { gotoUrl(data.url); }, []); return (
); }; export const CustomVariables: FC<{ variables: Array<{ key: string; label: string; defaultValue?: string; validation: string; type: 'text' | 'password'; }>; close?: () => void; identifier: string; gotoUrl(url: string): void; }> = (props) => { const { close, gotoUrl, identifier, variables } = props; const modals = useModals(); const schema = useMemo(() => { return object({ ...variables.reduce((aIcc, item) => { const splitter = item.validation.split('/'); const regex = new RegExp( splitter.slice(1, -1).join('/'), splitter.pop() ); return { ...aIcc, [item.key]: string() .matches(regex, `${item.label} is invalid`) .required(), }; }, {}), }); }, [variables]); const methods = useForm({ mode: 'onChange', resolver: yupResolver(schema), values: variables.reduce( (acc, item) => ({ ...acc, ...(item.defaultValue ? { [item.key]: item.defaultValue } : {}), }), {} ), }); const submit = useCallback( async (data: FieldValues) => { gotoUrl( `/integrations/social/${identifier}?state=nostate&code=${Buffer.from( JSON.stringify(data) ).toString('base64')}` ); }, [variables] ); return (
{variables.map((variable) => (
))}
); }; export const AddProviderComponent: FC<{ social: Array<{ identifier: string; name: string; isExternal: boolean; customFields?: Array<{ key: string; label: string; validation: string; type: 'text' | 'password'; }>; }>; article: Array<{ identifier: string; name: string }>; update?: () => void; }> = (props) => { const { update, social, article } = props; const { isGeneral } = useVariables(); const toaster = useToaster(); const router = useRouter(); const fetch = useFetch(); const modal = useModals(); const getSocialLink = useCallback( ( identifier: string, isExternal: boolean, customFields?: Array<{ key: string; label: string; validation: string; defaultValue?: string; type: 'text' | 'password'; }> ) => async () => { const gotoIntegration = async (externalUrl?: string) => { const { url, err } = await ( await fetch( `/integrations/social/${identifier}${ externalUrl ? `?externalUrl=${externalUrl}` : `` }` ) ).json(); if (err) { toaster.show('Could not connect to the platform', 'warning'); return; } window.location.href = url; }; if (isExternal) { modal.closeAll(); modal.openModal({ title: '', withCloseButton: false, classNames: { modal: 'bg-transparent text-textColor', }, children: , }); return; } if (customFields) { modal.closeAll(); modal.openModal({ title: '', withCloseButton: false, classNames: { modal: 'bg-transparent text-textColor', }, children: ( router.push(url)} variables={customFields} /> ), }); return; } await gotoIntegration(); }, [] ); const close = useCallback(() => { modal.closeAll(); }, []); const showApiButton = useCallback( (identifier: string, name: string) => async () => { modal.openModal({ title: '', withCloseButton: false, classNames: { modal: 'bg-transparent text-textColor', }, children: ( ), }); }, [] ); return (

Social

{social.map((item) => (
{item.identifier === 'youtube' ? ( ) : ( )}
{item.name}
))}
{!isGeneral && (

Articles

{article.map((item) => (
{item.name}
))}
)}
); };