diff --git a/.github/workflows/vitest.yml b/.github/workflows/backend_vitest.yml
similarity index 94%
rename from .github/workflows/vitest.yml
rename to .github/workflows/backend_vitest.yml
index c18dc6a0..ad80ab7b 100644
--- a/.github/workflows/vitest.yml
+++ b/.github/workflows/backend_vitest.yml
@@ -1,4 +1,4 @@
-name: Vitest
+name: Backend Vitest
on:
push:
diff --git a/.github/workflows/frontend_vitest.yml b/.github/workflows/frontend_vitest.yml
new file mode 100644
index 00000000..cfac4547
--- /dev/null
+++ b/.github/workflows/frontend_vitest.yml
@@ -0,0 +1,24 @@
+name: Frontend Vitest
+
+on:
+ push:
+ workflow_dispatch:
+
+jobs:
+ vitest:
+ runs-on: ubuntu-latest
+ defaults:
+ run:
+ working-directory: frontend
+ steps:
+ - name: Checkout latest repo
+ uses: actions/checkout@v4
+
+ - name: Setup pnpm
+ uses: pnpm/action-setup@v2
+ with:
+ version: 9
+ run_install: true
+
+ - name: Run Vitest
+ run: pnpm run test
diff --git a/frontend/app/components/book-detail/BookDetailBorrower.tsx b/frontend/app/components/book-detail/BookDetailBorrower.tsx
index fb67e561..f2646700 100644
--- a/frontend/app/components/book-detail/BookDetailBorrower.tsx
+++ b/frontend/app/components/book-detail/BookDetailBorrower.tsx
@@ -1,39 +1,49 @@
-import { Badge, Blockquote, Group, Loader, rem, Stack, Text } from '@mantine/core'
-import { useGetLoans } from 'orval/client'
+import {
+ Badge,
+ Blockquote,
+ Group,
+ Loader,
+ rem,
+ Stack,
+ Text,
+} from "@mantine/core";
+import { useGetLoans } from "client/client";
import { MdError } from "react-icons/md";
const BookDetailBorrower = () => {
- const loans = useGetLoans()
+ const loans = useGetLoans();
if (loans.isError) {
return (
} mt="xl">
データの取得に失敗しました
- )
+ );
}
return (
-
+
借りている人
- {loans.isPending ? :
+ {loans.isPending ? (
+
+ ) : (
- {loans.data.data.loans.map((loan) => loan.users &&
-
- {loan.users.name}
-
+ {loans.data.data.loans.map(
+ (loan) =>
+ loan.users && (
+
+ {loan.users.name}
+
+ )
)}
- }
+ )}
- )
-}
+ );
+};
-export default BookDetailBorrower
\ No newline at end of file
+export default BookDetailBorrower;
diff --git a/frontend/app/components/book-detail/BookDetailComponent.tsx b/frontend/app/components/book-detail/BookDetailComponent.tsx
index 5846b357..920c2b61 100644
--- a/frontend/app/components/book-detail/BookDetailComponent.tsx
+++ b/frontend/app/components/book-detail/BookDetailComponent.tsx
@@ -1,40 +1,39 @@
-import { Stack, Grid, rem } from '@mantine/core'
-import ErrorComponent from '~/components/common/ErrorComponent'
+import { Grid, rem, Stack } from "@mantine/core";
+import ErrorComponent from "~/components/common/ErrorComponent";
-import BookDetailContent from './BookDetailContent'
-import { getBookResponse } from 'orval/client'
-import BookDetailControlPanel from './BookDetailControlPanel'
+import { getBookResponse } from "client/client";
+import BookDetailContent from "./BookDetailContent";
+import BookDetailControlPanel from "./BookDetailControlPanel";
interface BookDetailComponentProps {
- bookResponse: getBookResponse
+ bookResponse: getBookResponse;
}
const BookDetailComponent = ({ bookResponse }: BookDetailComponentProps) => {
switch (bookResponse.status) {
case 400:
- return
+ return ;
case 404:
- return
+ return ;
case 500:
- return
+ return ;
}
return (
-
+
-
+
- )
-}
+ );
+};
-export default BookDetailComponent
\ No newline at end of file
+export default BookDetailComponent;
diff --git a/frontend/app/components/book-detail/BookDetailContent.tsx b/frontend/app/components/book-detail/BookDetailContent.tsx
index d1dab3d0..ed0237ab 100644
--- a/frontend/app/components/book-detail/BookDetailContent.tsx
+++ b/frontend/app/components/book-detail/BookDetailContent.tsx
@@ -1,31 +1,31 @@
-import { Stack } from '@mantine/core'
-import { Book } from 'orval/client.schemas'
-import BookDetailTitle from './BookDetailTitle'
-import BookDetailContentTable from './BookDetailContentTable'
-import BookDetailDescription from './BookDetailDescription'
-import { useAtom } from 'jotai'
-import { userAtom } from '~/stores/userAtom'
-import BookDetailBorrower from './BookDetailBorrower'
+import { Stack } from "@mantine/core";
+import { Book } from "client/client.schemas";
+import { useAtom } from "jotai";
+import { userAtom } from "~/stores/userAtom";
+import BookDetailBorrower from "./BookDetailBorrower";
+import BookDetailContentTable from "./BookDetailContentTable";
+import BookDetailDescription from "./BookDetailDescription";
+import BookDetailTitle from "./BookDetailTitle";
interface BookDetailComponentProps {
- book: Book
+ book: Book;
}
const BookDetailContent = ({ book }: BookDetailComponentProps) => {
- const [user] = useAtom(userAtom)
+ const [user] = useAtom(userAtom);
return (
{!!user && }
- )
-}
+ );
+};
-export default BookDetailContent
\ No newline at end of file
+export default BookDetailContent;
diff --git a/frontend/app/components/book-detail/BookDetailContentTable.tsx b/frontend/app/components/book-detail/BookDetailContentTable.tsx
index d660fccd..0fc95725 100644
--- a/frontend/app/components/book-detail/BookDetailContentTable.tsx
+++ b/frontend/app/components/book-detail/BookDetailContentTable.tsx
@@ -1,23 +1,25 @@
-import { Group, rem, Stack, Table, Text } from '@mantine/core'
-import { Book } from 'orval/client.schemas'
-import BookDetailAuthorBadge from './BookDetailAuthorBadge'
+import { Group, rem, Stack, Table, Text } from "@mantine/core";
+import { Book } from "client/client.schemas";
+import BookDetailAuthorBadge from "./BookDetailAuthorBadge";
interface BookDetailContentTableProps {
- book: Book
+ book: Book;
}
const BookDetailContentTable = ({ book }: BookDetailContentTableProps) => {
return (
-
+
書籍情報
- 著者
- {book.authors.map((author, id) => )}
+ 著者
+
+
+ {book.authors.map((author, id) => (
+
+ ))}
+
+
出版社
@@ -37,7 +39,7 @@ const BookDetailContentTable = ({ book }: BookDetailContentTableProps) => {
- )
-}
+ );
+};
-export default BookDetailContentTable
\ No newline at end of file
+export default BookDetailContentTable;
diff --git a/frontend/app/components/book-search/BookSearchAuthorForm.tsx b/frontend/app/components/book-search/BookSearchAuthorForm.tsx
index 1fc4d476..82075344 100644
--- a/frontend/app/components/book-search/BookSearchAuthorForm.tsx
+++ b/frontend/app/components/book-search/BookSearchAuthorForm.tsx
@@ -1,9 +1,12 @@
-import { TextInput } from '@mantine/core'
-import type { UseFormReturnType } from '@mantine/form'
-import type { GetBooksParams } from 'orval/client.schemas'
+import { TextInput } from "@mantine/core";
+import type { UseFormReturnType } from "@mantine/form";
+import type { GetBooksParams } from "client/client.schemas";
interface BookSearchAuthorFormProps {
- form: UseFormReturnType GetBooksParams>
+ form: UseFormReturnType<
+ GetBooksParams,
+ (values: GetBooksParams) => GetBooksParams
+ >;
}
const BookSearchAuthorForm = ({ form }: BookSearchAuthorFormProps) => {
@@ -11,10 +14,10 @@ const BookSearchAuthorForm = ({ form }: BookSearchAuthorFormProps) => {
- )
-}
+ );
+};
-export default BookSearchAuthorForm
\ No newline at end of file
+export default BookSearchAuthorForm;
diff --git a/frontend/app/components/book-search/BookSearchComponent.tsx b/frontend/app/components/book-search/BookSearchComponent.tsx
index 2b3058c2..e2235712 100644
--- a/frontend/app/components/book-search/BookSearchComponent.tsx
+++ b/frontend/app/components/book-search/BookSearchComponent.tsx
@@ -1,14 +1,17 @@
-import BookSearchModeButton from './BookSearchModeButton'
-import type { UseFormReturnType } from '@mantine/form'
-import type { GetBooksParams } from 'orval/client.schemas'
-import BookSearchForm from './BookSearchForm'
+import type { UseFormReturnType } from "@mantine/form";
+import type { GetBooksParams } from "client/client.schemas";
+import BookSearchForm from "./BookSearchForm";
+import BookSearchModeButton from "./BookSearchModeButton";
interface BookSearchComponentProps {
- isOpen: boolean
- open: () => void
- close: () => void
- form: UseFormReturnType GetBooksParams>
- handleSubmit: (props: GetBooksParams) => void
+ isOpen: boolean;
+ open: () => void;
+ close: () => void;
+ form: UseFormReturnType<
+ GetBooksParams,
+ (values: GetBooksParams) => GetBooksParams
+ >;
+ handleSubmit: (props: GetBooksParams) => void;
}
const BookSearchComponent = ({
@@ -16,14 +19,14 @@ const BookSearchComponent = ({
open,
close,
form,
- handleSubmit
+ handleSubmit,
}: BookSearchComponentProps) => {
return (
<>
>
- )
-}
+ );
+};
-export default BookSearchComponent
\ No newline at end of file
+export default BookSearchComponent;
diff --git a/frontend/app/components/book-search/BookSearchForm.tsx b/frontend/app/components/book-search/BookSearchForm.tsx
index 121608bf..44dc3a91 100644
--- a/frontend/app/components/book-search/BookSearchForm.tsx
+++ b/frontend/app/components/book-search/BookSearchForm.tsx
@@ -1,30 +1,26 @@
-import { Collapse } from '@mantine/core'
-import FormLayout from '../layouts/FormLayout'
-import type { UseFormReturnType } from '@mantine/form'
-import type { GetBooksParams } from 'orval/client.schemas'
-import BookSearchTitleForm from './BookSearchTitleForm'
-import BookSearchAuthorForm from './BookSearchAuthorForm'
-import BookSearchPublisherForm from './BookSearchPublisherForm'
-import BookSearchIsbnForm from './BookSearchIsbnForm'
-import BookSearchSubmitButton from './BookSearchSubmitButton'
+import { Collapse } from "@mantine/core";
+import type { UseFormReturnType } from "@mantine/form";
+import type { GetBooksParams } from "client/client.schemas";
+import FormLayout from "../layouts/FormLayout";
+import BookSearchAuthorForm from "./BookSearchAuthorForm";
+import BookSearchIsbnForm from "./BookSearchIsbnForm";
+import BookSearchPublisherForm from "./BookSearchPublisherForm";
+import BookSearchSubmitButton from "./BookSearchSubmitButton";
+import BookSearchTitleForm from "./BookSearchTitleForm";
interface SearchFormProps {
- isOpen: boolean
- form: UseFormReturnType GetBooksParams>
- handleSubmit: (props: GetBooksParams) => void
+ isOpen: boolean;
+ form: UseFormReturnType<
+ GetBooksParams,
+ (values: GetBooksParams) => GetBooksParams
+ >;
+ handleSubmit: (props: GetBooksParams) => void;
}
-const BookSearchForm = ({
- isOpen,
- form,
- handleSubmit
-}: SearchFormProps) => {
+const BookSearchForm = ({ isOpen, form, handleSubmit }: SearchFormProps) => {
return (
-
- form={form}
- handleSubmit={handleSubmit}
- >
+ form={form} handleSubmit={handleSubmit}>
@@ -32,7 +28,7 @@ const BookSearchForm = ({
- )
-}
+ );
+};
-export default BookSearchForm
\ No newline at end of file
+export default BookSearchForm;
diff --git a/frontend/app/components/book-search/BookSearchIsbnForm.tsx b/frontend/app/components/book-search/BookSearchIsbnForm.tsx
index 507acc34..528dbf1d 100644
--- a/frontend/app/components/book-search/BookSearchIsbnForm.tsx
+++ b/frontend/app/components/book-search/BookSearchIsbnForm.tsx
@@ -1,9 +1,12 @@
-import { TextInput } from '@mantine/core'
-import type { UseFormReturnType } from '@mantine/form'
-import type { GetBooksParams } from 'orval/client.schemas'
+import { TextInput } from "@mantine/core";
+import type { UseFormReturnType } from "@mantine/form";
+import type { GetBooksParams } from "client/client.schemas";
interface SearchIsbnFormProps {
- form: UseFormReturnType GetBooksParams>
+ form: UseFormReturnType<
+ GetBooksParams,
+ (values: GetBooksParams) => GetBooksParams
+ >;
}
const BookSearchIsbnForm = ({ form }: SearchIsbnFormProps) => {
@@ -11,10 +14,10 @@ const BookSearchIsbnForm = ({ form }: SearchIsbnFormProps) => {
- )
-}
+ );
+};
-export default BookSearchIsbnForm
\ No newline at end of file
+export default BookSearchIsbnForm;
diff --git a/frontend/app/components/book-search/BookSearchPublisherForm.tsx b/frontend/app/components/book-search/BookSearchPublisherForm.tsx
index 0bcd148e..7f941111 100644
--- a/frontend/app/components/book-search/BookSearchPublisherForm.tsx
+++ b/frontend/app/components/book-search/BookSearchPublisherForm.tsx
@@ -1,9 +1,12 @@
-import { TextInput } from '@mantine/core'
-import type { UseFormReturnType } from '@mantine/form'
-import type { GetBooksParams } from 'orval/client.schemas'
+import { TextInput } from "@mantine/core";
+import type { UseFormReturnType } from "@mantine/form";
+import type { GetBooksParams } from "client/client.schemas";
interface SearchPublisherFormProps {
- form: UseFormReturnType GetBooksParams>
+ form: UseFormReturnType<
+ GetBooksParams,
+ (values: GetBooksParams) => GetBooksParams
+ >;
}
const BookSearchPublisherForm = ({ form }: SearchPublisherFormProps) => {
@@ -11,10 +14,10 @@ const BookSearchPublisherForm = ({ form }: SearchPublisherFormProps) => {
- )
-}
+ );
+};
-export default BookSearchPublisherForm
\ No newline at end of file
+export default BookSearchPublisherForm;
diff --git a/frontend/app/components/book-search/BookSearchTitleForm.tsx b/frontend/app/components/book-search/BookSearchTitleForm.tsx
index f4c368a5..d66fcd3f 100644
--- a/frontend/app/components/book-search/BookSearchTitleForm.tsx
+++ b/frontend/app/components/book-search/BookSearchTitleForm.tsx
@@ -1,9 +1,12 @@
-import { TextInput } from '@mantine/core'
-import type { UseFormReturnType } from '@mantine/form'
-import type { GetBooksParams } from 'orval/client.schemas'
+import { TextInput } from "@mantine/core";
+import type { UseFormReturnType } from "@mantine/form";
+import type { GetBooksParams } from "client/client.schemas";
interface SearchTitleFormProps {
- form: UseFormReturnType GetBooksParams>
+ form: UseFormReturnType<
+ GetBooksParams,
+ (values: GetBooksParams) => GetBooksParams
+ >;
}
const BookSearchTitleForm = ({ form }: SearchTitleFormProps) => {
@@ -11,10 +14,10 @@ const BookSearchTitleForm = ({ form }: SearchTitleFormProps) => {
- )
-}
+ );
+};
-export default BookSearchTitleForm
\ No newline at end of file
+export default BookSearchTitleForm;
diff --git a/frontend/app/components/books/BookCard.tsx b/frontend/app/components/books/BookCard.tsx
index e0dec570..f5328a2b 100644
--- a/frontend/app/components/books/BookCard.tsx
+++ b/frontend/app/components/books/BookCard.tsx
@@ -1,6 +1,6 @@
import { Card } from "@mantine/core";
+import type { Book } from "client/client.schemas";
import { useAtom } from "jotai";
-import type { Book } from "orval/client.schemas";
import { userAtom } from "~/stores/userAtom";
import BookCardFooter from "./BookCardFooter";
import BookCardHeader from "./BookCardHeader";
diff --git a/frontend/app/components/books/BookCards.tsx b/frontend/app/components/books/BookCards.tsx
index 3c0b0677..d0e84a48 100644
--- a/frontend/app/components/books/BookCards.tsx
+++ b/frontend/app/components/books/BookCards.tsx
@@ -1,6 +1,6 @@
import { ScrollArea, SimpleGrid } from "@mantine/core";
+import { Book } from "client/client.schemas";
import { useAtom } from "jotai";
-import { Book } from "orval/client.schemas";
import { userAtom } from "~/stores/userAtom";
import BookCard from "./BookCard";
import BookSelectedDialog from "./BookSelectedDialog";
diff --git a/frontend/app/components/books/BookListComponent.tsx b/frontend/app/components/books/BookListComponent.tsx
index d7f5b1a1..37f4e861 100644
--- a/frontend/app/components/books/BookListComponent.tsx
+++ b/frontend/app/components/books/BookListComponent.tsx
@@ -1,25 +1,28 @@
-import { Stack } from '@mantine/core'
-import { getBooksResponse } from 'orval/client'
-import ErrorComponent from '../common/ErrorComponent'
-import BookCards from './BookCards'
-import type { UseFormReturnType } from '@mantine/form'
-import type { GetBooksParams } from 'orval/client.schemas'
-import BookSearchComponent from '../book-search/BookSearchComponent'
-import ContentsHeader from '../common/ContentsHeader'
-import PaginationComponent from '../common/PaginationComponent'
+import { Stack } from "@mantine/core";
+import type { UseFormReturnType } from "@mantine/form";
+import { getBooksResponse } from "client/client";
+import type { GetBooksParams } from "client/client.schemas";
+import BookSearchComponent from "../book-search/BookSearchComponent";
+import ContentsHeader from "../common/ContentsHeader";
+import ErrorComponent from "../common/ErrorComponent";
+import PaginationComponent from "../common/PaginationComponent";
+import BookCards from "./BookCards";
interface BookListComponentProps {
- booksResponse: getBooksResponse
- form: UseFormReturnType GetBooksParams>
- handleSubmit: (props: GetBooksParams) => void
- isOpen: boolean
- open: () => void
- close: () => void
- handlePaginationChange: (newPage: number) => void
- handleLimitChange: (newLimit: number) => void
- page?: number
- limit?: number
- totalBook: number
+ booksResponse: getBooksResponse;
+ form: UseFormReturnType<
+ GetBooksParams,
+ (values: GetBooksParams) => GetBooksParams
+ >;
+ handleSubmit: (props: GetBooksParams) => void;
+ isOpen: boolean;
+ open: () => void;
+ close: () => void;
+ handlePaginationChange: (newPage: number) => void;
+ handleLimitChange: (newLimit: number) => void;
+ page?: number;
+ limit?: number;
+ totalBook: number;
}
const BookListComponent = ({
@@ -33,20 +36,36 @@ const BookListComponent = ({
handleLimitChange,
page,
limit,
- totalBook
+ totalBook,
}: BookListComponentProps) => {
return (
-
-
-
- {booksResponse.status !== 200 ? : }
-
+
+
+
+ {booksResponse.status !== 200 ? (
+
+ ) : (
+
+ )}
+
- )
-}
+ );
+};
-export default BookListComponent
\ No newline at end of file
+export default BookListComponent;
diff --git a/frontend/app/components/header/HeaderComponent.tsx b/frontend/app/components/header/HeaderComponent.tsx
index f1d1e90b..593679ef 100644
--- a/frontend/app/components/header/HeaderComponent.tsx
+++ b/frontend/app/components/header/HeaderComponent.tsx
@@ -1,47 +1,40 @@
-import { AppShell, Group } from '@mantine/core'
-import HeaderTitleLogo from './HeaderTitleLogo'
-import HeaderMainComponent from './HeaderMainComponent'
-import { useAtom } from "jotai"
-import { getUser } from "orval/client"
-import { User } from "orval/client.schemas"
-import { userAtom } from "~/stores/userAtom"
+import { AppShell, Group } from "@mantine/core";
+import { getUser } from "client/client";
+import { User } from "client/client.schemas";
+import { useAtom } from "jotai";
+import { userAtom } from "~/stores/userAtom";
+import HeaderMainComponent from "./HeaderMainComponent";
+import HeaderTitleLogo from "./HeaderTitleLogo";
const getCookieUserId = () => {
- if (typeof document === "undefined") return undefined
+ if (typeof document === "undefined") return undefined;
return document.cookie
.split("; ")
.find((row) => row.startsWith("__Secure-user_id="))
?.split("=")[1];
-}
+};
const HeaderComponent = () => {
- const [user, setUser] = useAtom(userAtom)
- const userId = getCookieUserId()
+ const [user, setUser] = useAtom(userAtom);
+ const userId = getCookieUserId();
if (userId) {
if (!user) {
// ユーザ情報を取得するAPIを呼び出す。
getUser(userId).then((response) => {
if (response.status === 200) {
- setUser(response.data as User)
+ setUser(response.data as User);
}
- })
+ });
}
}
return (
-
-
+
+
- )
-}
+ );
+};
-export default HeaderComponent
\ No newline at end of file
+export default HeaderComponent;
diff --git a/frontend/app/components/header/HeaderLoginComponent.tsx b/frontend/app/components/header/HeaderLoginComponent.tsx
index 55752177..a6ca5430 100644
--- a/frontend/app/components/header/HeaderLoginComponent.tsx
+++ b/frontend/app/components/header/HeaderLoginComponent.tsx
@@ -1,43 +1,43 @@
-import { Button, Group, Modal, Stack, Text } from '@mantine/core'
-import HeaderBookMenu from './HeaderBookMenu'
-import HeaderUserMenu from './HeaderUserMenu';
-import { useDisclosure } from '@mantine/hooks'
-import { useLogout } from 'orval/client';
-import { useNavigate } from '@remix-run/react';
+import { Button, Group, Modal, Stack, Text } from "@mantine/core";
+import { useDisclosure } from "@mantine/hooks";
+import { useNavigate } from "@remix-run/react";
+import { useLogout } from "client/client";
+import { useAtom } from "jotai";
import { LuLogOut } from "react-icons/lu";
-import { errorNotifications, successNotifications } from '~/utils/notification';
-import HeaderUsersMenu from './HeaderUsersMenu';
-import { useAtom } from 'jotai';
-import { userAtom } from '~/stores/userAtom';
+import { userAtom } from "~/stores/userAtom";
+import { errorNotifications, successNotifications } from "~/utils/notification";
+import HeaderBookMenu from "./HeaderBookMenu";
+import HeaderUserMenu from "./HeaderUserMenu";
+import HeaderUsersMenu from "./HeaderUsersMenu";
const HeaderLoginComponent = () => {
- const [, setUser] = useAtom(userAtom)
- const [opened, { open, close }] = useDisclosure()
- const navigate = useNavigate()
- const logoutTask = useLogout()
- const handleLogoout = () => {
+ const [, setUser] = useAtom(userAtom);
+ const [opened, { open, close }] = useDisclosure();
+ const navigate = useNavigate();
+ const logoutTask = useLogout();
+ const handleLogout = () => {
logoutTask.mutate(undefined, {
onSuccess: (response) => {
switch (response.status) {
case 204:
- setUser(undefined)
- successNotifications('ログアウトしました')
- navigate('/home')
- break
+ setUser(undefined);
+ successNotifications("ログアウトしました");
+ navigate("/home");
+ break;
case 500:
- errorNotifications('サーバーエラーが発生しました')
- break
+ errorNotifications("サーバーエラーが発生しました");
+ break;
default:
- errorNotifications('エラーが発生しました')
- break
+ errorNotifications("エラーが発生しました");
+ break;
}
},
onError: () => {
- errorNotifications('ログアウトに失敗しました')
- close()
- }
- })
- }
+ errorNotifications("ログアウトに失敗しました");
+ close();
+ },
+ });
+ };
return (
<>
@@ -45,23 +45,23 @@ const HeaderLoginComponent = () => {
-
-
- ログアウトしますか?
-
-
-