diff --git a/apps/frontend/src/components/settings/github.component.tsx b/apps/frontend/src/components/settings/github.component.tsx index 4d039247..adbd56fc 100644 --- a/apps/frontend/src/components/settings/github.component.tsx +++ b/apps/frontend/src/components/settings/github.component.tsx @@ -4,6 +4,8 @@ import { Button } from '@gitroom/react/form/button'; import { FC, useCallback, useEffect, useState } from 'react'; import { useFetch } from '@gitroom/helpers/utils/custom.fetch'; import { deleteDialog } from '@gitroom/react/helpers/delete.dialog'; +import { Input } from '@gitroom/react/form/input'; +import { useToaster } from '@gitroom/react/toaster/toaster'; const ConnectedComponent: FC<{ id: string; @@ -93,9 +95,9 @@ const ConnectComponent: FC<{ deleteRepository: () => void; }> = (props) => { const { id, setConnected, deleteRepository } = props; - const [repo, setRepo] = useState(); - const [select, setSelect] = useState(); + const [url, setUrl] = useState(''); const fetch = useFetch(); + const toast = useToaster(); const cancelConnection = useCallback(async () => { await ( @@ -108,42 +110,56 @@ const ConnectComponent: FC<{ }, []); const completeConnection = useCallback(async () => { + const [select, repo] = url + .match(/https:\/\/github\.com\/([A-Za-z0-9_.-]+)\/([A-Za-z0-9_.-]+)/)! + .slice(1); + + const response = await fetch(`/settings/organizations/${id}`, { + method: 'POST', + body: JSON.stringify({ login: `${select}/${repo}` }), + }); + + if (response.status === 404) { + toast.show('Repository not found', 'warning'); + return ; + } + setConnected(`${select}/${repo}`); - await ( - await fetch(`/settings/organizations/${id}`, { - method: 'POST', - body: JSON.stringify({ login: `${select}/${repo}` }), - }) - ).json(); - }, [repo, select]); + }, [url]); return ( -
-
+
+
GitHub
Connect your repository
- setUrl(e.target.value)} + name="github" + label="" + placeholder="Full GitHub URL" + /> + } + Connect +
); diff --git a/libraries/nestjs-libraries/src/database/prisma/stars/stars.service.ts b/libraries/nestjs-libraries/src/database/prisma/stars/stars.service.ts index a709fca9..a315d349 100644 --- a/libraries/nestjs-libraries/src/database/prisma/stars/stars.service.ts +++ b/libraries/nestjs-libraries/src/database/prisma/stars/stars.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { HttpException, Injectable } from '@nestjs/common'; import { StarsRepository } from '@gitroom/nestjs-libraries/database/prisma/stars/stars.repository'; import { chunk, groupBy } from 'lodash'; import dayjs from 'dayjs'; @@ -431,6 +431,11 @@ export class StarsService { } async updateGitHubLogin(orgId: string, id: string, login: string) { + const check = await fetch(`https://github.com/${login}`); + if (check.status === 404) { + throw new HttpException('GitHub repository not found', 404); + } + this._workerServiceProducer .emit('sync_all_stars', { payload: { login } }) .subscribe(); diff --git a/libraries/react-shared-libraries/src/form/input.tsx b/libraries/react-shared-libraries/src/form/input.tsx index 1251b12b..3450bc2e 100644 --- a/libraries/react-shared-libraries/src/form/input.tsx +++ b/libraries/react-shared-libraries/src/form/input.tsx @@ -1,23 +1,38 @@ -"use client"; +'use client'; -import {DetailedHTMLProps, FC, InputHTMLAttributes, useMemo} from "react"; -import {clsx} from "clsx"; -import {useFormContext} from "react-hook-form"; +import { DetailedHTMLProps, FC, InputHTMLAttributes, useMemo } from 'react'; +import { clsx } from 'clsx'; +import { useFormContext } from 'react-hook-form'; -export const Input: FC, HTMLInputElement> & {error?: any, disableForm?: boolean, label: string, name: string}> = (props) => { - const {label, className, disableForm, error, ...rest} = props; - const form = useFormContext(); - const err = useMemo(() => { - if (error) return error; - if (!form || !form.formState.errors[props?.name!]) return; - return form?.formState?.errors?.[props?.name!]?.message! as string; - }, [form?.formState?.errors?.[props?.name!]?.message, error]); +export const Input: FC< + DetailedHTMLProps, HTMLInputElement> & { + removeError?: boolean; + error?: any; + disableForm?: boolean; + label: string; + name: string; + } +> = (props) => { + const { label, removeError, className, disableForm, error, ...rest } = props; + const form = useFormContext(); + const err = useMemo(() => { + if (error) return error; + if (!form || !form.formState.errors[props?.name!]) return; + return form?.formState?.errors?.[props?.name!]?.message! as string; + }, [form?.formState?.errors?.[props?.name!]?.message, error]); - return ( -
-
{label}
- -
{err || <> }
-
- ) -} \ No newline at end of file + return ( +
+
{label}
+ + {!removeError &&
{err || <> }
} +
+ ); +};