React でアプリを作成しました【13】【Portfolio Website Using Tailwind CSS】

## 環境の準備
①ターミナルでreactアプリケーションを作成する。

```
$ npx create-react-app <プロジェクト名>
% cd <プロジェクト名>
% npm start
```

② 必要なパッケージをインストールする。

```
$ npm install -D tailwindcss postcss autoprefixer
$ npx tailwindcss init -p
$ npm install react-icons
$ npm install react-scroll
```

③ 不必要なファイルを削除する。

```
App.css
App.test.js
logo.svg
reportWebVitals.js
setupTests.js
```

## コンポーネント・ファイル構成

```
 src
  ├── assets //画像を入れるファイル
  └── components
       ├── About.jsx
       ├── Contact.jsx
       ├── Home.jsx
       ├── Nabvar.jsx
       ├── Skills.jsx
       └── Work.jsx
  ├── App.js
  ├── index.css
  └── index.js
 ├── postcss.config.js
 ├── tailwind.config.js
```

公式サイト:[Tailwind CSS](https://tailwindcss.com/)


```src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

```postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
```

```tailwind.config.js
module.exports = {
  content: ["./src/**/*.{js,jsx,ts,tsx}"],
  theme: {
    extend: {},
  },
  plugins: [],
};
```

## 「Getform」とは

「Getform」は、WebサイトやWebアプリに簡単にフォーム送信を実装できるサービス。
サーバーの設定とか難しいバックエンドの作成も不要。
[Getform.ioの使い方をまとめてみた](https://qiita.com/kanfutrooper/items/107a82ce342c44edb4f7)

### src/components/About.jsx

```src/components/About.jsx
import React from "react";

const About = () => {
  return (
    <div name="about" className="w-full  h-screen bg-[#0a192f] text-white">
      <div className="flex flex-col justify-center items-center w-full h-full">
        <div className="max-w-[1000px] w-full grid grid-cols-2 gap-8">
          <div className="sm:text-right pb-8 pl-4">
            <p className="text-4xl font-bold inline border-b-4 border-green-500">
              About
            </p>
          </div>
          <div></div>
        </div>
        <div className="max-w-[1000px]  w-full grid sm:grid-cols-2 gap-8 px-4">
          <div className="sm:text-left text-2xl font-bold">
            <p>
              Hi. I'm Masaomi kito, nice to meet you. Please take a look around.
            </p>
          </div>
          <div className="sm:text-left text-2xl font-bold">
            <p>
              I am passionate abaut building excellent software that improves
              the lives of those around me.
            </p>
          </div>
        </div>
      </div>
    </div>
  );
};

export default About;
```
### src/components/Contact.jsx

```src/components/Contact.jsx
import React from "react";

const Contact = () => {
  return (
    <div
      name="contact"
      className="w-full h-full bg-[#0a192f] flex justify-center items-center p-4"
    >
      <form
        method="POST"

//「Getform」と接続
        action="https://getform.io/f/18a7110a-c49a-4193-8731-035c074efacd"
        className="flex flex-col max-w-[600px] w-full"
      >
        <div className="pb-8">
          <p className="text-4xl font-bold inline border-b-4 border-green-500 text-white">
            Contact
          </p>
          <p className="text-white py-4">
            Submit the from below or shoot me an email
          </p>
        </div>
        <input
          className="text-white p-2"
          type="text"
          placeholder="Name"
          name="name"
        />
        <input
          className="my-4 p-2 text-white"
          type="email"
          placeholder="Email"
          name="email"
        />
        <textarea
          className="text-white p-2"
          name="message"
          rows="10"
          placeholder="Message"
        ></textarea>
        <button className="text-white border-2 hover:bg-green-500 px-4 py-3 my-8 mx-auto flex items-center">
          Let's Collaborate
        </button>
      </form>
    </div>
  );
};

export default Contact;
```
##### src/components/Home.jsx

```src/components/Home.jsx
import { HiArrowNarrowRight } from "react-icons/hi";

const Home = () => {
  return (
    <div name="home" className="w-full h-screen bg-[#0a192f]">
      <div className="max-w-[1000px] mx-auto px-8 flex flex-col justify-center h-full">
        <p className="text-2xl sm:text-7x1 font-bold text-green-500">
          {" "}
          Hi , my name is
        </p>
        <h1 className="text-5xl sm:text-7x1 font-bold text-white">
          Masaomi Kito
        </h1>
        <h2 className="text-3xl sm:text-7x1 font-bold text-white">
          I'm a Full Stack Developer.
        </h2>
        <p className="text-[#fff] py-4 max-w-[700px]">
          I'm a full-stack developer specializing in building(and occasionally
          designing) exceptional digital experiences. Currently, I'm focused on
          building responsive full-stack web applications.
        </p>
        <div>
          <button className="text-white group border-2 px-6 py-3 my-2 flex items-center hover:bg-green-500 hover:border-green-500">
            View Work
            <span className="group:hover:rotate-90 duration-300">
              <HiArrowNarrowRight className="ml-3" />
            </span>
          </button>
        </div>
      </div>
    </div>
  );
};

