Skip to content

Commit

Permalink
Merge pull request #801 from NUTFes/develop
Browse files Browse the repository at this point in the history
新機能アップデート
  • Loading branch information
Kubosaka authored Jun 27, 2024
2 parents c41799a + 3250b73 commit 17b8001
Show file tree
Hide file tree
Showing 24 changed files with 444 additions and 231 deletions.
2 changes: 1 addition & 1 deletion api/externals/repository/activity_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ func (ar *activityRepository) AllDetailsByPeriod(c context.Context, year string)
year_periods.year_id = years.id
WHERE
years.year = ` + year +
" ORDER BY activities.id"
" ORDER BY activities.updated_at DESC"

return ar.crud.Read(c, query)
}
2 changes: 1 addition & 1 deletion api/externals/repository/fund_information_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,6 @@ func (fir *fundInformationRepository) AllDetailsByPeriod(c context.Context, year
year_periods.year_id = years.id
WHERE
years.year = ` + year +
" ORDER BY fund_informations.id;"
" ORDER BY fund_informations.updated_at DESC;"
return fir.crud.Read(c, query)
}
4 changes: 2 additions & 2 deletions mysql/db/users.sql
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ INSERT into users (name, bureau_id, role_id) values ('技大太郎2', 6, 2);
-- 財務局長
INSERT into users (name, bureau_id, role_id) values ('技大太郎3', 3, 3);

