У каждого разработчика должен быть веб-сайт портфолио, чтобы продемонстрировать свои навыки и проекты. Мы создадим веб-сайт портфолио с помощью React.js и Tailwind CSS.
Настраивать
Чтобы сначала собрать проект, нам нужно настроить проект React.js и Tailwind CSS. Вы можете легко сделать это с помощью документации Tailwind.
Следуйте этим инструкциям из документации Tailwind, чтобы настроить проект.
Настройка проекта React и Tailwind
Я подожду, пока вы настроите проект.
Вы сделали!
давайте перейдем к следующему шагу.
Компоненты
Прежде чем мы начнем, нам нужно немного узнать о структуре проекта.
Поскольку это React, мы будем разбивать веб-сайты на крошечные компоненты.
У нас будет 6 компонентов:
- Заголовок
- Герой
- О
- Проекты
- Блог
- Нижний колонтитул
Примечание: все эти компоненты будут находиться в папке компонентов в папке src. И все компоненты будут импортированы в файл App.js.
Так:
import "./App.css"; import Header from "./components/Header"; import Hero from "./components/Hero"; import About from "./components/About"; import Projects from "./components/Projects"; import Blog from "./components/Blog"; import Contact from "./components/Contact"; import Footer from "./components/Footer"; function App() { return ( <> <Header /> <Hero /> <About /> <Projects /> <Blog /> <Contact /> <Footer /> </> ); } export default App;
№1. Заголовок
У них есть адаптивное мобильное меню с кнопкой-переключателем и настольное меню.
Мы будем использовать хук react useState для реализации эффекта переключения. А для иконок мы будем использовать библиотеку React Icons.
import React, { useState } from "react"; import { AiOutlineMenu, AiOutlineClose } from "react-icons/ai"; const Header = () => { const [toggle, setToggle] = useState(false); const handleToggle = () => setToggle(!toggle); return ( <header className="flex justify-between px-5 py-2 bg-primary text-white fixed w-full z-10"> <a href="/" className="logo text-2xl font-bold text-accent"> Amrin </a> {/* Desktop Nav */} <nav className="hidden md:block"> <ul className="flex"> <li> <a href="/#about">About</a> </li> <li> <a href="/#projects">Projects</a> </li> <li> <a href="/#blog">Blog</a> </li> <li> <a href="/#contact">Contact</a> </li> <li> <a href="#resume -link" target="_blank" without rel="noreferrer"> Resume </a> </li> </ul> </nav> {/* Mobile Nav */} <nav className={!toggle ? "mobile-nav left-[-100%]" : "mobile-nav left-0"} > <ul className="flex flex-col"> <li> <a href="/#about">About</a> </li> <li> <a href="/#projects">Projects</a> </li> <li> <a href="/#blog">Blog</a> </li> <li> <a href="/#contact">Contact</a> </li> <li> <a href="/#resume">Resume</a> </li> </ul> </nav> {/* Toggle button */} <button onClick={handleToggle} className="block md:hidden"> {!toggle ? <AiOutlineMenu size={30} /> : <AiOutlineClose size={30} />} </button> </header> ); }; export default Header;
Поскольку у нас есть собственная цветовая палитра, я решил создать несколько служебных классов для цветов.
/* color */ .bg-primary { background: #0F172A; } .bg-secondery { background: #1E293B; } .bg-accent { background: #7477FF; } .text-accent { color: #7477FF; }
Когда мы стилизовали мобильную навигацию с попутным ветром, она становилась очень запутанной и повторяющейся. Итак, я решил извлечь классы и поместить их в пользовательский класс с именем .mobile-nav в файле Style.css, например так:
.mobile-nav { @apply block md:hidden fixed top-10 py-2 w-full h-full bg-gray-900 duration-500; }
Также для стилизации тегов a внутри навигации мы использовали пользовательский CSS. Иначе мы бы много повторялись.
nav li a { @apply px-4 py-5 text-lg; } nav li a:hover { color: #7477FF; }
Теперь, когда мы закончили с навигацией, давайте перейдем к разделу героев.
№ 2. Герой
Герой состоит из двух разделов: информация о герое и изображение героя.
Я использовал иллюстрацию на герое-img, вы можете использовать свою картинку, если хотите.
import React from "react"; import HeroImg from "../assets/hero-img.png"; import { AiOutlineTwitter, AiOutlineYoutube, AiOutlineFacebook, } from "react-icons/ai"; const Hero = () => { return ( <section className="bg-primary px-5 text-white py-32"> <div className="container mx-auto grid md:grid-cols-2 items-center justify-center md:justify-between"> <div className="hero-info pb-5 md:pb-0"> <h1 className="text-4xl lg:text-6xl"> Hi, <br />I am <span className="text-accent">a</span>mrin <br /> Frontend Developer </h1> <p className="py-5"> I am proficient in JavaScript, React.js and Tailwind CSS </p> <div className="flex py-5 "> <a href="https://twitter.com/CoderAmrin" className="pr-4 inline-block text-accent hover:text-white" > {" "} <AiOutlineTwitter size={40} />{" "} </a> <a href="https://www.youtube.com/@coderamrin" className="pr-4 inline-block text-accent hover:text-white" > {" "} <AiOutlineYoutube size={40} />{" "} </a> <a href="https://www.facebook.com/CoderAmrin/" className="pr-4 inline-block text-accent hover:text-white" > {" "} <AiOutlineFacebook size={40} />{" "} </a> </div> <a href="/#projects" className=" btn bg-accent border-2 border-[#7477FF] text-white px-6 py-3 hover:bg-transparent" > See Projects </a> </div> <div className="hero-img"> <img src={HeroImg} alt="coding illustration" className="lgw-[80%] ml-auto" /> </div> </div> </section> ); }; export default Hero;
Чтобы оформить титул героя, мы использовали собственный шрифт и добавили нестандартные стили.
Примечание: вам нужно будет добавить этот шрифт в index.html вашего проекта. Это бесплатный шрифт Google.
/* hero */ h1 { font-family: 'Pacifico', cursive; line-height: 1.5 !important; }
№3. О
Раздел «О нас» состоит из двух частей, как и раздел «Герои».
В первом разделе будет вся информация о вас, о том, какие у вас навыки и чем вы занимаетесь. И другой раздел about-img. Это иллюстрация кодирования человека.
Примечание. Все изображения находятся в каталоге src/assets.
import React from "react"; import AboutImg from "../assets/about-img.png"; const About = () => { return ( <section className="bg-secondery text-white px-5 py-32" id="about"> <div className="container mx-auto grid md:grid-cols-2 items-center justify-center md:justify-between"> <div className="about-info"> <h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[180px] border-indigo-600 pb-2"> About Me </h2> <p className="pb-5"> Hi, My Name Is Rohima Akther everyone calls me Amrin. I am a Frontend Developer. I build beautifull websites with React and Tailwind CSS. </p> <p className="pb-5"> I am proficient in Frontend skills like React.js, Redux, Redux Tool Kit, Axios, Tailwind CSS, SaSS, Css3 and many more. </p> <p>In backend I know Node.js, Express.js, MongoDB, and Mongoose</p> <p> In my spare time I create YouTube videos and write blogs on my Blog. Where I talk about programming theory and build various projects. </p> </div> <div className="about-img"> <img src={AboutImg} alt="coding illustration" className="lgw-[80%] md:ml-auto" /> </div> </div> </section> ); }; export default About;
Для стилизации этого раздела мы не использовали никаких других пользовательских CSS, кроме цветовых классов.
№ 4. Проект
Раздел проекта немного сложен. Сначала у нас есть все проекты в массиве, так что нам не нужно повторяться. С этим набором проектов мы теперь можем легко отображать и визуализировать элемент проекта.
const projects = [ { img: devlog, title: "devlog", desc: " A multi author blog. Built with Node.js, MongoDB, React, Redux and Tailwind CSS ", live: "https://devlogg.onrender.com/", code: "https://github.com/Coderamrin/devlog", }, { img: uilogs, title: "uilogs", desc: "Free website template directory for SaaS and Degital Agency. Built with Bootstrap, JQuery and JavaScript", live: "https://uilogs.xyz/", code: "https://github.com/Coderamrin/html-templates", }, { img: cssProjects, title: "css projects", desc: "Frontend Mentor challange directory, solved with vanilla CSS", live: "https://build-10-css-projects.netlify.app/", code: "https://github.com/Coderamrin/build-10-css-projects", }, { img: getInspirred, title: "get Inspirred", desc: "Quote search app. Used Quotable API for the quotes and React, Redux on the frontend", live: "https://get-inspirred.netlify.app/", code: "https://github.com/Coderamrin/get-inspired", }, ];
Остальная часть компонента продукта это.
import React from "react"; import cssProjects from "../assets/cssprojects.png"; import devlog from "../assets/devlog.png"; import getInspirred from "../assets/get-inspirred.png"; import uilogs from "../assets/uilogs.png"; const Projects = () => { const projects = [...]; return ( <section className="bg-primary text-white px-5 py-32" id="projects"> <div className="container mx-auto grid md:grid-cols-2 items-center md:justify-between"> <div className="about-info mb-5"> <h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[180px] border-indigo-600 pb-2"> Projects </h2> <p className="pb-5"> These are some of my best projects. I have built these with React, MERN and vanilla CSS. Check them out. </p> </div> <div className="about-img"></div> </div> <div className="projects container mx-auto grid md:grid-cols-3 gap-10"> {projects.map((project, i) => { return ( <div className="relative" key={i}> <img src={project.img} alt={project.title} /> <div className="flex absolute left-0 right-0 top-[13px] bottom-0 mx-auto w-[90%] h-[90%] bg-primary opacity-0 duration-500 justify-center flex-col hover:opacity-100 "> <p className="py-5 text-center font-bold px-2 text-white"> {project.desc} </p> <div className="mx-auto"> <a href={project.live} className="px-5 py-2 bg-blue-500 hover:bg-blue-600 mr-5 font-bold" > Live </a> <a href={project.code} className="px-5 py-2 bg-blue-700 hover:bg-blue-800 font-bold" > Code </a> </div> </div> </div> ); })} </div> </section> ); }; export default Projects;
№ 5. Блог
Теперь раздел блога. Это почти как раздел проектов.
Массив элементов блога для сопоставления и отображения элементов.
Все остальное аналогично компонентам проектов.
import React from "react"; const Blog = () => { const post = [ { img: "https://res.cloudinary.com/practicaldev/image/fetch/s--AuZFJnr6--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a8okx5rxzuh5fojibsy3.png", title: "How to build a counter app with JavaScript", url: "https://dev.to/coderamrin/how-to-build-a-counter-app-with-javascript-439p", }, { img: "https://res.cloudinary.com/practicaldev/image/fetch/s--FsJZ6lhI--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gv7y2de8kalk9l0820ag.jpg", title: "JavaScript Ultimate Guide 02: The DOM", url: "https://dev.to/coderamrin/javascript-ultimate-guide-02-the-dom-3ho9", }, ]; return ( <section className="bg-primary text-white px-5 py-32" id="blog"> <div className="container mx-auto grid md:grid-cols-2 items-center md:justify-between"> <div className="about-info mb-5"> <h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[100px] border-indigo-600 pb-2"> Blogs </h2> <p className="pb-5">Some of my best blogs.</p> </div> <div></div> </div> <div className="projects container mx-auto grid md:grid-cols-2 gap-10"> {post.map((item) => { return ( <div> <img src={item.img} alt={item.title} /> <h3 className="py-5 text-2xl">{item.title}</h3> <a href={item.url} className=" btn bg-accent border-2 border-[#7477FF] text-white px-6 py-3 hover:bg-transparent" > Read More </a> </div> ); })} </div> </section> ); }; export default Blog;
№ 6. Контакты и нижний колонтитул
Наконец, раздел контактов и раздел нижнего колонтитула.
Эти разделы представляют собой просто несколько текстов в центре div. Нет, модный дизайн.
#Контакт
import React from "react"; const Contact = () => { return ( <section className="bg-secondery px-5 py-32" id="contact"> <div className="text-center md:w-[60%] mx-auto text-white"> <h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[200px] mx-auto border-indigo-600 pb-2"> Contact Me </h2> <p> I am currently open for a fulltime Frontend Developer role. If you want to discuss about that feel free to email me or call me. </p> <p className="py-2"> <span className="font-bold">Email:</span> [email protected] </p> <p className="py-2"> <span className="font-bold">Phone:</span> +88 01624-890723 </p> </div> </section> ); }; export default Contact;
#Нижний колонтитул
import React from "react"; const Footer = () => { return <div className="py-4 text-center bg-primary text-white "> © 2023 coderamrin all right reserved</div>; }; export default Footer;