https://startbootstrap.com/ 무료 템플릿 다운
사용한 툴
|
// # 설치 패키지 # 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 '외부라이브러리명'; |
bootstrap이 적용되지 않을 시
오류 처리 테마 : 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 원본에서 CSS link & JS 파일 들고오기
npm (설치)하는 코드는 주석 처리
※ 하단 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")}
Home.tsx 코드
더보기
// 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"
>
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--> */}
{/* <!-- 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>
</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 © 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
'[Spring Boot] > [JPA]' 카테고리의 다른 글
[JPA] 벡엔드 (02_SimpleDMS_Page) 반응형 게시판 (1) | 2023.11.02 |
---|---|
[JPA] 프론트엔드 (02_SimpleDMS_Page) 반응형 게시판 (2) | 2023.11.01 |
[JPA] Pilot_Project 블로그 테마별 알아보기 (1) | 2023.10.30 |
[JPA] JPQL (Java Persistence Query Language)이란 ? (2) | 2023.10.29 |
[JPA] 임베디드 타입 (@Embeddable) (1) | 2023.10.28 |