見出し画像

React で作る柔軟な割り勘アプリ:動的な人数調整とリアルタイム計算機能付き

今回のブログ記事では、Reactを使って作成した高機能な割り勘アプリのコンポーネントを紹介します。このアプリは、複数人での利用を想定し、直感的なユーザーインターフェースを備えています。

主な特徴:

  1. 動的な人数調整:2人以上の支払い者を簡単に追加・削除できます。

  2. スライダーによる割合設定:各参加者の支払い割合をスムーズに調整可能。

  3. リアルタイム自動計算:全体の割合が常に100%になるよう自動調整します。

  4. 柔軟な金額計算:合計金額を入力すると、各人の支払額をリアルタイムで計算。

  5. モダンなUI:shadcn/uiライブラリを活用し、美しく使いやすいデザインを実現。

このブログでは、コンポーネントの実装詳細や、Reactの特徴を活かした状態管理、ユーザーインタラクションの処理方法について深く掘り下げています。さらに、shadcn/uiライブラリの活用法や、コンポーネントのカスタマイズについても触れています。

React開発者はもちろん、使いやすいWebアプリケーションの設計に興味がある方にとって、参考になる内容となっています。ぜひ、あなたのプロジェクトにこのコンポーネントを取り入れ、カスタマイズしてみてください!

プロンプト
複数人で利用できる割り勘アプリを作成し、各人が支払う割合をスライダーで設定できるようにします。また、支払いの合計が常に100%になるように計算を行う機能を備えます。


import React, { useState, useEffect } from 'react';
import { Slider } from '@/components/ui/slider';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';

const SplitBillApp = () => {
  const [people, setPeople] = useState([
    { name: '人物1', percentage: 50 },
    { name: '人物2', percentage: 50 },
  ]);
  const [totalAmount, setTotalAmount] = useState(0);

  useEffect(() => {
    adjustPercentages();
  }, [people]);

  const adjustPercentages = () => {
    const total = people.reduce((sum, person) => sum + person.percentage, 0);
    if (total !== 100) {
      const factor = 100 / total;
      setPeople(people.map(person => ({
        ...person,
        percentage: Math.round(person.percentage * factor)
      })));
    }
  };

  const handleSliderChange = (index, newValue) => {
    const newPeople = [...people];
    newPeople[index].percentage = newValue[0];
    setPeople(newPeople);
  };

  const handleNameChange = (index, newName) => {
    const newPeople = [...people];
    newPeople[index].name = newName;
    setPeople(newPeople);
  };

  const addPerson = () => {
    setPeople([...people, { name: `人物${people.length + 1}`, percentage: 0 }]);
  };

  const removePerson = (index) => {
    const newPeople = people.filter((_, i) => i !== index);
    setPeople(newPeople);
  };

  return (
    <div className="p-4 max-w-md mx-auto">
      <h1 className="text-2xl font-bold mb-4">割り勘アプリ</h1>
      <div className="mb-4">
        <label className="block mb-2">合計金額</label>
        <Input
          type="number"
          value={totalAmount}
          onChange={(e) => setTotalAmount(Number(e.target.value))}
          className="w-full"
        />
      </div>
      {people.map((person, index) => (
        <div key={index} className="mb-4 p-4 border rounded">
          <Input
            value={person.name}
            onChange={(e) => handleNameChange(index, e.target.value)}
            className="mb-2"
          />
          <Slider
            value={[person.percentage]}
            onValueChange={(newValue) => handleSliderChange(index, newValue)}
            max={100}
            step={1}
            className="mb-2"
          />
          <div className="flex justify-between">
            <span>{person.percentage}%</span>
            <span>{Math.round(totalAmount * person.percentage / 100)}円</span>
          </div>
          {people.length > 2 && (
            <Button onClick={() => removePerson(index)} className="mt-2">削除</Button>
          )}
        </div>
      ))}
      <Button onClick={addPerson} className="mt-4">人物を追加</Button>
    </div>
  );
};

export default SplitBillApp;


Live Preview


いいなと思ったら応援しよう!

この記事が参加している募集