-- 一般ユーザー(財務局員
INSERT into users (name, bureau_id, role_id) values ('技大太郎4', 3, 1);
-- 財務局員
INSERT into users (name, bureau_id, role_id) values ('技大太郎4', 3, 4);
3 changes: 3 additions & 0 deletions view/next-project/src/components/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@ export { default as EditButton } from './EditButton';
export { default as Input } from './Input';
export { default as Modal } from './Modal';
export { default as OutlinePrimaryButton } from './OutlinePrimaryButton';
export { default as OpenModalButton } from './OpenModalButton';
export { default as PrimaryButton } from './PrimaryButton';
export { default as PullDown } from './PullDown';
export { default as Radio } from './Radio';
export { default as RedButton } from './RedButton';
export { default as RegistButton } from './RegistButton';
export { default as Select } from './Select';
export { default as Stepper } from './Stepper';
export { default as Textarea } from './Textarea';
export { default as Title } from './Title';
export { default as Tooltip } from './Tooltip';
export { default as UnderlinePrimaryButton } from './UnderlinePrimaryButton';
export { default as Label } from './Label';
export { default as LoadingButton } from './LoadingButton';
export { default as BureauLabel } from './BureauLabel';
export { default as Header } from './Header';
export { default as SideNav } from './SideNav';
Expand Down
36 changes: 26 additions & 10 deletions view/next-project/src/components/layout/MainLayout/MainLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,46 @@ import { useRouter } from 'next/router';
import React, { useEffect, useState } from 'react';
import { useRecoilState } from 'recoil';
import s from './MainLayout.module.css';

import { authAtom } from '@/store/atoms';
import { authAtom, userAtom } from '@/store/atoms';
import 'tailwindcss/tailwind.css';
import { Header, SideNav } from '@components/common';
import { User } from '@type/common';
import { get_with_token_valid } from '@utils/api/api_methods';

interface LayoutProps {
children?: React.ReactNode;
}

export default function MainLayout(props: LayoutProps) {
const router = useRouter();
const [auth] = useRecoilState(authAtom);
const [auth, setAuth] = useRecoilState(authAtom);
const [_, setUser] = useRecoilState(userAtom);
const [isSideNavOpen, setIsSideNavOpen] = useState(true);

useEffect(() => {
if (router.isReady) {
if (!auth.isSignIn) {
router.push('/');
const getCurrentUserUrl = process.env.CSR_API_URI + '/current_user';
get_with_token_valid(getCurrentUserUrl, auth.accessToken).then((result) => {
if (!result) {
localStorage.clear();
} else if (auth.isSignIn === true && router.pathname == '/') {
router.push('/purchaseorders');
const authData = {
isSignIn: false,
accessToken: '',
};
setAuth(authData);
setUser({} as User);
router.push('/');
} else {
if (router.isReady) {
if (!auth.isSignIn) {
router.push('/');
localStorage.clear();
} else if (auth.isSignIn === true && router.pathname == '/') {
router.push('/purchaseorders');
}
}
}
}
}, [router, auth]);
});
}, [router]);

return (
<>
Expand Down
114 changes: 114 additions & 0 deletions view/next-project/src/components/purchasereports/DetailEditModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import router from 'next/router';
import { useEffect, useState } from 'react';
import { Expense, PurchaseOrder, PurchaseReport } from '@/type/common';
import { put } from '@/utils/api/purchaseOrder';
import { get } from '@api/api_methods';
import {
CloseButton,
Input,
Modal,
OutlinePrimaryButton,
PrimaryButton,
Select,
} from '@components/common';

export const DetailEditModal: React.FC<{
purchaseReportId: number;
isOpen: boolean;
setIsOpen: () => void;
onOpenInitial: () => void;
}> = ({ purchaseReportId, setIsOpen, onOpenInitial }) => {
const [expenses, setExpenses] = useState<Expense[]>([]);
const [purchaseOrder, setPurchaseOrder] = useState<PurchaseOrder>({
id: 0,
deadline: '',
userID: 0,
expenseID: 0,
financeCheck: false,
});

useEffect(() => {
const fetchData = async () => {
try {
const purchaseReportRes: PurchaseReport = await get(
`${process.env.CSR_API_URI}/purchasereports/${purchaseReportId}`,
);
const purchaseOrderId = purchaseReportRes.purchaseOrderID;
const expensesRes: Expense[] = await get(`${process.env.CSR_API_URI}/expenses`);
const purchaseOrderRes: PurchaseOrder = await get(
`${process.env.CSR_API_URI}/purchaseorders/${purchaseOrderId}`,
);
setExpenses(expensesRes);
setPurchaseOrder(purchaseOrderRes);
} catch (error) {
console.error('Failed to fetch data:', error);
}
};
fetchData();
}, [purchaseReportId]);

const formatDate = (date: string) => {
const d = new Date(date);
const year = d.getFullYear();
const month = (1 + d.getMonth()).toString().padStart(2, '0');
const day = d.getDate().toString().padStart(2, '0');
return `${year}-${month}-${day}`;
};

const submit = async () => {
try {
const updatePurchaseOrderUrl = `${process.env.CSR_API_URI}/purchaseorders/${purchaseOrder.id}`;
await put(updatePurchaseOrderUrl, purchaseOrder);
} finally {
router.reload();
}
};

const handleInputChange = (key: keyof PurchaseOrder, value: string | number) => {
setPurchaseOrder((prev) => ({ ...prev, [key]: value }));
};

return (
<Modal className='md:w-1/2'>
<div className='ml-auto w-fit'>
<CloseButton onClick={setIsOpen} />
</div>
<div className='mx-auto mb-10 w-fit text-xl text-black-600'>
<p>購入した局と期限日を修正</p>
</div>
<div className='mx-auto my-6 grid w-9/10 grid-cols-4 items-center justify-items-center gap-4'>
<p className='text-lg text-black-600'>購入した局</p>
<div className='col-span-3 w-full'>
<Select
value={purchaseOrder.expenseID}
onChange={(e) => handleInputChange('expenseID', Number(e.target.value))}
>
{expenses.map((data) => (
<option key={data.id} value={data.id}>
{data.name}
</option>
))}
{!expenses.length && <option>局・団体が登録されていません</option>}
</Select>
</div>
<p className='text-lg text-black-600'>期限日</p>
<div className='col-span-3 w-full'>
<Input
type='date'
value={purchaseOrder.deadline ? formatDate(purchaseOrder.deadline) : ''}
onChange={(e) => handleInputChange('deadline', e.target.value)}
className='w-full'
/>
</div>
</div>
<div className='flex justify-center'>
<OutlinePrimaryButton onClick={onOpenInitial} className='mx-2'>
戻る
</OutlinePrimaryButton>
<PrimaryButton onClick={submit} className='mx-2 px-4'>
編集完了
</PrimaryButton>
</div>
</Modal>
);
};
13 changes: 7 additions & 6 deletions view/next-project/src/components/purchasereports/EditModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface ModalProps {
purchaseReportId: number;
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
onOpenInitial: () => void;
}

export default function EditModal(props: ModalProps) {
Expand Down Expand Up @@ -309,12 +310,12 @@ export default function EditModal(props: ModalProps) {
<div className='col-span-10 grid justify-items-center'>
{formDataList.length > 0 ? (
<div className='flex'>
{/* stepが1より大きい時のみ戻るボタンを表示 */}
{activeStep > 1 && (
<OutlinePrimaryButton onClick={prevStep} className={'mx-2'}>
戻る
</OutlinePrimaryButton>
)}
<OutlinePrimaryButton
onClick={activeStep > 1 ? prevStep : props.onOpenInitial}
className={'mx-2'}
>
戻る
</OutlinePrimaryButton>
<PrimaryButton
className={'mx-2 pl-4 pr-2'}
onClick={() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import * as React from 'react';
import { useState } from 'react';

import { EditButton } from '@components/common';
import { DetailEditModal } from './DetailEditModal';
import { CloseButton, EditButton, Modal, PrimaryButton } from '@components/common';
import EditModal from '@components/purchasereports/EditModal';

interface Props {
Expand All @@ -10,15 +11,55 @@ interface Props {
isDisabled: boolean;
}

const InitialModal: React.FC<{ setStep: (step: string) => void; closeModal: () => void }> = ({
setStep,
closeModal,
}) => (
<Modal className='md:w-1/2'>
<div className='ml-auto w-fit'>
<CloseButton onClick={closeModal} />
</div>
<div className='mx-auto mb-6 w-fit text-xl text-black-600'>
<p>購入報告の修正</p>
</div>
<div className='flex justify-center gap-2 pb-4'>
<PrimaryButton onClick={() => setStep('editDetails')}>局と期限日を編集</PrimaryButton>
<PrimaryButton onClick={() => setStep('editPurchases')}>購入物品を編集</PrimaryButton>
</div>
</Modal>
);

const OpenEditModalButton: React.FC<Props> = (props) => {
const [isOpen, setIsOpen] = useState(false);
const onOpen = () => {
setIsOpen(true);
const [step, setStep] = useState<string | null>(null);

const onOpenInitial = () => {
setStep('initial');
};

const closeModal = () => {
setStep(null);
};

return (
<>
<EditButton onClick={onOpen} isDisabled={props.isDisabled} />
{isOpen && <EditModal purchaseReportId={props.id} isOpen={isOpen} setIsOpen={setIsOpen} />}
<EditButton onClick={onOpenInitial} isDisabled={props.isDisabled} />
{step === 'initial' && <InitialModal setStep={setStep} closeModal={closeModal} />}
{step === 'editDetails' && (
<DetailEditModal
purchaseReportId={props.id}
isOpen={true}
setIsOpen={closeModal}
onOpenInitial={onOpenInitial}
/>
)}
{step === 'editPurchases' && (
<EditModal
purchaseReportId={props.id}
isOpen={true}
setIsOpen={closeModal}
onOpenInitial={onOpenInitial}
/>
)}
</>
);
};
Expand Down
22 changes: 6 additions & 16 deletions view/next-project/src/pages/budgets/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Tabs, TabList, TabPanels, Tab, TabPanel } from '@chakra-ui/react';
import clsx from 'clsx';
import Head from 'next/head';
import { useState, useEffect, useMemo } from 'react';
import { useState, useEffect } from 'react';
import { RiAddCircleLine } from 'react-icons/ri';

import { useRecoilValue } from 'recoil';
import OpenExpenditureAddModalButton from '@/components/budgets/OpenExpenditureAddModalButton';
import OpenExpenseAddModalButton from '@/components/budgets/OpenExpenseAddModalButton';
import OpenExpenseDeleteModalButton from '@/components/budgets/OpenExpenseDeleteModalButton';
import OpenExpenseEditModalButton from '@/components/budgets/OpenExpenseEditModalButton';
import { authAtom } from '@/store/atoms';
import { getCurrentUser } from '@/utils/api/currentUser';
import { userAtom } from '@/store/atoms';
import { get } from '@api/api_methods';
import DetailModal from '@components/budgets/DetailModal';
import OpenAddModalButton from '@components/budgets/OpenAddModalButton';
Expand Down Expand Up @@ -58,25 +57,16 @@ export async function getServerSideProps() {

export default function BudgetList(props: Props) {
const { budgets, sources, years, expenses } = props;
const auth = useRecoilValue(authAtom);
const user = useRecoilValue(userAtom);
const [currentUser, setCurrentUser] = useState<User>();
const [budgetViews, setBudgetViews] = useState<BudgetView[]>(props.budgets);
const [expenseViews, setExpenseViews] = useState<ExpenseView[]>(props.expenses);

useEffect(() => {
const getUser = async () => {
const res = await getCurrentUser(auth);
setCurrentUser(res);
};
getUser();
}, [auth]);
setCurrentUser(user);
}, []);

const isDisabled = useMemo(() => {
if (currentUser) {
return !(currentUser.roleID === 2 || currentUser.roleID === 3);
}
return true;
}, [currentUser]);
const isDisabled = !(currentUser?.roleID === 2 || currentUser?.roleID === 3);

const [forcusExpense, setForcusExpense] = useState<ExpenseView | null>(null);
const [isOpen, setIsOpen] = useState(false);
Expand Down
Loading

0 comments on commit 17b8001

Please sign in to comment.