export default Home;
```

### src/components/Navbar.jsx

```src/components/Navbar.jsx
import React, { useState } from "react";
import { FaBars, FaTimes, FaGithub, FaInstagram, FaBlog } from "react-icons/fa";
import { HiOutlineMail } from "react-icons/hi";
import { BsFillPersonLinesFill } from "react-icons/bs";
//import Logo1 from "../assets/logo1.png";
import Logo5 from "../assets/logo5.png";
import { Link } from "react-scroll";

const Navbar = () => {
  const [nav, setNav] = useState(false);
  const handleClick = () => setNav(!nav);
  return (
    <div className="fixed w-full h-[80px] flex justify-between items-center px-4 bg-[#0a192f] text-white">
      <div>
        {/* <img src={Logo1} alt="Logo image" style={{ width: "30px" }} /> */}
        <img src={Logo5} alt="Logo5 image" style={{ width: "40px" }} />
      </div>

      <ul className="hidden md:flex">
        <li>
          <Link to="home" smooth={true} duration={500}>
            Home
          </Link>
        </li>
        <li>
          <Link to="about" smooth={true} duration={500}>
            About
          </Link>
        </li>
        <li>
          <Link to="skills" smooth={true} duration={500}>
            Skills
          </Link>
        </li>
        <li>
          <Link to="work" smooth={true} duration={500}>
            Work
          </Link>
        </li>
        <li>
          <Link to="contact" smooth={true} duration={500}>
            Contact
          </Link>
        </li>
      </ul>

      <div onClick={handleClick} className="md:hidden z-10">
        {!nav ? <FaBars /> : <FaTimes />}
      </div>
      <ul
        className={
          !nav
            ? "hidden"
            : "absolute top-0 left-0 w-full h-screen bg-[#0a192f] flex-col justify-center items-center"
        }
      >
        <li className="py-6 text-4xl">
          <Link onClick={handleClick} to="home" smooth={true} duration={500}>
            Home
          </Link>
        </li>
        <li className="py-6 text-4xl">
          <Link onClick={handleClick} to="about" smooth={true} duration={500}>
            About
          </Link>
        </li>
        <li className="py-6 text-4xl">
          <Link onClick={handleClick} to="skills" smooth={true} duration={500}>
            Skills
          </Link>
        </li>
        <li className="py-6 text-4xl">
          <Link onClick={handleClick} to="work" smooth={true} duration={500}>
            Work
          </Link>
        </li>
        <li className="py-6 text-4xl">
          <Link onClick={handleClick} to="contact" smooth={true} duration={500}>
            Contact
          </Link>
        </li>
      </ul>
      <div className="hidden lg:flex fixed flex-col top-[35%] left-0">
        <ul>
          <li className="w-[160px] h-[60px] flex justify-between items-center ml-[-100px] hover:ml-[-10px] duration-300 bg-green-500">
            <a
              className="flex justify-between items-center w-full text-white"
              href="/"
            >
              Instagram <FaInstagram size={30} />
            </a>
          </li>
          <li className="w-[160px] h-[60px] flex justify-between items-center ml-[-100px] hover:ml-[-10px] duration-300 bg-green-500">
            <a
              className="flex justify-between items-center w-full text-white"
              href="/"
            >
              Github <FaGithub size={30} />
            </a>
          </li>
          <li className="w-[160px] h-[60px] flex justify-between items-center ml-[-100px] hover:ml-[-10px] duration-300 bg-green-500">
            <a
              className="flex justify-between items-center w-full text-white"
              href="/"
            >
              Blog <FaBlog size={30} />
            </a>
          </li>
          <li className="w-[160px] h-[60px] flex justify-between items-center ml-[-100px] hover:ml-[-10px] duration-300 bg-green-500">
            <a
              className="flex justify-between items-center w-full text-white"
              href="/"
            >
              Email <HiOutlineMail size={30} />
            </a>
          </li>
          <li className="w-[160px] h-[60px] flex justify-between items-center ml-[-100px] hover:ml-[-10px] duration-300 bg-green-500">
            <a
              className="flex justify-between items-center w-full text-white"
              href="/"
            >
              Resume <BsFillPersonLinesFill size={30} />
            </a>
          </li>
        </ul>
      </div>
    </div>
  );
};

