Skip to content

Conversation

@nakatashingo
Copy link
Collaborator

対応Issue

https://www.notion.so/nutfes-nutmeg/FinanSu-2b941f19206380518f1af6de573da465
https://nut-m-e-g.slack.com/archives/C020WQ3GY07/p1765010563203229

概要

  • 購入報告一覧において,「局名」「氏名」で立替者の絞り込みを可能に
  • 購入報告一覧において,「未精算金額」「未封詰め金額」の合計金額を表示

画面スクリーンショット等

  • URL
    スクリーンショット

テスト項目

備考

@gemini-code-assist
Copy link

Summary of Changes

Hello @nakatashingo, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

このプルリクエストは、購入報告一覧ページのユーザビリティを大幅に向上させるための機能追加です。具体的には、立替者(局名および氏名)による絞り込み機能と、未清算金額および未封詰め金額の合計表示機能が導入されました。これにより、ユーザーはより効率的に必要な情報を探し、全体の財務状況を把握できるようになります。

Highlights

  • 立替者絞り込み機能の追加: 購入報告一覧ページに、立替者(局名と氏名)で絞り込みを行うための新しいモーダルコンポーネントが追加されました。
  • 合計金額表示機能の追加: 購入報告一覧ページに、未清算金額と未封詰め金額の合計を表示する新しいコンポーネントが追加され、財務状況の概要を素早く確認できるようになりました。
  • 既存ページへの機能統合: 上記の絞り込み機能と合計金額表示機能が、既存の購入報告リストページ(purchase_report_list/index.tsx)に統合され、ユーザーインターフェースが改善されました。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 24, 2026

Deploying finansu with  Cloudflare Pages  Cloudflare Pages

Latest commit: 29d8823
Status: ✅  Deploy successful!
Preview URL: https://a09fe70f.finansu.pages.dev
Branch Preview URL: https://feat-walt-purchase-report-so.finansu.pages.dev

View logs

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

このプルリクエストでは、購入報告一覧ページに立替者による絞り込み機能と、未清算・未封詰め金額の合計表示機能が追加されました。新機能の実装は概ね良好ですが、状態管理のロジックにいくつか改善の余地があります。特に、絞り込みモーダル内の状態管理が冗長であり、簡潔にすることができます。また、APIからのデータ取得部分で、より堅牢な型チェックを行うことで、将来的なエラーを防ぐことができます。詳細は各コメントを参照してください。

Comment on lines 44 to +49

const { data: usersResponse } = useGetUsers();
const users = useMemo(() => {
const responseData = usersResponse?.data as User[] | { data?: User[] } | undefined;
if (Array.isArray(responseData)) return responseData;
return responseData?.data ?? [];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

useGetUsersフックからのデータ抽出ロジックが、型アサーションに依存しており、堅牢性に欠ける可能性があります。orvalで生成されたuseGetUsersの戻り値の型がvoidになっているようですが、実際には{ data: User[] }またはUser[]のようなデータが返却されていると推測されます。この不一致は、APIスキーマ定義の誤りやorvalの設定に起因する可能性があります。

現状のコードは型アサーション as User[] | { data?: User[] } | undefined を使ってこの問題を回避していますが、APIのレスポンス形式が想定外のものに変わった場合にランタイムエラーを引き起こす可能性があります。

根本的な解決としてはAPIスキーマやorvalの設定を見直すべきですが、コンポーネントレベルでの改善として、より安全な型ガードを使用するか、この実装のリスクについてコメントを残しておくことを推奨します。

Comment on lines 53 to +55

const [selectedYear, setSelectedYear] = useState<number>(
yearPeriods && yearPeriods.length > 0 ? yearPeriods[yearPeriods.length - 1].year : 0,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

selectedYear の初期値を useState で設定しようとしていますが、初回レンダリング時には yearPeriods が未定義の可能性があるため、この式は期待通りに動作せず、常に 0 が初期値となります。後続の useEffect で正しい値が設定されるため動作に問題はありませんが、コードの意図を明確にするために、useState の初期値は 0 に固定し、初期化は useEffect に任せるのが良いでしょう。

  const [selectedYear, setSelectedYear] = useState<number>(0);

Comment on lines +24 to +67
const [draftPaidByUserId, setDraftPaidByUserId] = useState<number | null | undefined>(
selectedPaidByUserId,
);

useEffect(() => {
if (!isOpen) return;
setDraftBureauId(selectedBureauId);
setDraftPaidByUserId(selectedPaidByUserId);
}, [isOpen, selectedBureauId, selectedPaidByUserId]);

const bureauNameMap = useMemo(
() =>
new Map(
bureaus.map((bureau) => [bureau.id ?? 0, bureau.name] as const).filter(([id]) => id > 0),
),
[bureaus],
);

const filteredUsers = useMemo(() => {
if (!draftBureauId) return users;
return users.filter((user) => user.bureauID === draftBureauId);
}, [draftBureauId, users]);

const paidBySelectValue = draftPaidByUserId === null ? 'none' : draftPaidByUserId ?? '';

const handleBureauChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const value = event.target.value;
const nextBureauId = value === '' ? null : Number(value);
setDraftBureauId(nextBureauId);
setDraftPaidByUserId(undefined);
};

const handlePaidByChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
const value = event.target.value;
if (value === '') {
setDraftPaidByUserId(undefined);
return;
}
if (value === 'none') {
setDraftPaidByUserId(null);
return;
}
setDraftPaidByUserId(Number(value));
};

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

draftPaidByUserId の状態管理に number | null | undefined の3つの型が使われており、コードが少し複雑になっています。現状では nullundefined が両方とも「絞り込みなし」を意味するように見え、冗長です。
draftBureauIdnumber | null で管理されているように、draftPaidByUserIdnumber | null に統一し、null を「絞り込みなし」として扱うことで、コードをシンプルにし、一貫性を高めることができます。

以下の提案では、関連する状態とハンドラを null を使うように修正しています。
これに合わせて、96行目の optionvalue'none' から '' に変更してください: <option value=''>絞り込みなし</option>

  const [draftPaidByUserId, setDraftPaidByUserId] = useState<number | null>(
    selectedPaidByUserId ?? null,
  );

  useEffect(() => {
    if (!isOpen) return;
    setDraftBureauId(selectedBureauId);
    setDraftPaidByUserId(selectedPaidByUserId ?? null);
  }, [isOpen, selectedBureauId, selectedPaidByUserId]);

  const bureauNameMap = useMemo(
    () =>
      new Map(
        bureaus.map((bureau) => [bureau.id ?? 0, bureau.name] as const).filter(([id]) => id > 0),
      ),
    [bureaus],
  );

  const filteredUsers = useMemo(() => {
    if (!draftBureauId) return users;
    return users.filter((user) => user.bureauID === draftBureauId);
  }, [draftBureauId, users]);

  const paidBySelectValue = draftPaidByUserId ?? '';

  const handleBureauChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    const value = event.target.value;
    const nextBureauId = value === '' ? null : Number(value);
    setDraftBureauId(nextBureauId);
    setDraftPaidByUserId(null);
  };

  const handlePaidByChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    const value = event.target.value;
    setDraftPaidByUserId(value === '' ? null : Number(value));
  };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants