본문 바로가기
[Spring Boot]/[JPA]

[JPA] Creative-stylish-portfolio (블로그 테마) 연습 예제

by 북방바다코끼리표범 2023. 11. 3.
stylish-portfolio easy_thema Blog 연습 예제 https://startbootstrap.com/theme/creative

기본 설정
# 설치 패키지 
# 1) 메뉴 라이브러리 설치
npm i react-router-dom
npm i @types/react-router-dom

# 2) 벡엔드 연동 라이브러리 설치
npm i axios

# 3) pre css 컴파일러 : sass
npm i sass

# 4) Material Page component 업그레이드 
# 과거 v4 -> v5 변경 설치
npm i @mui/material @emotion/react @emotion/styled

# 4-1) 소스에서 임포트 사용법 : <Pagination />
import Pagination from '@mui/material/Pagination';

# 5) typescript jquery, jqueryui type 넣기
# 5-1) typescript jquery 사용
npm i --save-dev @types/jquery
npm i --save-dev @types/jqueryui


# 6) npm i wowjs : npm 설치, GNU GPL 라이선스 v3
# npm i wowjs

# 6-1) import { WOW } from "wowjs"; import 하기
# import { WOW } from "wowjs";

# 7) npm install simplelightbox 설치
npm install simplelightbox

# 7-1) import SimpleLightbox from "simplelightbox" 설치
import SimpleLightbox from "simplelightbox"; // js
// todo: simplelightbox css import
import "simplelightbox/dist/simple-lightbox.css"; // css

# 8) bootstrap npm 설치
npm i bootstrap
npm i @types/bootstrap

# 8-1) bootstrap import
import * as bootstrap from "bootstrap";

# * 외부 라이브러리 타입이 없을 경우 처리 : 타입 설정
# 1) tsconfig.json 파일 - compilerOptions 속성에 아래 추가 : 프로젝트시작위치/types - 이 위치에 타입을 인식하게 하는 경로 설정
"typeRoots": ["./types", "./node_modules/@types"], // 보통 types 폴더를 만들어 타입 정의
# 2) types/외부라이브러리명/index.d.ts 파일 생성 후 아래 추가
declare module '외부라이브러리명';


오류 처리
테마 : npm i bootstrap
import * as bootstrap from "bootstrap";

일반 html -> 리액트 변경
1) class -> className
2)  labelfor -> label htmlFor
3) style="height: 10rem" => style={{height:10 + "rem"}}
4) textarea type속성(제거)
<!-- C:\Work\08_Pilot_Project\01_Blog\01_JPA\01_easy_thema\02_creative-gh\frontend-typescript\public\index.html -->

index.html 원본에서&nbsp; CSS link &&nbsp; JS 파일 들고오기

npm (설치)하는 코드는 주석 처리 ※ 하단&nbsp; startbootstrap 사이트에서 상용으로 팔기위한 목적으로 사용 / 주석처리
<!-- C:\Work\08_Pilot_Project\01_Blog\01_JPA\01_easy_thema\02_creative-gh\frontend-typescript\public\index.html -->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
    <!-- TODO : Favicon-->
    <link rel="icon" type="image/x-icon" href="assets/favicon.ico" />
    <!-- TODO : Bootstrap Icons-->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css"
      rel="stylesheet"
    />
    <!-- TODO : Google fonts-->
    <link
      href="https://fonts.googleapis.com/css?family=Merriweather+Sans:400,700"
      rel="stylesheet"
    />
    <link
      href="https://fonts.googleapis.com/css?family=Merriweather:400,300,300italic,400italic,700,700italic"
      rel="stylesheet"
      type="text/css"
    />
    <!-- TODO: SimpleLightbox plugin CSS link / npm (설치) 이동 / 주석처리  -->
    <!-- <link
      href="https://cdnjs.cloudflare.com/ajax/libs/SimpleLightbox/2.1.0/simpleLightbox.min.css"
      rel="stylesheet"
    /> -->
    <!-- TODO: Core theme CSS (includes Bootstrap) (개발자 작성) => src/assets/ 이동 / 주석처리  -->
    <!-- <link href="css/styles.css" rel="stylesheet" /> -->

  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
    <!-- TODO: Bootstrap core JS / 주석처리-->
    <!-- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script> -->
    <!-- TODO: SimpleLightbox plugin JS : npm (설치) / 주석처리-->
    <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/SimpleLightbox/2.1.0/simpleLightbox.min.js"></script> -->
    <!-- TODO: Core theme JS : 테마 개발자가 직접 만든 js => src/assets 이동 / 주석처리 -->
    <!-- <script src="js/scripts.js"></script> -->
    
    <!-- TODO: startbootstrap 사이트에서 상용으로 팔기위한 목적으로 사용 / 주석처리 -->
    <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
    <!-- * *                               SB Forms JS                               * *-->
    <!-- * * Activate your form at https://startbootstrap.com/solution/contact-forms * *-->
    <!-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *-->
    <!-- <script src="https://cdn.startbootstrap.com/sb-forms-latest.js"></script> -->
  </body>