export default Navbar;
```

### src/components/Skills.jsx

```src/components/Skills.jsx
import React from "react";
import HTML from "../assets/html.png";
import CSS from "../assets/css.png";
import JAVASCRIPT from "../assets/javascript.png";
import REACT from "../assets/react.png";
import FIREBASE from "../assets/firebase.png";
import REACTROUTER from "../assets/react-router.png";
import REDUXTOOLKIT from "../assets/reduxtoolkit.png";
import MATERIALUI from "../assets/material-ui.png";
import TAILWINDCSS from "../assets/tailwindcss.png";
import RUBY from "../assets/ruby.png";
import RAILS from "../assets/rails.png";
import BOOTSTRAP from "../assets/bootstrap.png";
import GITHUB from "../assets/github.png";
import FIGMA from "../assets/figma.png";

const Skills = () => {
  return (
    <div name="skills" className="w-full h-screen bg-[#0a192f] text-white">
      <div className="max-w-[1000px] mx-auto p-4 flex flex-col justify-center w-full h-full">
        <div>
          <p className="text-4xl font-bold inline border-b-4 border-green-500">
            Skills
          </p>
          <p className="py-4">These are the technologies I've worked with</p>
        </div>

        <div className="w-full grid grid-cols-2 sm:grid-cols-4 gap-4 text-center py-8">
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img className="w-20 mx-auto" src={HTML} alt="HTML icon" />
            <p className="my-4">HTML</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img className="w-20 mx-auto" src={CSS} alt="HTML icon" />
            <p className="my-4">CSS</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img className="w-20 mx-auto" src={JAVASCRIPT} alt="HTML icon" />
            <p className="my-4">JAVASCRIPT</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img className="w-20 mx-auto" src={REACT} alt="HTML icon" />
            <p className="my-4">REACT</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img className="w-20 mx-auto" src={FIREBASE} alt="HTML icon" />
            <p className="my-4">FIREBASE</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              className="w-20 mx-auto"
              src={REACTROUTER}
              alt="REACTROUTER icon"
            />
            <p className="my-4">REACT-ROUTER</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              className="w-20 mx-auto"
              src={REDUXTOOLKIT}
              alt="REDUXTOOLKIT icon"
            />
            <p className="my-4">REDUXTOOLKIT</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              className="w-20 mx-auto"
              src={MATERIALUI}
              alt="MATERIALUI icon"
            />
            <p className="my-4">MATERIAL-UI</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              className="w-20 mx-auto"
              src={TAILWINDCSS}
              alt="TAILWINDCSS icon"
            />
            <p className="my-4">TAILWINDCSS</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img className="w-20 mx-auto" src={RUBY} alt="RUBY icon" />
            <p className="my-4">RUBY</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img className="w-20 mx-auto" src={RAILS} alt="RAILS icon" />
            <p className="my-4">RUBY-ON-RAILS</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img
              className="w-20 mx-auto"
              src={BOOTSTRAP}
              alt="BOOTSTRAP icon"
            />
            <p className="my-4">BOOTSTRAP</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img className="w-20 mx-auto" src={GITHUB} alt="GITHUB icon" />
            <p className="my-4">GITHUB</p>
          </div>
          <div className="shadow-md shadow-[#040c16] hover:scale-110 duration-500">
            <img className="w-20 mx-auto" src={FIGMA} alt="GITHUB icon" />
            <p className="my-4">FIGMA</p>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Skills;
```

### src/components/Work.jsx

```src/components/Work.jsx
import React from "react";
//import WorkImg from "../assets/WorkImg.jpeg";
//import realEstate from "../assets/realestate.jpeg";

const Work = () => {
  return (
    <div name="work" className="w-full md:h-screen text-white bg-[#0a192f]">
      <div className="max-w-[1000px] mx-auto p-4 flex flex-col justify-center w-full h-full">
        <div className="pb-8">
          <p className="text-4xl font-bold inline border-b-4 text-white border-green-500">
            Work
          </p>
          <p className="py-6">Check out some of my recent work</p>
        </div>

        <div className="grid sm:grid-cols-2 md:grid-cols-3 gap-4">
          <div //style={{ backgroundImage: `url(${WorkImg})` }}
            className="shadow-lg shadow-[#040c16] group container rounded-md flex justify-center items-center mx-auto content-div"
          >
            <div className="opacity-0 group-hover:opacity-100">
              <span className="text-2xl font-bold text-white tracking-wider">
                React JS Application
              </span>
              <div className="pt-8 text-center">
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Demo
                  </button>
                </a>
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Code
                  </button>
                </a>
              </div>
            </div>
          </div>
          <div //style={{ backgroundImage: `url(${WorkImg})` }}
            className="shadow-lg shadow-[#040c16] group container rounded-md flex justify-center items-center mx-auto content-div"
          >
            <div className="opacity-0 group-hover:opacity-100">
              <span className="text-2xl font-bold text-white tracking-wider">
                React JS Application
              </span>
              <div className="pt-8 text-center">
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Demo
                  </button>
                </a>
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Code
                  </button>
                </a>
              </div>
            </div>
          </div>
          <div //style={{ backgroundImage: `url(${WorkImg})` }}
            className="shadow-lg shadow-[#040c16] group container rounded-md flex justify-center items-center mx-auto content-div"
          >
            <div className="opacity-0 group-hover:opacity-100">
              <span className="text-2xl font-bold text-white tracking-wider">
                React JS Application
              </span>
              <div className="pt-8 text-center">
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Demo
                  </button>
                </a>
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Code
                  </button>
                </a>
              </div>
            </div>
          </div>
          <div //style={{ backgroundImage: `url(${WorkImg})` }}
            className="shadow-lg shadow-[#040c16] group container rounded-md flex justify-center items-center mx-auto content-div"
          >
            <div className="opacity-0 group-hover:opacity-100">
              <span className="text-2xl font-bold text-white tracking-wider">
                React JS Application
              </span>
              <div className="pt-8 text-center">
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Demo
                  </button>
                </a>
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Code
                  </button>
                </a>
              </div>
            </div>
          </div>
          <div //style={{ backgroundImage: `url(${WorkImg})` }}
            className="shadow-lg shadow-[#040c16] group container rounded-md flex justify-center items-center mx-auto content-div"
          >
            <div className="opacity-0 group-hover:opacity-100">
              <span className="text-2xl font-bold text-white tracking-wider">
                React JS Application
              </span>
              <div className="pt-8 text-center">
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Demo
                  </button>
                </a>
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Code
                  </button>
                </a>
              </div>
            </div>
          </div>
          <div //style={{ backgroundImage: `url(${WorkImg})` }}
            className="shadow-lg shadow-[#040c16] group container rounded-md flex justify-center items-center mx-auto content-div"
          >
            <div className="opacity-0 group-hover:opacity-100">
              <span className="text-2xl font-bold text-white tracking-wider">
                React JS Application
              </span>
              <div className="pt-8 text-center">
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Demo
                  </button>
                </a>
                <a href="/">
                  <button className="text-center rounded-lg px-4 py-3 m-2 bg-white text-black font-bold text-lg">
                    Code
                  </button>
                </a>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Work;
```

### src/App.js

```src/App.js
import About from "./components/About";
import Contact from "./components/Contact";
import Home from "./components/Home";
import Navbar from "./components/Navbar";
import Skills from "./components/Skills";
import Work from "./components/Work";

function App() {
  return (
    <div>
      <Navbar />
      <Home />
      <About />
      <Skills />
      <Work />
      <Contact />
    </div>
  );
}
export default App;
```

### src/index.css

```src/index.css
@tailwind base;
@tailwind components;
@tailwind utilities;

@import url("https://fonts.googleapis.com/css2?family=Raleway:wght@300;400;500;600;700;800;900&display=swap");

@layer base {
  body {
    @apply font-[Raleway];
  }
  li {
    @apply px-4;
    @apply cursor-pointer;
  }
}

.content-div {
  background-repeat: no-repeat;
  background-size: cover;
  background-position: center;
  height: 250px;
}

.content-div:hover {
  background-image: linear-gradient(
    to right,
    rgba(65, 247, 41, 0.932),
    hsla(108, 89%, 44%, 0.849)
  ) !important;
}
```

### src/index.js

```src/index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);
```

## 参考サイト
[Build a REACT JS Portfolio Website Using Tailwind CSS - Get Hired!](https://www.youtube.com/watch?v=2kg0z1qNrkw)
[プログラムなしでお問い合わせフォームを作れる「Getform」](http://web-marketing.zako.org/web-tools/getform.html)
[【フォーム送信を実装】Getform.ioの使い方を解説【HTMLのみでOK】](https://ralacode.com/blog/post/create-contact-form-with-getform-io-in-react/#:~:text=%E3%80%8CGetform%E3%80%8D%E3%81%AF%E3%80%81Web%E3%82%B5%E3%82%A4%E3%83%88,%E3%82%92%E5%AE%9F%E8%A3%85%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%A7%E3%81%99%E3%80%82&text=%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%81%A8%E3%81%8B%E9%9B%A3%E3%81%97%E3%81%84%E3%83%90%E3%83%83%E3%82%AF%E3%82%A8%E3%83%B3%E3%83%89%E3%81%AE%E4%BD%9C%E6%88%90%E3%82%82%E4%B8%8D%E8%A6%81%E3%80%82)