diff --git a/Makefile b/Makefile index b2624ea1b..90803c3d3 100644 --- a/Makefile +++ b/Makefile @@ -68,3 +68,7 @@ run-prod: # DB入るコマンド ent-db: docker compose exec db mysql -u root -proot + +# eslintの実行 +run-eslint: + docker compose exec view npm run lint diff --git a/api/docs/docs.go b/api/docs/docs.go index 72bdf33cf..868a61c11 100644 --- a/api/docs/docs.go +++ b/api/docs/docs.go @@ -88,8 +88,8 @@ const docTemplate = `{ "required": false, "schema": { "type": "string", - "enum": ["true", "false", "all"] - } + "enum": ["true", "false", "all"] + } }, { "name": "sponsor_style_id", @@ -134,7 +134,7 @@ const docTemplate = `{ "required": true, "schema": { "type": "string" - } + } }, { "name": "is_done", @@ -143,8 +143,8 @@ const docTemplate = `{ "required": false, "schema": { "type": "string", - "enum": ["true", "false", "all"] - } + "enum": ["true", "false", "all"] + } }, { "name": "sponsor_style_id", diff --git a/api/externals/controller/activity_controller.go b/api/externals/controller/activity_controller.go index bf571ccc9..f7585ea03 100644 --- a/api/externals/controller/activity_controller.go +++ b/api/externals/controller/activity_controller.go @@ -108,7 +108,7 @@ func (a *activityController) IndexActivityDetailsByPeriod(c echo.Context) error } func (a *activityController) IndexFilteredActivityDetail(c echo.Context) error { - isDone := c.QueryParam("is_done") + isDone := c.QueryParam("is_done") sponsorStyleIDs := c.QueryParams()["sponsor_style_id"] keyword := c.QueryParam("keyword") activities, err := a.u.GetFilteredActivityDetail(c.Request().Context(), isDone, sponsorStyleIDs, keyword) @@ -119,7 +119,7 @@ func (a *activityController) IndexFilteredActivityDetail(c echo.Context) error { } func (a *activityController) IndexFilteredActivityDetailByPeriod(c echo.Context) error { - isDone := c.QueryParam("is_done") + isDone := c.QueryParam("is_done") sponsorStyleIDs := c.QueryParams()["sponsor_style_id"] year := c.Param("year") keyword := c.QueryParam("keyword") @@ -128,4 +128,4 @@ func (a *activityController) IndexFilteredActivityDetailByPeriod(c echo.Context) return err } return c.JSON(http.StatusOK, activities) -} \ No newline at end of file +} diff --git a/api/externals/repository/activity_repository.go b/api/externals/repository/activity_repository.go index a1dcfdfb5..f79c55310 100644 --- a/api/externals/repository/activity_repository.go +++ b/api/externals/repository/activity_repository.go @@ -334,9 +334,9 @@ func (ar *activityRepository) FindFilteredDetailByPeriod(c context.Context, isDo if year != "" { if optionQuery != "" { optionQuery += ` AND - years.year = ` + year + " ORDER BY activities.updated_at DESC" + years.year = ` + year + " ORDER BY activities.updated_at DESC, activities.id DESC" } else { - optionQuery += ` years.year = ` + year + " ORDER BY activities.updated_at DESC" + optionQuery += ` years.year = ` + year + " ORDER BY activities.updated_at DESC, activities.id DESC" } } @@ -345,4 +345,4 @@ func (ar *activityRepository) FindFilteredDetailByPeriod(c context.Context, isDo } return ar.crud.Read(c, query) -} \ No newline at end of file +} diff --git a/view/next-project/.eslintrc.json b/view/next-project/.eslintrc.json index 2eb42e9a4..8cdd21d28 100644 --- a/view/next-project/.eslintrc.json +++ b/view/next-project/.eslintrc.json @@ -18,7 +18,7 @@ "jsx": true }, "ecmaVersion": "latest", - "project": ["./tsconfig.json"], + "project": ["./tsconfig.json", "./tsconfig.stories.json"], "sourceType": "module" }, "settings": { diff --git a/view/next-project/src/components/common/Input/Input.module.css b/view/next-project/src/components/common/Input/Input.module.css index a0ee10c0d..c72d0c595 100644 --- a/view/next-project/src/components/common/Input/Input.module.css +++ b/view/next-project/src/components/common/Input/Input.module.css @@ -1,5 +1,4 @@ .input:focus { border-color: #48b2cf; - border-width: 1.75px; - outline: none; + outline: 1.5px #48b2cf solid; } diff --git a/view/next-project/src/components/common/Modal.tsx b/view/next-project/src/components/common/Modal.tsx index 5b5dfe1ce..f85fc4e0e 100644 --- a/view/next-project/src/components/common/Modal.tsx +++ b/view/next-project/src/components/common/Modal.tsx @@ -4,6 +4,7 @@ import React, { useEffect } from 'react'; interface Props { className?: string; children?: React.ReactNode; + onClick?: () => void; } export default function Modal(props: Props) { @@ -23,7 +24,10 @@ export default function Modal(props: Props) { return ( <> -
+
{props.children}
diff --git a/view/next-project/src/components/common/Select/Select.module.css b/view/next-project/src/components/common/Select/Select.module.css index 7e567b318..a5788b61a 100644 --- a/view/next-project/src/components/common/Select/Select.module.css +++ b/view/next-project/src/components/common/Select/Select.module.css @@ -1,7 +1,6 @@ .select:focus { border-color: #48b2cf; - border-width: 1.75px; - outline: none; + outline: 1.5px #48b2cf solid; } .customSelect { diff --git a/view/next-project/src/components/sponsoractivities/FilterModal.tsx b/view/next-project/src/components/sponsoractivities/FilterModal.tsx new file mode 100644 index 000000000..975d263c6 --- /dev/null +++ b/view/next-project/src/components/sponsoractivities/FilterModal.tsx @@ -0,0 +1,183 @@ +import React, { FC, useState } from 'react'; +import { Modal, Select, CloseButton, Input, PrimaryButton } from '@components/common'; +import { SponsorStyle, SponsorFilterType } from '@type/common'; + +interface ModalProps { + isOpen: boolean; + setIsOpen: (isOpen: boolean) => void; + sponsorStyles: SponsorStyle[]; + filterData: SponsorFilterType; + setFilterData: (filterData: SponsorFilterType) => void; +} + +const SELECT = '選択中'; +const NOT_SELECT = '未選択'; + +const FilterModal: FC = (props) => { + const { sponsorStyles, filterData, setFilterData } = props; + + const [isAllStyleCheck, setIsAllStyleCheck] = useState( + filterData.styleIds.length === sponsorStyles.length, + ); + type SelectOption = 'all' | 'false' | 'true'; + + // モーダル用の変数 + const [draftFilterData, setDraftFilterData] = useState(filterData); + + function includeStyleIds(id: number) { + return draftFilterData.styleIds.includes(id); + } + + function filterHandler(event: any) { + event.preventDefault(); + setFilterData(draftFilterData); + setIsAllStyleCheck(isAllStyleCheck); + props.setIsOpen(false); + } + + function addAndRemoveStyleIds(id: number) { + includeStyleIds(id) + ? (setDraftFilterData({ + ...draftFilterData, + styleIds: draftFilterData.styleIds.filter((styleId) => styleId !== id), + }), + setIsAllStyleCheck(false)) + : (setDraftFilterData({ + ...draftFilterData, + styleIds: [...draftFilterData.styleIds, id], + }), + sponsorStyles.length === [...draftFilterData.styleIds, id].length && + setIsAllStyleCheck(true)); + } + + const topCheckboxEvent = (event: any) => { + isAllStyleCheck ? deleteAllStyleIds() : addAllStyleIds(); + }; + + const preventCloseModalEvent = (event: any) => { + event.stopPropagation(); + }; + + function addAllStyleIds() { + const allStyleIDs = sponsorStyles.map((style) => style?.id || 0); + setDraftFilterData({ ...draftFilterData, styleIds: allStyleIDs }); + setIsAllStyleCheck(true); + } + + function deleteAllStyleIds() { + setDraftFilterData({ ...draftFilterData, styleIds: [] }); + setIsAllStyleCheck(false); + } + + const onClose = () => { + props.setIsOpen(false); + }; + + return ( + { + onClose(); + }} + > +
+
+
+
+ +
+
+
協賛フィルター
+
+

協賛スタイル

+
+
+
+ + +
+
+ {props.sponsorStyles.map((style) => ( +
+ { + addAndRemoveStyleIds(style?.id || 0); + }} + id={String(style.id)} + > + +
+ ))} +
+
+
+