</html>
scripts.js
/* C:\Work\08_Pilot_Project\01_Blog\01_JPA\01_easy_thema\02_creative-gh\frontend-typescript\src\assets\js\scripts.js */
/* C:\Work\08_Pilot_Project\01_Blog\01_JPA\01_easy_thema\02_creative-gh\frontend-typescript\src\assets\js\scripts.js */

/*!
* Start Bootstrap - Creative v7.0.7 (https://startbootstrap.com/theme/creative)
* Copyright 2013-2023 Start Bootstrap
* Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-creative/blob/master/LICENSE)
*/
//
// Scripts

// TODO : bootstrap npm 설치 (cdn 주석 막음)
import * as bootstrap from "bootstrap"

// TODO : simplelightbox import(npm 설치)
import SimpleLightbox from "simplelightbox";


/* window.addEventListener('DOMContentLoaded', event => {
 Navbar shrink function
var navbarShrink = function () { });*/
    // TODO : HTML => REACT export 받기(코드 수정)
    export default function initMain() {
        // Navbar shrink function
        var navbarShrink = function () {
          const navbarCollapsible = document.body.querySelector("#mainNav");
          if (!navbarCollapsible) {
            return;
          }
          if (window.scrollY === 0) {
            navbarCollapsible.classList.remove("navbar-shrink");
          } else {
            navbarCollapsible.classList.add("navbar-shrink");
          }
        };
      
        // Shrink the navbar
        navbarShrink();
      
        // Shrink the navbar when page is scrolled
        document.addEventListener("scroll", navbarShrink);
      
        // Activate Bootstrap scrollspy on the main nav element
        const mainNav = document.body.querySelector("#mainNav");
        if (mainNav) {
          new bootstrap.ScrollSpy(document.body, {
            target: "#mainNav",
            rootMargin: "0px 0px -40%",
          });
        }
      
        // Collapse responsive navbar when toggler is visible
        const navbarToggler = document.body.querySelector(".navbar-toggler");
        const responsiveNavItems = [].slice.call(
          document.querySelectorAll("#navbarResponsive .nav-link")
        );
        responsiveNavItems.map(function (responsiveNavItem) {
          responsiveNavItem.addEventListener("click", () => {
            if (window.getComputedStyle(navbarToggler).display !== "none") {
              navbarToggler.click();
            }
          });
        });
      
        // Activate SimpleLightbox plugin for portfolio items
      //  사용법 : new SimpleLightbox(선택자)
        new SimpleLightbox("#portfolio a.portfolio-box");
      }

bootstrap npm 설치 (cdn 주석 막음),  simplelightbox import(npm 설치) import 해서 해결
Home.tsx
// C:\Work\08_Pilot_Project\01_Blog\01_JPA\01_easy_thema\02_creative-gh\frontend-typescript\src\pages\Home.tsx : rfce
- simplelightbox css import
- 이미지 경로 : require 사용 ../ 경로 수정
src={require("../assets/img/portfolio/thumbnails/2.jpg")}
href={require("../assets/img/portfolio/fullsize/2.jpg")}

 

더보기

// C:\Work\08_Pilot_Project\01_Blog\01_JPA\01_easy_thema\02_creative-gh\frontend-typescript\src\pages\Home.tsx : rfce

import React, { useEffect } from "react";

import initMain from "../assets/js/scripts";

 

/* styles.css import : react 의 최고 부모 컴포넌트(App.tsx) */

import "../assets/css/styles.css"

 

// TODO: simplelightbox css import

import "simplelightbox/dist/simple-lightbox.css";

 

