0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ReactとVercelで作るモダンな電卓アプリ「Dentaku」を作りました

Posted at

2024-07-29 15.13の画像.jpeg

こんにちは、皆さん!今回は、Reactを使ったモダンな電卓アプリケーション「Dentaku」を開発し、Vercelにデプロイした経験をシェアしたいと思います。プロジェクトの全体像から、具体的な手順まで詳しく紹介しますので、ぜひ参考にしてください。

アプリリンク

プロジェクトの概要

「Dentaku」は、シンプルでスタイリッシュな電卓アプリケーションです。最新のWeb技術を活用し、ユーザーに快適な使用感を提供することを目指しています。以下はプロジェクトの主な特徴です。

  • フロントエンドフレームワーク: React
  • ホスティング: Vercel
  • スタイル: Tailwind CSS
  • 機能: 基本的な計算機能(加算、減算、乗算、除算)

アプリケーションの機能

基本的な機能
数字入力: 0から9までの数字ボタンを使って、計算したい数値を入力できます。
小数点入力: 小数点ボタンを使って、小数を入力できます。
四則演算: 加算、減算、乗算、除算の基本的な計算機能を提供します。
結果表示: =ボタンを押すと計算結果が表示されます。
クリア機能: Clearボタンを押すと、現在の入力と計算結果がクリアされます。

プロジェクトのセットアップ

1. Create React Appの利用

まずは、Create React Appを使ってReactプロジェクトを作成しました。

npx create-react-app dentaku
cd dentaku

2. Tailwind CSSのインストールと設定

次に、Tailwind CSSをインストールし、設定を行いました。

npm install -D tailwindcss
npx tailwindcss init

tailwind.config.jsを以下のように設定します。

module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
    "./public/index.html",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

src/index.cssに以下を追加します。

@tailwind base;
@tailwind components;
@tailwind utilities;

3. 電卓コンポーネントの作成

src/components/MainComponent.jsに電卓コンポーネントを作成します。

"use client";
import React from "react";

function MainComponent() {
  const [display, setDisplay] = React.useState("0");
  const [currentValue, setCurrentValue] = React.useState("");
  const [previousValue, setPreviousValue] = React.useState("");
  const [operation, setOperation] = React.useState(null);

  const handleNumber = (num) => {
    if (display === "0" || operation) {
      setDisplay(num);
      setCurrentValue(num);
    } else {
      setDisplay((prevDisplay) => prevDisplay + num);
      setCurrentValue((prevValue) => prevValue + num);
    }
  };

  const handleOperation = (op) => {
    if (currentValue) {
      setPreviousValue(currentValue);
      setOperation(op);
      setCurrentValue("");
    }
  };

  const handleEqual = () => {
    if (previousValue && currentValue && operation) {
      const prev = parseFloat(previousValue);
      const curr = parseFloat(currentValue);
      const operations = {
        "+": (a, b) => a + b,
        "-": (a, b) => a - b,
        "*": (a, b) => a * b,
        "/": (a, b) => a / b,
      };
      const result = operations[operation](prev, curr);
      setDisplay(result.toString());
      setCurrentValue(result.toString());
      setPreviousValue("");
      setOperation(null);
    }
  };

  const handleClear = () => {
    setDisplay("0");
    setCurrentValue("");
    setPreviousValue("");
    setOperation(null);
  };

  const renderButton = (btn) => {
    const isOperation = ["+", "-", "*", "/"].includes(btn);
    const isEqual = btn === "=";
    const onClick = isOperation
      ? () => handleOperation(btn)
      : isEqual
      ? handleEqual
      : () => handleNumber(btn);

    let buttonClass =
      "bg-gradient-to-r from-indigo-500 to-purple-600 hover:from-indigo-600 hover:to-purple-700 text-white font-bold py-4 px-6 rounded-full shadow-lg transition duration-300 ease-in-out transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-purple-400 text-2xl";

    if (isOperation || isEqual) {
      buttonClass =
        "bg-gradient-to-r from-pink-500 to-red-600 hover:from-pink-600 hover:to-red-700 text-white font-bold py-4 px-6 rounded-full shadow-lg transition duration-300 ease-in-out transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-red-400 text-2xl";
    }

    return (
      <button key={btn} className={buttonClass} onClick={onClick}>
        {btn}
      </button>
    );
  };

  return (
    <div className="flex flex-col items-center justify-center min-h-screen bg-gradient-to-r from-purple-400 via-pink-500 to-red-500 font-roboto p-4">
      <div className="bg-white bg-opacity-20 backdrop-filter backdrop-blur-lg p-8 rounded-2xl shadow-2xl w-full max-w-md">
        <div className="bg-gray-800 p-4 mb-6 rounded-xl">
          <p className="text-right text-5xl text-white overflow-x-auto whitespace-nowrap">
            {display}
          </p>
        </div>
        <div className="grid grid-cols-4 gap-4">
          {[
            "7",
            "8",
            "9",
            "/",
            "4",
            "5",
            "6",
            "*",
            "1",
            "2",
            "3",
            "-",
            "0",
            ".",
            "=",
            "+",
          ].map(renderButton)}
          <button
            className="col-span-4 bg-gradient-to-r from-yellow-400 to-orange-500 hover:from-yellow-500 hover:to-orange-600 text-white font-bold py-4 px-6 rounded-full shadow-lg transition duration-300 ease-in-out transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-orange-400 text-2xl"
            onClick={handleClear}
          >
            Clear
          </button>
        </div>
      </div>
    </div>
  );
}