回収有無

+
+ +
+

企業名検索

+
+ { + setDraftFilterData({ ...draftFilterData, keyword: e.target.value }); + }} + /> +
+

並び替え

+
+ +
+
+
+ 設定 +
+
+
+
+ ); +}; + +export default FilterModal; diff --git a/view/next-project/src/components/sponsoractivities/OpenAddModalButton.tsx b/view/next-project/src/components/sponsoractivities/OpenAddModalButton.tsx index e2f39a177..4c1891c4a 100644 --- a/view/next-project/src/components/sponsoractivities/OpenAddModalButton.tsx +++ b/view/next-project/src/components/sponsoractivities/OpenAddModalButton.tsx @@ -12,7 +12,7 @@ interface Props { children?: React.ReactNode; } -export default function OpenModalButton(props: Props) { +export default function OpenAddModalButton(props: Props) { const [isOpen, setIsOpen] = useState(false); return ( diff --git a/view/next-project/src/components/sponsoractivities/index.ts b/view/next-project/src/components/sponsoractivities/index.ts new file mode 100644 index 000000000..aa890f8b5 --- /dev/null +++ b/view/next-project/src/components/sponsoractivities/index.ts @@ -0,0 +1,15 @@ +export { default as AddPdfDetailModal } from './AddPdfDetailModal'; +export { default as DeleteModal } from './DeleteModal'; +export { default as DetailModal } from './DetailModal'; +export { default as DetailPage1 } from './DetailPage1'; +export { default as DetailPage2 } from './DetailPage2'; +export { default as EditModal } from './EditModal'; +export { default as FilterModal } from './FilterModal'; +export { default as OpenAddModalButton } from './OpenAddModalButton'; +export { default as OpenAddPdfDetailModalButton } from './OpenAddPdfDetailModalButton'; +export { default as OpenDeleteModalButton } from './OpenDeleteModalButton'; +export { default as OpenEditModalButton } from './OpenEditModalButton'; +export { default as OpenPaymentDayModalButton } from './OpenPaymentDayModalButton'; +export { default as PaymentDayModal } from './PaymentDayModal'; +export { default as SponsorActivitiesAddModal } from './SponsorActivitiesAddModal'; +export { default as UploadFileModal } from './UploadFileModal'; diff --git a/view/next-project/src/pages/sponsoractivities/index.tsx b/view/next-project/src/pages/sponsoractivities/index.tsx index 90e33e0d7..e218e9fa8 100644 --- a/view/next-project/src/pages/sponsoractivities/index.tsx +++ b/view/next-project/src/pages/sponsoractivities/index.tsx @@ -2,17 +2,22 @@ import clsx from 'clsx'; import Head from 'next/head'; import { useState, useEffect, useMemo } from 'react'; +import { MdFilterList, MdCircle } from 'react-icons/md'; import { RiExternalLinkLine } from 'react-icons/ri'; import PrimaryButton from '@/components/common/OutlinePrimaryButton/OutlinePrimaryButton'; -import OpenModalButton from '@/components/sponsoractivities/OpenAddModalButton'; +import { + OpenAddModalButton, + DetailModal, + OpenDeleteModalButton, + OpenEditModalButton, + FilterModal, +} from '@/components/sponsoractivities'; import { createPresentationCsv } from '@/utils/createActivityCsv'; import { downloadFile } from '@/utils/downloadFile'; import { get } from '@api/api_methods'; +import { getByFiler } from '@api/sponsorActivities'; import { Card, Title } from '@components/common'; import MainLayout from '@components/layout/MainLayout'; -import DetailModal from '@components/sponsoractivities/DetailModal'; -import OpenDeleteModalButton from '@components/sponsoractivities/OpenDeleteModalButton'; -import OpenEditModalButton from '@components/sponsoractivities/OpenEditModalButton'; import { DESIGNERS } from '@constants/designers'; import { SponsorActivity, @@ -22,6 +27,7 @@ import { User, ActivityStyle, YearPeriod, + SponsorFilterType, } from '@type/common'; interface Props { @@ -35,14 +41,8 @@ interface Props { } export async function getServerSideProps() { - const getSponsorActivitiesUrl = process.env.SSR_API_URI + '/years/periods'; - const periodsRes = await get(getSponsorActivitiesUrl); - const getSponsorActivitiesViewUrl = - process.env.SSR_API_URI + - '/activities/details/' + - (periodsRes - ? String(periodsRes[periodsRes.length - 1].year) - : String(new Date().getFullYear())); + const getYearPeriodUrl = process.env.SSR_API_URI + '/years/periods'; + const periodsRes = await get(getYearPeriodUrl); const getSponsorStylesUrl = process.env.SSR_API_URI + '/sponsorstyles'; const getSponsorsUrl = process.env.SSR_API_URI + @@ -53,8 +53,6 @@ export async function getServerSideProps() { const getUsersUrl = process.env.SSR_API_URI + '/users'; const getActivityStylesUrl = process.env.SSR_API_URI + '/activity_styles'; - const sponsorActivitiesRes = await get(getSponsorActivitiesUrl); - const sponsorActivitiesViewRes = await get(getSponsorActivitiesViewUrl); const sponsorStylesRes = await get(getSponsorStylesUrl); const sponsorsRes = await get(getSponsorsUrl); const usersRes = await get(getUsersUrl); @@ -62,8 +60,6 @@ export async function getServerSideProps() { return { props: { - sponsorActivities: sponsorActivitiesRes, - sponsorActivitiesView: sponsorActivitiesViewRes, sponsorStyles: sponsorStylesRes, sponsors: sponsorsRes, users: usersRes, @@ -81,69 +77,47 @@ const formatYYYYMMDD = (date: Date) => { }; export default function SponsorActivities(props: Props) { - const [sponsorActivities, setSponsorActivities] = useState( - props.sponsorActivitiesView, - ); + const { sponsorStyles, sponsors, users, activityStyles, yearPeriods } = props; + const [sponsorActivities, setSponsorActivities] = useState(); const [sponsorActivitiesID, setSponsorActivitiesID] = useState(1); const [sponsorActivitiesItem, setSponsorActivitiesViewItem] = useState(); const [isOpen, setIsOpen] = useState(false); - const sponsors = props.sponsors; - - const onOpen = (sponsorActivitiesID: number, sponsorActivitiesItem: SponsorActivityView) => { - setSponsorActivitiesID(sponsorActivitiesID); - setSponsorActivitiesViewItem(sponsorActivitiesItem); - setIsOpen(true); - }; - - const formatDate = (date: string) => { - const datetime = date.replace('T', ' ').replace('Z', ''); - const datetime2 = datetime.substring(5, datetime.length - 3).replace('-', '/'); - return datetime2; - }; - - const yearPeriods = props.yearPeriods; + const [isFilerOpen, setIsFilerOpen] = useState(false); + const [filterData, setFilterData] = useState({ + styleIds: sponsorStyles.map((style) => style?.id || 0), + isDone: 'all', + keyword: '', + selectedSort: 'default', + }); const [selectedYear, setSelectedYear] = useState( yearPeriods ? String(yearPeriods[yearPeriods.length - 1].year) : String(new Date().getFullYear()), ); + const currentYear = new Date().getFullYear().toString(); + + const onModalOpen = (sponsorActivitiesID: number, sponsorActivitiesItem: SponsorActivityView) => { + setSponsorActivitiesID(sponsorActivitiesID); + setSponsorActivitiesViewItem(sponsorActivitiesItem); + setIsOpen(true); + }; const getSponsorActivities = async () => { const getSponsorActivitiesViewUrlByYear = - process.env.CSR_API_URI + '/activities/details/' + selectedYear; - const getSponsorActivitiesByYears = await get(getSponsorActivitiesViewUrlByYear); - setSponsorActivities(getSponsorActivitiesByYears); + process.env.CSR_API_URI + '/activities/filtered_details/' + selectedYear; + const getFilterSponsorActivitiesByYears = await getByFiler( + getSponsorActivitiesViewUrlByYear, + filterData.isDone, + filterData.styleIds, + filterData.keyword, + sponsorStyles.length, + ); + setSponsorActivities(getFilterSponsorActivitiesByYears); }; - const currentYear = new Date().getFullYear().toString(); - const [selectedIsDone, setSelectedIsDone] = useState('all'); - const [selectedSort, setSelectedSort] = useState('default'); - - const sortedAndFilteredSponsorActivitiesViews = useMemo(() => { - let filteredActivities = sponsorActivities; - - switch (selectedIsDone) { - case 'false': - if (!Array.isArray(filteredActivities)) { - return []; - } - filteredActivities = filteredActivities.filter((sponsorActivitiesItem) => { - return !sponsorActivitiesItem.sponsorActivity.isDone; - }); - break; - case 'true': - if (!Array.isArray(filteredActivities)) { - return []; - } - filteredActivities = filteredActivities.filter((sponsorActivitiesItem) => { - return sponsorActivitiesItem.sponsorActivity.isDone; - }); - break; - default: - break; - } - - switch (selectedSort) { + const sortedSponsorActivitiesViews = useMemo(() => { + const filteredActivities = sponsorActivities; + switch (filterData.selectedSort) { case 'updateSort': if (!Array.isArray(filteredActivities)) { return []; @@ -202,22 +176,22 @@ export default function SponsorActivities(props: Props) { default: return filteredActivities; } - }, [props, selectedYear, selectedIsDone, selectedSort, sponsorActivities]); + }, [filterData, sponsorActivities]); const TotalTransportationFee = useMemo(() => { let totalFee = 0; - if (sortedAndFilteredSponsorActivitiesViews) { - sortedAndFilteredSponsorActivitiesViews?.map((sponsorActivityItem) => { + if (sortedSponsorActivitiesViews) { + sortedSponsorActivitiesViews?.map((sponsorActivityItem) => { totalFee += sponsorActivityItem.sponsorActivity.expense; }); } return totalFee; - }, [sortedAndFilteredSponsorActivitiesViews]); + }, [sortedSponsorActivitiesViews]); const TotalActivityStyleFee = useMemo(() => { let totalFee = 0; - if (sortedAndFilteredSponsorActivitiesViews) { - sortedAndFilteredSponsorActivitiesViews?.map((sponsorActivityItem) => { + if (sortedSponsorActivitiesViews) { + sortedSponsorActivitiesViews?.map((sponsorActivityItem) => { const sponsorActivitiesStylesPrice = sponsorActivityItem.styleDetail ? sponsorActivityItem.styleDetail.map((styleDetail) => { return styleDetail.sponsorStyle.price; @@ -231,11 +205,19 @@ export default function SponsorActivities(props: Props) { }); } return totalFee; - }, [sortedAndFilteredSponsorActivitiesViews]); + }, [sortedSponsorActivitiesViews]); useEffect(() => { getSponsorActivities(); - }, [selectedYear]); + }, [filterData, selectedYear]); + + const isFiltered = useMemo(() => { + const isStyleFilter = sponsorStyles.length !== filterData.styleIds.length; + const isDonefilter = filterData.isDone !== 'all'; + const isKeywordFilter = filterData.keyword.length !== 0; + const isSorted = filterData.selectedSort !== 'default'; + return isStyleFilter || isDonefilter || isKeywordFilter || isSorted; + }, [filterData]); return ( @@ -264,33 +246,36 @@ export default function SponsorActivities(props: Props) { ); })} - - +
+ + {isFiltered && ( +
+ +
+ )} +
+ {isFilerOpen && ( + + )} { downloadFile({ downloadContent: await createPresentationCsv( - sortedAndFilteredSponsorActivitiesViews, + sortedSponsorActivitiesViews || [], ), fileName: `協賛活動一覧_${formatYYYYMMDD(new Date())}.csv`, isBomAdded: true, @@ -303,26 +288,26 @@ export default function SponsorActivities(props: Props) {
- 協賛活動登録 - +
-
- {sortedAndFilteredSponsorActivitiesViews && - sortedAndFilteredSponsorActivitiesViews.map((sponsorActivitiesItem) => ( + {sortedSponsorActivitiesViews && + sortedSponsorActivitiesViews.map((sponsorActivitiesItem) => (
@@ -393,9 +378,9 @@ export default function SponsorActivities(props: Props) { sponsorActivity={sponsorActivitiesItem.sponsorActivity} sponsors={props.sponsors} sponsorStyles={props.sponsorStyles} - users={props.users} + users={users} sponsorStyleDetails={sponsorActivitiesItem.styleDetail} - activityStyles={props.activityStyles} + activityStyles={activityStyles} year={selectedYear} yearPeriods={yearPeriods} /> @@ -404,10 +389,9 @@ export default function SponsorActivities(props: Props) {
))} - {sortedAndFilteredSponsorActivitiesViews && - sortedAndFilteredSponsorActivitiesViews.length === 0 && ( -
データがありません
- )} + {sortedSponsorActivitiesViews && sortedSponsorActivitiesViews.length === 0 && ( +
データがありません
+ )}
@@ -440,15 +424,15 @@ export default function SponsorActivities(props: Props) { - {sortedAndFilteredSponsorActivitiesViews && - sortedAndFilteredSponsorActivitiesViews.map((sponsorActivitiesItem) => ( + {sortedSponsorActivitiesViews && + sortedSponsorActivitiesViews.map((sponsorActivitiesItem) => ( ))} - {sortedAndFilteredSponsorActivitiesViews && - sortedAndFilteredSponsorActivitiesViews.length > 0 && ( - - - - - - - )} - {(!sortedAndFilteredSponsorActivitiesViews || - sortedAndFilteredSponsorActivitiesViews.length === 0) && ( + {sortedSponsorActivitiesViews && sortedSponsorActivitiesViews.length > 0 && ( + + + + + + + )} + {(!sortedSponsorActivitiesViews || sortedSponsorActivitiesViews.length === 0) && (
{ - onOpen( + onModalOpen( sponsorActivitiesItem.sponsorActivity.id || 0, sponsorActivitiesItem, ); @@ -460,7 +444,7 @@ export default function SponsorActivities(props: Props) { { - onOpen( + onModalOpen( sponsorActivitiesItem.sponsorActivity.id || 0, sponsorActivitiesItem, ); @@ -482,7 +466,7 @@ export default function SponsorActivities(props: Props) { { - onOpen( + onModalOpen( sponsorActivitiesItem.sponsorActivity.id || 0, sponsorActivitiesItem, ); @@ -494,7 +478,7 @@ export default function SponsorActivities(props: Props) { { - onOpen( + onModalOpen( sponsorActivitiesItem.sponsorActivity.id || 0, sponsorActivitiesItem, ); @@ -509,7 +493,7 @@ export default function SponsorActivities(props: Props) { { - onOpen( + onModalOpen( sponsorActivitiesItem.sponsorActivity.id || 0, sponsorActivitiesItem, ); @@ -521,7 +505,7 @@ export default function SponsorActivities(props: Props) { { - onOpen( + onModalOpen( sponsorActivitiesItem.sponsorActivity.id || 0, sponsorActivitiesItem, ); @@ -544,7 +528,7 @@ export default function SponsorActivities(props: Props) { { - onOpen( + onModalOpen( sponsorActivitiesItem.sponsorActivity.id || 0, sponsorActivitiesItem, ); @@ -560,11 +544,11 @@ export default function SponsorActivities(props: Props) { @@ -578,33 +562,31 @@ export default function SponsorActivities(props: Props) {
-
-
合計
-
-
-
- {TotalActivityStyleFee} -
-
-
-
合計
-
-
-
- {TotalTransportationFee} -
-
+
+
合計
+
+
+
+ {TotalActivityStyleFee} +
+
+
+
合計
+
+
+
+ {TotalTransportationFee} +
+
データがありません
diff --git a/view/next-project/src/stories/purchaseorders/DetailModal.stories.tsx b/view/next-project/src/stories/purchaseorders/DetailModal.stories.tsx index 60c7801d6..5a9bfa667 100644 --- a/view/next-project/src/stories/purchaseorders/DetailModal.stories.tsx +++ b/view/next-project/src/stories/purchaseorders/DetailModal.stories.tsx @@ -28,36 +28,47 @@ Primary.args = { id: '123', purchaseOrderViewItem: { purchaseOrder: { - id: '12345', // 適切なidを設定 - expenseID: '123', // 必要に応じて調整 - createdAt: new Date().toISOString(), // 現在の日付のISO文字列 - deadline: new Date().toISOString(), // 現在の日付のISO文字列 + id: 123, // 適切なidを設定 + expenseID: 123, // 必要に応じて調整 + userID: 123, + deadline: '20240907', + financeCheck: false, }, purchaseItem: [ { - id: '1', + id: 123, item: 'ポストイット 黄色', - price: '6000', - quantity: '20', + price: 6000, + purchaseOrderID: 123, + quantity: 20, detail: '衛生物品仕分けのため', url: 'https://www.amazon.co.jp/%E3%83%9D%E3%82%B9%E3%83%88%E3%82%A4%E3%83%83%E3%83%88-%E3%82%A4%E3%82%A8%E3%83%AD%E3%83%BC-75%C3%9775mm-90%E6%9E%9A%C3%9710%E3%83%91%E3%83%83%E3%83%89-6541SS-Y/dp/B09RMQKJL5/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=D6173OMOUM5T&dib=eyJ2IjoiMSJ9.27UQkXbp5c3HOdcXxqY7y8lurZZ2fWRkOsTe3OnG9yGEzulWe80kR9f3dwtbRl6_CE91H4xyd9cw4A0qjVXWE9aQI65uLFf6162PSTVYxTCbckLGNZPyXrt6Qs62tpZDweOBdMPnxJnOBCeATox63FfN7ax4wTVS2xozWVR473JM-BgA_PEq6nZW9gKeavZv91Gxw4bVVpD9wFZ9AXw_fgI3Ntdvd1EoDyU7BgsWJD0.4_nNNIuZNJGWWjvn8p7uJcf8OKpkc2pj-rnFj15ePl0&dib_tag=se&keywords=%E3%83%9D%E3%82%B9%E3%83%88%E3%82%A4%E3%83%83%E3%83%88+%E9%BB%84%E8%89%B2&qid=1720144913&s=instant-video&sprefix=%E3%83%9D%E3%82%B9%E3%83%88%E3%82%A4%E3%83%83%E3%83%88+%E9%BB%84%E8%89%B2,instant-video,173&sr=1-3', financeCheck: false, }, { - id: '2', + id: 124, item: 'ラミネートフィルム', - price: '3000', - quantity: '1', + price: 3000, + quantity: 1, + purchaseOrderID: 123, detail: 'ラミネート看板用の予備', url: 'https://www.amazon.co.jp/Bonsaii-100%CE%BCm%E3%83%95%E3%82%A3%E3%83%AB%E3%83%A0%E5%AF%BE%E5%BF%9C-%E8%A9%B0%E3%81%BE%E3%82%8A%E9%98%B2%E6%AD%A2%E3%83%AC%E3%83%90%E3%83%BC%E6%90%AD%E8%BC%89-%EF%BC%91%E5%88%86%E9%96%93400mm-%E3%82%AB%E3%83%BC%E3%83%89%E3%82%B5%E3%82%A4%E3%82%BA%E5%AF%BE%E5%BF%9C/dp/B07PHSX45C/ref=sr_1_2?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1TFXLNS619SWR&dib=eyJ2IjoiMSJ9.mSiLkvsecGF8tVQLpUZmpVkeWWGAf2aCp-ngfpOXY3vIn1D002MPU2kg_LbRpel42f2kowuYQQWH_Jqa12PPmZTtPLa6gQczNGEKIIHcWZCA0ESPm4sCj36lBPcpV30TcQqCw5wFMFse8RzEns8wVOojZU69CHnt8oAapLYKPYFqLtj5nW1RX3Qp8TECj36Nap9b3Aw1yWYDlYOi9_63KkpWwtsRqBHiwJNqb7_vcwY.2krKINDdmAX-06jEu3patfEDv3oPFI32gzXBAwseXHY&dib_tag=se&keywords=%E3%83%A9%E3%83%9F%E3%83%8D%E3%83%BC%E3%83%88&qid=1720145001&s=instant-video&sprefix=%E3%83%A9%E3%83%9F%E3%83%8D%E3%83%BC%E3%83%88,instant-video,175&sr=1-2', financeCheck: true, }, ], // 購入項目の配列、必要に応じて詳細を追加 + user: { + id: 123, + name: '窪坂駿吾', + bureauID: 1, + roleID: 2, + }, }, expenses: [ { - id: '123', + id: 123, name: '総務局', + totalPrice: 100, + yearID: 1, }, ], isDelete: false, diff --git a/view/next-project/src/stories/purchaseorders/EditModal.stories.tsx b/view/next-project/src/stories/purchaseorders/EditModal.stories.tsx index b87953d28..b635b8dd3 100644 --- a/view/next-project/src/stories/purchaseorders/EditModal.stories.tsx +++ b/view/next-project/src/stories/purchaseorders/EditModal.stories.tsx @@ -1,4 +1,4 @@ -import { Meta, Story } from '@storybook/react'; +import { Meta, StoryFn } from '@storybook/react'; import { EditModal } from '@components/purchaseorders'; import { PurchaseItem } from '@type/common'; // PurchaseItem 型のインポートを確認してください @@ -16,15 +16,16 @@ const samplePurchaseItems: PurchaseItem[] = [ { id: 1, item: 'ノートパソコン', - price: '100000', + price: 100000, quantity: 2, detail: 'ビジネス用', url: 'http://example.com', - finance_check: false, + financeCheck: false, + purchaseOrderID: 123, }, ]; -export const Primary: Story = (args) => ; +export const Primary: StoryFn = (args) => ; Primary.args = { purchaseOrderId: 123, purchaseItems: samplePurchaseItems, diff --git a/view/next-project/src/stories/purchaseorders/PurchaseOrderAddModal.stories.tsx b/view/next-project/src/stories/purchaseorders/PurchaseOrderAddModal.stories.tsx index 549995aa2..cfd175804 100644 --- a/view/next-project/src/stories/purchaseorders/PurchaseOrderAddModal.stories.tsx +++ b/view/next-project/src/stories/purchaseorders/PurchaseOrderAddModal.stories.tsx @@ -1,6 +1,6 @@ import { Meta, StoryFn } from '@storybook/react'; import React from 'react'; -import PurchaseOrderAddModal from '@components/purchaseorders/PurchaseOrderAddModal'; +import { PurchaseOrderAddModal } from '@components/purchaseorders'; const meta: Meta = { title: 'FinanSu/purchaseorders/PurchaseOrderAddModal', @@ -11,7 +11,9 @@ const meta: Meta = { export default meta; -const Template: StoryFn = (args) => ; +const Template: StoryFn = (args) => ( + +); export const Primary = Template.bind({}); Primary.args = { diff --git a/view/next-project/src/type/common.ts b/view/next-project/src/type/common.ts index 8eff044ff..a025b02b2 100644 --- a/view/next-project/src/type/common.ts +++ b/view/next-project/src/type/common.ts @@ -156,6 +156,12 @@ export interface SponsorActivityView { styleDetail: SponsorStyleDetail[]; } +export interface SponsorFilterType { + styleIds: number[]; + isDone: 'all' | 'false' | 'true'; + keyword: string; + selectedSort: string; +} // // Sponsor(協賛企業) export interface Sponsor { id?: number; diff --git a/view/next-project/src/utils/api/sponsorActivities.ts b/view/next-project/src/utils/api/sponsorActivities.ts index 799262046..bdac1ed95 100644 --- a/view/next-project/src/utils/api/sponsorActivities.ts +++ b/view/next-project/src/utils/api/sponsorActivities.ts @@ -24,3 +24,25 @@ export const put = async (url: string, data: SponsorActivity) => { }).then((response) => response.json()); return res; }; + +export const getByFiler = async ( + url: string, + isDone: string, + styleIds: number[], + keyword: string, + allSponsorStyleLen: number, +) => { + // TODO APIのリファクタリング NOTE 0件選択のとき全件取得するため存在しないidを指定している + const postStyleIds = styleIds.length > 0 ? styleIds : [allSponsorStyleLen + 1]; + const isDoneURL = `is_done=${isDone}`; + const styleIdsURL = `sponsor_style_id=${postStyleIds}`; + const keywordURL = `keyword=${keyword}`; + const getURL = `${url}?${isDoneURL}&${styleIdsURL}&${keywordURL}`; + const res = await fetch(getURL, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }); + return await res.json(); +}; diff --git a/view/next-project/tsconfig.json b/view/next-project/tsconfig.json index d42dbcca9..cd52a0bd5 100644 --- a/view/next-project/tsconfig.json +++ b/view/next-project/tsconfig.json @@ -19,6 +19,6 @@ "noFallthroughCasesInSwitch": true }, "extends": "./tsconfig.paths.json", - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "src/**/*.ts", "src/**/*.tsx"], "exclude": ["node_modules"] } diff --git a/view/next-project/tsconfig.stories.json b/view/next-project/tsconfig.stories.json new file mode 100644 index 000000000..b6dfcdd41 --- /dev/null +++ b/view/next-project/tsconfig.stories.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES6", + "module": "commonjs", + "jsx": "react", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/stories/**/*.tsx"] +}