export default function Home() {

  // 화면이 뜰 때 실행되는 이벤트

  useEffect(() => {

    initMain(); // 사이트 메뉴 실행

  }, []);

 

  return (

    // TODO: HTML

    <div id="page-top">

      {/* <!-- Navigation--> */}

      <nav

        className="navbar navbar-expand-lg navbar-light fixed-top py-3"

        id="mainNav"

      >

        <div className="container px-4 px-lg-5">

          <a className="navbar-brand" href="#page-top">

            Start Bootstrap

          </a>

          <button

            className="navbar-toggler navbar-toggler-right"

            type="button"

            data-bs-toggle="collapse"

            data-bs-target="#navbarResponsive"

            aria-controls="navbarResponsive"

            aria-expanded="false"

            aria-label="Toggle navigation"

          >

            <span className="navbar-toggler-icon"></span>

          </button>

          <div className="collapse navbar-collapse" id="navbarResponsive">

            <ul className="navbar-nav ms-auto my-2 my-lg-0">

              <li className="nav-item">

                <a className="nav-link" href="#about">

                  About

                </a>

              </li>

              <li className="nav-item">

                <a className="nav-link" href="#services">

                  Services

                </a>

              </li>

              <li className="nav-item">

                <a className="nav-link" href="#portfolio">

                  Portfolio

                </a>

              </li>

              <li className="nav-item">

                <a className="nav-link" href="#contact">

                  Contact

                </a>

              </li>

            </ul>

          </div>

        </div>

      </nav>

      {/* <!-- Masthead--> */}

      <header className="masthead">

        <div className="container px-4 px-lg-5 h-100">

          <div className="row gx-4 gx-lg-5 h-100 align-items-center justify-content-center text-center">

            <div className="col-lg-8 align-self-end">

              <h1 className="text-white font-weight-bold">

                Your Favorite Place for Free Bootstrap Themes

              </h1>

              <hr className="divider" />

            </div>

            <div className="col-lg-8 align-self-baseline">

              <p className="text-white-75 mb-5">

                Start Bootstrap can help you build better websites using the

                Bootstrap framework! Just download a theme and start

                customizing, no strings attached!

              </p>

              <a className="btn btn-primary btn-xl" href="#about">

                Find Out More

              </a>

            </div>

          </div>

        </div>

      </header>

      {/* <!-- About--> */}

      <section className="page-section bg-primary" id="about">

        <div className="container px-4 px-lg-5">

          <div className="row gx-4 gx-lg-5 justify-content-center">

            <div className="col-lg-8 text-center">

              <h2 className="text-white mt-0">We've got what you need!</h2>

              <hr className="divider divider-light" />

              <p className="text-white-75 mb-4">

                Start Bootstrap has everything you need to get your new website

                up and running in no time! Choose one of our open source, free

                to download, and easy to use themes! No strings attached!

              </p>

              <a className="btn btn-light btn-xl" href="#services">

                Get Started!

              </a>

            </div>

          </div>

        </div>

      </section>

      {/* <!-- Services--> */}

      <section className="page-section" id="services">

        <div className="container px-4 px-lg-5">

          <h2 className="text-center mt-0">At Your Service</h2>

          <hr className="divider" />

          <div className="row gx-4 gx-lg-5">

            <div className="col-lg-3 col-md-6 text-center">

              <div className="mt-5">

                <div className="mb-2">

                  <i className="bi-gem fs-1 text-primary"></i>

                </div>

                <h3 className="h4 mb-2">Sturdy Themes</h3>

                <p className="text-muted mb-0">

                  Our themes are updated regularly to keep them bug free!

                </p>

              </div>

            </div>

            <div className="col-lg-3 col-md-6 text-center">

              <div className="mt-5">

                <div className="mb-2">

                  <i className="bi-laptop fs-1 text-primary"></i>

                </div>

                <h3 className="h4 mb-2">Up to Date</h3>

                <p className="text-muted mb-0">

                  All dependencies are kept current to keep things fresh.

                </p>

              </div>

            </div>

            <div className="col-lg-3 col-md-6 text-center">

              <div className="mt-5">

                <div className="mb-2">

                  <i className="bi-globe fs-1 text-primary"></i>

                </div>

                <h3 className="h4 mb-2">Ready to Publish</h3>

                <p className="text-muted mb-0">

                  You can use this design as is, or you can make changes!

                </p>

              </div>

            </div>

            <div className="col-lg-3 col-md-6 text-center">

              <div className="mt-5">

                <div className="mb-2">

                  <i className="bi-heart fs-1 text-primary"></i>

                </div>

                <h3 className="h4 mb-2">Made with Love</h3>

                <p className="text-muted mb-0">

                  Is it really open source if it's not made with love?

                </p>

              </div>

            </div>

          </div>

        </div>

      </section>

      {/* <!-- Portfolio--> */}

      <div id="portfolio">

        <div className="container-fluid p-0">

          <div className="row g-0">

            <div className="col-lg-4 col-sm-6">

              <a

                className="portfolio-box"

                href={require("../assets/img/portfolio/fullsize/1.jpg")}

                title="Project Name"

              >

                <img

                  className="img-fluid"

                  src={require("../assets/img/portfolio/thumbnails/1.jpg")}

                  alt="..."

                />

                <div className="portfolio-box-caption">

                  <div className="project-category text-white-50">Category</div>

                  <div className="project-name">Project Name</div>

                </div>

              </a>

            </div>

            <div className="col-lg-4 col-sm-6">

              <a

                className="portfolio-box"

                href={require("../assets/img/portfolio/fullsize/2.jpg")}

                title="Project Name"

              >

                <img

                  className="img-fluid"

                  src={require("../assets/img/portfolio/thumbnails/2.jpg")}

                  alt="..."

                />

                <div className="portfolio-box-caption">

                  <div className="project-category text-white-50">Category</div>

                  <div className="project-name">Project Name</div>

                </div>

              </a>

            </div>

            <div className="col-lg-4 col-sm-6">

              <a

                className="portfolio-box"

                href={require("../assets/img/portfolio/fullsize/3.jpg")}

                title="Project Name"

              >

                <img

                  className="img-fluid"

                  src={require("../assets/img/portfolio/thumbnails/3.jpg")}

                  alt="..."

                />

                <div className="portfolio-box-caption">

                  <div className="project-category text-white-50">Category</div>

                  <div className="project-name">Project Name</div>

                </div>

              </a>

            </div>

            <div className="col-lg-4 col-sm-6">

              <a

                className="portfolio-box"

                href={require("../assets/img/portfolio/fullsize/4.jpg")}

                title="Project Name"

              >

                <img

                  className="img-fluid"

                  src={require("../assets/img/portfolio/thumbnails/4.jpg")}

                  alt="..."

                />

                <div className="portfolio-box-caption">

                  <div className="project-category text-white-50">Category</div>

                  <div className="project-name">Project Name</div>

                </div>

              </a>

            </div>

            <div className="col-lg-4 col-sm-6">

              <a

                className="portfolio-box"

                href={require("../assets/img/portfolio/fullsize/5.jpg")}

                title="Project Name"

              >

                <img

                  className="img-fluid"

                  src={require("../assets/img/portfolio/thumbnails/5.jpg")}

                  alt="..."

                />

                <div className="portfolio-box-caption">

                  <div className="project-category text-white-50">Category</div>

                  <div className="project-name">Project Name</div>

                </div>

              </a>

            </div>

            <div className="col-lg-4 col-sm-6">

              <a

                className="portfolio-box"

                href={require("../assets/img/portfolio/fullsize/6.jpg")}

                title="Project Name"

              >

                <img

                  className="img-fluid"

                  src={require("../assets/img/portfolio/thumbnails/6.jpg")}

                  alt="..."

                />

                <div className="portfolio-box-caption p-3">

                  <div className="project-category text-white-50">Category</div>

                  <div className="project-name">Project Name</div>

                </div>

              </a>

            </div>

          </div>

        </div>

      </div>

      {/* <!-- Call to action--> */}

      <section className="page-section bg-dark text-white">

        <div className="container px-4 px-lg-5 text-center">

          <h2 className="mb-4">Free Download at Start Bootstrap!</h2>

          <a

            className="btn btn-light btn-xl"

            href="https://startbootstrap.com/theme/creative/"

          >

            Download Now!

          </a>

        </div>

      </section>

      {/* <!-- Contact--> */}

      <section className="page-section" id="contact">

        <div className="container px-4 px-lg-5">

          <div className="row gx-4 gx-lg-5 justify-content-center">

            <div className="col-lg-8 col-xl-6 text-center">

              <h2 className="mt-0">Let's Get In Touch!</h2>

              <hr className="divider" />

              <p className="text-muted mb-5">

                Ready to start your next project with us? Send us a messages and

                we will get back to you as soon as possible!

              </p>

            </div>

          </div>

          <div className="row gx-4 gx-lg-5 justify-content-center mb-5">

            <div className="col-lg-6">

              {/* <!-- * * * * * * * * * * * * * * *--> */}

              {/* <!-- * * SB Forms Contact Form * *--> */}

              {/* <!-- * * * * * * * * * * * * * * *--> */}

              {/* <!-- This form is pre-integrated with SB Forms.--> */}

              {/* <!-- To make this form functional, sign up at--> */}

              {/* https://startbootstrap.com/solution/contact-forms--> */}

              {/* <!-- to get an API token!--> */}

              <form id="contactForm" data-sb-form-api-token="API_TOKEN">

                {/* <!-- Name input--> */}

                <div className="form-floating mb-3">

                  <input

                    className="form-control"

                    id="name"

                    type="text"

                    placeholder="Enter your name..."

                    data-sb-validations="required"

                  />

                  <label htmlFor="name">Full name</label>

                  <div

                    className="invalid-feedback"

                    data-sb-feedback="name:required"

                  >

                    A name is required.

                  </div>

                </div>

                {/* <!-- Email address input--> */}

                <div className="form-floating mb-3">

                  <input

                    className="form-control"

                    id="email"

                    type="email"

                    placeholder="name@example.com"

                    data-sb-validations="required,email"

                  />

                  <label htmlFor="email">Email address</label>

                  <div

                    className="invalid-feedback"

                    data-sb-feedback="email:required"

                  >

                    An email is required.

                  </div>

                  <div

                    className="invalid-feedback"

                    data-sb-feedback="email:email"

                  >

                    Email is not valid.

                  </div>

                </div>

                {/* <!-- Phone number input--> */}

                <div className="form-floating mb-3">

                  <input

                    className="form-control"

                    id="phone"

                    type="tel"

                    placeholder="(123) 456-7890"

                    data-sb-validations="required"

                  />

                  <label htmlFor="phone">Phone number</label>

                  <div

                    className="invalid-feedback"

                    data-sb-feedback="phone:required"

                  >

                    A phone number is required.

                  </div>

                </div>

                {/* <!-- Message input--> */}

                <div className="form-floating mb-3">

                  <input

                    className="form-control"

                    id="message"

                    type="text"

                    placeholder="Enter your message here..."

                    style={{ height: 10 + "rem" }}

                    data-sb-validations="required"

                  />

                  <label htmlFor="message">Message</label>

                  <div

                    className="invalid-feedback"

                    data-sb-feedback="message:required"

                  >

                    A message is required.

                  </div>

                </div>

                {/* <!-- Submit success message--> */}

                {/* <!----> */}

                {/* <!-- This is what your users will see when the form--> */}

                {/* <!-- has successfully submitted--> */}

                <div className="d-none" id="submitSuccessMessage">

                  <div className="text-center mb-3">

                    <div className="fw-bolder">Form submission successful!</div>

                    To activate this form, sign up at

                    <br />

                    <a href="https://startbootstrap.com/solution/contact-forms">

                      https://startbootstrap.com/solution/contact-forms

                    </a>

                  </div>

                </div>

                {/* <!-- Submit error message--> */}

                {/* <!----> */}

                {/* <!-- This is what your users will see when there is--> */}

                {/* <!-- an error submitting the form--> */}

                <div className="d-none" id="submitErrorMessage">

                  <div className="text-center text-danger mb-3">

                    Error sending message!

                  </div>

                </div>

                {/* <!-- Submit Button--> */}

                <div className="d-grid">

                  <button

                    className="btn btn-primary btn-xl disabled"

                    id="submitButton"

                    type="submit"

                  >

                    Submit

                  </button>

                </div>

              </form>

            </div>

          </div>

          <div className="row gx-4 gx-lg-5 justify-content-center">

            <div className="col-lg-4 text-center mb-5 mb-lg-0">

              <i className="bi-phone fs-2 mb-3 text-muted"></i>

              <div>+1 (555) 123-4567</div>

            </div>

          </div>

        </div>

      </section>

      {/* <!-- Footer--> */}

      <footer className="bg-light py-5">

        <div className="container px-4 px-lg-5">

          <div className="small text-center text-muted">

            Copyright &copy; 2023 - Company Name

          </div>

        </div>

      </footer>

 

      {/* TODO: 하위 내용 다 삭제 */}

      {/* <!-- Bootstrap core JS--> */}

      {/* 삭제함 */}

      {/* <!-- SimpleLightbox plugin JS--> */}

      {/* 삭제함 */}

      {/* <!-- Core theme JS--> */}

 

    </div>

  );

}

리액트로 변환하여 화면 구현 완료


외부 lib npm으로 설치를 우선시 하고  타입 없을  때 import 위치를 찾아서 설정,

이미지에 경우에도 2가지 방법 중 택
1. 이미지 경로 import  방법 :
// C:\Work\08_Pilot_Project\01_Blog\00_JSLIB\frontend-npx\src\pages\SimpleLightboxCom.tsx
2. 이미지 JavaScript 키워드 require 방법 :
// C:\Work\08_Pilot_Project\01_Blog\00_JSLIB\frontend-npx\src\pages\OwlCarouselComExam.tsx