export default MainComponent;

4. App.jsの修正

src/App.jsを以下のように修正します。

import React from 'react';
import './App.css';
import './index.css';
import MainComponent from './components/MainComponent';

function App() {
  return (
    <div className="App">
      <MainComponent />
    </div>
  );
}

export default App;

GitHubへのアップロード

次に、プロジェクトをGitHubにアップロードします。

git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/<your-username>/dentaku.git
git branch -M main
git push -u origin main

Vercelへのデプロイ

Vercelにデプロイする手順は以下の通りです。

  1. Vercel CLIのインストール

    npm install -g vercel
    
  2. Vercelにログイン

    vercel login
    
  3. プロジェクトのデプロイ

    vercel
    

まとめ

以上の手順で、Reactを使ったモダンな電卓アプリケーション「Dentaku」を開発し、Vercelにデプロイすることができました。興味のある方はぜひこちらからアプリケーションをお試しください。

ご質問やフィードバックがあれば、コメント欄でお知らせください。最後まで読んでいただき、ありがとうございました!

以下は、「Dentaku」電卓アプリケーションのユーザーポリシーのドラフトです。


Dentaku ユーザーポリシー

はじめに

このユーザーポリシーは、Dentaku電卓アプリケーション(以下「本アプリ」)の利用に関するガイドラインを提供するものです。本アプリを利用することで、本ポリシーの内容に同意したものとみなされます。本アプリの提供者(以下「当社」)は、本ポリシーを随時変更することができます。変更があった場合は、最新のポリシーを本アプリまたは当社のウェブサイトで公開します。

1. 利用規約

1.1. 本アプリの利用

  • 本アプリは、無料で提供される計算機能をユーザーに提供します。
  • 本アプリの利用にあたり、ユーザーは本ポリシーを遵守するものとします。

1.2. 禁止事項

  • 本アプリの機能を悪用すること。
  • 他のユーザーまたは第三者に損害を与える行為。
  • 本アプリの正常な運営を妨げる行為。
  • 法令または公序良俗に反する行為。

2. プライバシー

2.1. 収集情報

  • 本アプリは、個人情報を収集しません。
  • ユーザーの利用状況や設定などの情報は、アプリのパフォーマンス改善のために匿名で収集される場合があります。

2.2. クッキーの使用

  • 本アプリはクッキーを使用しません。

3. 免責事項

3.1. サービスの提供

  • 当社は、本アプリの内容および提供するサービスが正確であるよう努めますが、その完全性、正確性、信頼性を保証するものではありません。
  • 当社は、本アプリの利用に関連して生じたいかなる損害についても、一切責任を負いません。

3.2. サービスの変更

  • 当社は、本アプリの内容や機能を予告なく変更、追加、または削除することがあります。

4. 知的財産権

  • 本アプリに関するすべてのコンテンツ、デザイン、ロゴ、トレードマーク、その他の知的財産は、当社またはそのライセンサーに帰属します。
  • ユーザーは、当社の事前の書面による承諾なしに、これらのコンテンツを複製、転用、配布、公開することはできません。

5. お問い合わせ

  • 本ポリシーに関するお問い合わせは、以下の連絡先までお願いいたします。

    連絡先: [お問い合わせフォームまたはメールアドレス]

6. 最終条項

  • 本ポリシーは、2024年7月29日から適用されます。
  • 本ポリシーの変更があった場合、変更後のポリシーは本アプリまたは当社のウェブサイトで公開されます。
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?