Project/Toy-project

์ผ๋‹จ ์ข€ ๊ทธ๋Ÿด๋“ฏํ•ด๋ณด์ด๊ฒŒ ์„ค๋ช… pop-over ์ฐฝ์„ ๋งŒ๋“ค์—ˆ๋‹ค. https://chakra-ui.com/docs/components/popover/usage Chakra UI - A simple, modular and accessible component library that gives you the building blocks you need to build your React aSimple, Modular and Accessible UI Components for your React Applications. Built with Styled Systemchakra-ui.com๊ทผ๋ฐ ๋ง‰์ƒ ํŽธํ•˜๊ฒŒ ํ•˜๋ ค๊ณ  chakra UI๋ฅผ ์“ฐ๋ ค ๋ณด๋‹ˆ ๋‹ค๋ฅธ css์™€ ์ถฉ๋Œ์ด ์ผ์–ด๋‚ฌ๋‹ค ใ…œใ…œ ๊ทธ๋ž˜์„œ ์ด๊ฒƒ์ €๊ฒƒ ์ˆ˜์ •ํ•˜๊ณ , !import..
๋ง์…ˆ ๊ธฐ๋Šฅ๊ฐ€์ง€๊ณ  ์‚ฌ์‹ค ๋‚ด๊ฐ€ ์“ธ ๊ธฐ๋Šฅ์€ ์ถฉ๋ถ„ํ•˜์ง€๋งŒ (...) ๊ทธ๋ž˜๋„ ๋บ„์…ˆ๊ธฐ๋Šฅ๊นŒ์ง€ ๊ตฌํ˜„ํ•ด์„œ ๋„ฃ์—ˆ๋‹ค. ใ…œใ…œ ์ฒ˜์Œ์— handleAdd ํ•จ์ˆ˜ ๋ฐ‘์— handleSubtract ํ•จ์ˆ˜๋ฅผ ๋˜‘๊ฐ™์ด ๋งŒ๋“ค๋‹ค๋ณด๋‹ˆ, ์•„ ์ด๊ฑฐ ๊ทธ๋ƒฅ ํŒŒ๋ผ๋ฏธํ„ฐ ๋ฐ›์•„์„œ ํ•˜๋‚˜์˜ ํ•จ์ˆ˜๋กœ ํ•ฉ์น˜๋ฉด ๋˜๊ฒ ๊ตฌ๋‚˜! ํ•˜๊ณ  ์žฌ๋นจ๋ฆฌ ์ˆ˜์ •ํ–ˆ๋‹ค! ๋งˆ์น˜ ์ฒ˜์Œ๋ถ€ํ„ฐ ๊ณ„ํšํ–ˆ๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ใ…Žใ…Ž ๋บ„์…ˆ ๊ธฐ๋Šฅ const handleOperation = (operator: string) => { const t1 = state.time1.includes(":") ? state.time1.split(":") : [state.time1, "00"]; const t2 = state.time2.includes(":") ? state.time2.split(":") : [state.time2, "00"];..
์ง€๋‚œ ๊ฒŒ์‹œ๊ธ€์—์„œ ์ˆซ์ž ์ž…๋ ฅํ•  ๋•Œ ์ž๋™์œผ๋กœ ์‹œ๊ฐ„ ๊ตฌ๋ถ„ (":") ํ•ด์ฃผ๋Š”๊ฑฐ๋ž‘ ์—”ํ„ฐํ‚ค ์ž…๋ ฅ์œผ๋กœ + ๊ตฌํ˜„์„ ํ–ˆ๋‹ค. ๊ทผ๋ฐ ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์€ ๊ทผ๋ฌด ์‹œ๊ฐ„์„ ์ „๋ถ€ ๋”ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋”ํ•œ ๊ฒƒ์— ๋˜ ๋”ํ•˜๊ณ  ๋˜ ๋”ํ•˜๊ณ  ๋˜ ๋”ํ•˜๋Š” ์ด๋Ÿฐ~ ๊ณ„์‚ฐ๊ธฐ ๊ฐ™์€ ๊ธฐ๋Šฅ์ด ํ•„์š”ํ–ˆ๋‹ค. ์‹œ๊ฐ„ ๋ˆ„์ ํ•ด์„œ ๋”ํ•˜๊ธฐ const result = `${adjustedHours .toString() .padStart(2, "0")}:${adjustedMinutes.toString().padStart(2, "0")}`; setState({ time1: result, time2: "", result: "", }); ๊ฒฐ๊ณผ๊ฐ’์— (๋ง์…ˆ์„ ํ•œ ํ›„) result ๋ฅผ time1์— ๋„ฃ์–ด์ค€๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์›๋ž˜ time2 ์˜ ์ดˆ๊ธฐ๊ฐ’์ด 00:00 ์ด์—ˆ๋Š”๋ฐ ์ด๊ฒƒ๋„ ๋นˆ ๋ฌธ์ž์—ด๋กœ ๋ฐ”๊พธ์–ด..
๊ทผ๋ฌด์‹œ๊ฐ„ ๊ณ„์‚ฐํ•  ๋•Œ ๊ณ„์‚ฐ์ด ์ž˜ ๋งž๋‚˜.. ํ™•์ธํ•  ๋•Œ๋งˆ๋‹ค ์‹œ๊ฐ„ ๊ณ„์‚ฐ์„ ํ•˜๋Š” ์‚ฌ์ดํŠธ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š”๋ฐ ๊ทธ๊ฒŒ ๋‚ด๊ฐ€ ๋”ฑ ํ•„์š”ํ•œ! ๊ธฐ๋Šฅ๋งŒ ์žˆ์ง€๊ฐ€ ์•Š์•„์„œ ๋ถˆํŽธํ•œ ์ ์ด ์žˆ์–ด ๊ทธ๋ƒฅ ์ด์ •๋„๋Š” ๋งŒ๋“ค์–ด์„œ ์จ๋ณด์ง€ ๋ญ.. ํ•˜๊ณ  ์‹œ์ž‘ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. const [state, setState] = useState({ time1: "00:00", time2: "00:00", result: "", }); const handleAdd = () => { const t1 = state.time1.split(":"); const t2 = state.time2.split(":"); const hours = parseInt(t1[0]) + parseInt(t2[0]); const minutes = parseInt(t1[1]) + parseInt(t2[1]..
๊ฐ„๋งŒ์— ๋‹ค์‹œ ๋“ค์–ด์˜จ ๋™์ˆฒ ํ”„๋กœ์ ํŠธ๋Š” ์˜ค๋ฅ˜ ํˆฌ์„ฑ์ด์˜€๋‹ค ^_^ ํ•˜๋ฃจ ์ข…์ผ ์—ฌ๊ธฐ๋ฅผ ๋ง‰์œผ๋ฉด ์ €๊ธฐ์„œ ์ƒˆ์–ด๋‚˜์˜ค๋Š” ์˜ค๋ฅ˜๋ฅผ ์žก์•˜๊ณ  ๋ณธ๋ก ์€ ์ด์ œ์„œ์•ผ ์‹œ์ž‘! https://tanstack.com/table/v8 TanStack Table | React Table, Solid Table, Svelte Table, Vue Table Headless UI for building powerful tables & datagrids with TS/JS, React, Solid, Svelte and Vue tanstack.com AG-grid๋ฅผ ์“ธ๊นŒ, tanstack table์„ ์“ธ๊นŒ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ผ๋˜ tanstacktable์ด๋‚˜ ํ™•์‹คํžˆ ์•Œ๊ณ  ๊ฐ€์ž ํ•˜๊ณ  ๊ฒฐ์ •ํ–ˆ๋‹ค $ npm install @tanstack/react-tabl..
์ง€๋‚œ ๋ฒˆ์— ์ด ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ต์งธ๋กœ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ + next.js๋กœ ์˜ฎ๊ธฐ๋Š” ์ž‘์—…์„ ํ–ˆ๋‹ค. ( + tailwind) ๊ทธ ์ค‘์— ํ•œ๋™์•ˆ ํ•ด๊ฒฐ์ด ์•ˆ๋˜๋˜ ์˜ค๋ฅ˜๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ... Property 'map' does not exist on type 'never' ์ง„์งœ ๋‚˜๋ฅผ ํ•œ๋™์•ˆ ํ”ผ๊ณคํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ์Œ. ์ธํ„ฐ๋„ท์— ๋‚˜์™€์žˆ๋Š” ๋ชจ๋“  ๋ฐฉ๋ฒ•์„ ์ด ๋™์›ํ–ˆ์œผ๋‚˜ ์ด๊ณณ์ด ํ•ด๊ฒฐ์ด ์•ˆ๋˜๋ฉด ์ €๊ณณ์ด ๋นต๊ตฌ๊ฐ€ ๋‚˜๊ณ  .... ๊ทธ๋žฌ๋Š”๋ฐ ๊ฒฐ๊ตญ ์กฐ๊ธˆ~~์€ ํ—ˆ๋ฌดํ•œ ํ•ด๊ฒฐ์ด์—ˆ๋‹ค. ๊ทธ๋ž˜๋„ ์ง„์งœ ๋„ˆ๋ฌด ์†์‹œ์› ์ผ๋‹จ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด, export default function VillagerList() { const [data, setData] = useState(null); const [error, setError] = useState(null); const URL = "h..
html2canvas ์ง€๋‚œ ๋ฒˆ์— ์ž‘์„ฑํ–ˆ๋˜ https://velog.io/@fairytale779/TIL-html2canvas ๋ฅผ ์ด์šฉํ•ด์„œ ์‰ฝ๊ฒŒ ๊ตฌํ˜„ํ•˜์˜€๋‹ค ์„ธํŒ…์€ ์œ„ ๊ฒŒ์‹œ๊ธ€์— ์ ํ˜€์žˆ์œผ๋‹ˆ ๋„˜์–ด๊ฐ€๊ณ , ํ•จ์ˆ˜๋Š” ๋‹ค์‹œ ์ ์–ด๋ณด์ž๋ฉด ์ด๋ ‡๋‹ค const onFullCapture = () => { html2canvas(document.querySelector(".App")).then( (canvas) => { const link = document.createElement("a"); link.download = "image"; link.href = canvas.toDataURL(); document.body.appendChild(link); link.click(); } ); }; const onFourCutCapture =..
์ง€๋‚œ ๋ฒˆ์— ์ด๋ฏธ์ง€ ์‚ฌ์ด์ฆˆ๋ฅผ ์ง€์ •ํ–ˆ๋”๋‹ˆ ๋ถˆ๋Ÿฌ์˜จ ์‚ฌ์ง„๋“ค์ด ๋น„์œจ ์ƒ๊ด€์—†์ด ์ฐŒ๋ถ€๊ฐ€ ๋˜๋Š” ๊ฒƒ๋“ค์„ ๋ง‰๊ณ ์ž ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ์„ ๊ณต๋ถ€ํ•ด๋ณด์•˜๋”ฐ. react-easy-crop ๊ณต์‹ github: https://github.com/ricardo-ch/react-easy-crop npm install react-easy-crop --save react-cropper ๋‚˜๋Š” ๋‘๊ฐ€์ง€ ์ค‘์— react-cropper๋ฅผ ์ด์šฉํ–ˆ๋‹ค. https://github.com/react-cropper/react-cropper ImageCrop.js import { useState, createRef } from "react"; import Cropper from "react-cropper"; import "cropperjs/dist/cropper.css..
์ŠคํŒŒ๋ฅดํƒ€ ์ฝ”๋”ฉํด๋Ÿฝ์—์„œ ๋ฌด๋ฃŒ๋กœ css,html ๊ฐ•์˜๋ฅผ ํ’€์–ด์คฌ๋Š”๋ฐ, ์ด๊ฑด ๊ทธ๋ƒฅ ๊ฐ„๋‹จํ•œ html,css๋‹ˆ ๋“ฃ์ง€ ์•Š๊ณ  ์—ฌ๊ธฐ์„œ ์˜๊ฐ์„ ์–ป์–ด... ๋ฆฌ์•กํŠธ๋กœ ์ธ์ƒ๋„ค์ปท ๋งŒ๋“ค๊ธฐ๋ฅผ ํ•ด๋ดค๋”ฐ. ๋ฐ˜๋‚˜์ ˆ์ด๋ฉด ๊ฐ„๋‹จํžˆ ๋๋‚ผ ์ค„ ์•Œ์•˜๋Š”๋ฐ, ์ด๋Ÿฐ ์ €๋Ÿฐ ๋ณต๋ณ‘์„ ๋งˆ์ฃผ์ณ ๊ฒฐ๊ตญ ๊ฒŒ์‹œ๊ธ€๋„ ๋‘ ๊ฐœ๋กœ ๋‚˜๋‰˜๊ฒŒ ๋จ ^_6 (์„ธ ๊ฐœ๊ฐ€ ๋  ์ˆ˜๋„) ๐ŸชŸ ๊ธฐ๋ณธ ํ‹€ ์ผ๋‹จ ๋งŒ๋“ค๊ณ  ๋ธ”๋กœ๊น…ํ•˜๋Š” ๊ฑฐ๋ผ ํ˜„์žฌ๊นŒ์ง€ ์ƒํ™ฉ์€ ์ด๋Ÿฌํ•˜๋‹ค ์™œ ์•„์ด๋ธŒ๊ณ  ์žฅ์›์˜์ด๋ƒ๋ฉด,... ์•„์ด๋ธŒ ์‹ ๊ณก์ด ๋„ˆ๋ฌด ์ข‹๊ณ  ์›์˜์ด๊ฐ€ ๋„ˆ๋ฌด ์ด๋ป์„œ.. ใ…  ์Šคํƒ€์ผ ์ปดํฌ๋„ŒํŠธ ์“ฐ๋ ค๋‹ค๊ฐ€ ๊ทธ๋ƒฅ css ์—๋‹ค๊ฐ€ ํ–ˆ๋‹ค. ์ง„ํ–‰ํ•˜๋ฉด์„œ ์ƒˆ๋กœ ์•Œ๊ฒŒ ๋œ ๊ฒƒ๋“ค๋งŒ ์ •๋ฆฌํ•ด๋ด„ ๋ฐฐ๊ฒฝ๋งŒ ํˆฌ๋ช…๋„ ์„ค์ • ์œ„ ์‚ฌ์ง„์— ๋ณด์ด๋Š” ๋ฐฐ๊ฒฝ์€ ์‚ฌ์‹ค ์ด๋Ÿฌํ•œ ์‚ฌ์ง„์ด๋‹ค. ๊ทผ๋ฐ ๋งŒ๋“ค์–ด ๋†“๊ณ  ๋ณด๋‹ˆ ๋ฐฐ๊ฒฝ์ด ๋„ˆ๋ฌด ์ •์‹ ์ด ์—†์–ด์„œ ใ… ใ…  ํˆฌ๋ช…๋„๋ฅผ ์กฐ๊ธˆ ์ฃผ๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ App์ž์ฒด์— ์ฃผ๊ฒŒ ..
๋™๋ฌผ์˜ ์ˆฒ์— ์š”์ฆ˜ ํ‘น ๋น ์ ธ์‚ฌ๋Š”๋ฐ, ๋‚ด๊ฐ€ ์ข‹์•„ํ•˜๋Š” ๊ฑธ๋กœ ๋ญ”๊ฐ€๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋ฉด ๋”์šฑ ํฅ๋ฏธ๊ฐ€ ์ƒ๊ธธ ๊ฑฐ ๊ฐ™์•„์„œ ์ผ๋‹จ ๋ƒ…๋‹ค ๋™๋ฌผ์˜์ˆฒ api๊ฐ€ ์žˆ๋‚˜ ์ฐพ์•„๋ณด์•˜๋‹ค. API ๋ถˆ๋Ÿฌ์˜ค๊ธฐ https://api.nookipedia.com/ ์—ฌ๊ธฐ์„œ api key๋ฅผ ์š”์ฒญํ•œ๋‹ค๊ณ  ํผ์„ ์ž‘์„ฑํ•ด ๋ณด๋ƒˆ๊ณ , ๋ณด๋ƒˆ๋”๋‹ˆ ๋ฉฐ์น  ๋งŒ์— ์‘์›ํ•œ๋‹ค๋ฉฐ (ใ…‹ใ…‹) ํ‚ค๋ฅผ ๋ณด๋‚ด์ฃผ์—ˆ๋‹ค. ์ผ๋‹จ ๋ฐ์ดํ„ฐ๋ฅผ ์ž˜ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ๋‚˜ ํ…Œ์ŠคํŠธ๋ฅผ ํ•ด๋ณด๊ธฐ์œ„ํ•ด ์ฃผ๋ฏผ ๋ชฉ๋ก๋ถ€ํ„ฐ postman ์œผ๋กœ ๋ถˆ๋Ÿฌ์™€ ๋ณด์•˜๋‹ค. X-API-KEY์— ๋‚ด๊ฐ€ ๋ฐ›์€ ํ‚ค๋ฅผ ๋„ฃ์–ด์ฃผ๊ณ  ํ˜ธ์ถœํ•˜๋ฉด ์ด๋ ‡๊ฒŒ ์ •๋ณด๊ฐ€ ์ญ‰~ ๋ถˆ๋Ÿฌ์™€์ง„๋‹ค. ๋ฆฌ์•กํŠธ๋กœ ์ถœ๋ ฅํ•˜๊ธฐ ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ npx create-react-app ์•ฑ์ด๋ฆ„ App key ์ถ”๊ฐ€ํ•˜๊ธฐ .env ํ‚ค๋Š” ์ผ๋‹จ ์ˆจ๊ฒจ์•ผ ํ•˜๋Š” ๋‚ด์šฉ์ด๋ฏ€๋กœ, .gitignore ์—์„œ # API KEY .env ..
๋ฐฐํฌ ์ค€๋น„ ํŽ˜์ด์ง€ ์ด๋ฆ„, ํŒŒ๋น„์ฝ˜ ์ˆ˜์ • public/index.html โœš en์„ ko๋กœ ๋ฐ”๊ฟ”์ฃผ์ง€ ์•Š์œผ๋ฉด ๋ฒˆ์—ญํ•˜๊ธฐ~ ๊ฐ™์€ ๊ฒŒ ๋‚˜์˜ฌ ์ˆ˜๋„ ์žˆ์Œ! ๊ฐ ํŽ˜์ด์ง€๋งˆ๋‹ค ๋ฐ”๊ฟ” ์ฃผ๊ธฐ index.html ์— ์žˆ๋Š” title์„ ์ฐพ์•„ ๋ฐ”๊พธ์–ด์ค€๋‹ค. ๋ Œ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค ๋ฐ”๊พธ์–ด์ฃผ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด useEffect ์‚ฌ์šฉ useEffect(() => { const titleElement = document.getElementsByTagName("title")[0]; titleElement.innerHTML = `๋‹ฌ๊ณผ ์ผ๊ธฐ์žฅ - ${id}๋ฒˆ ์ผ๊ธฐ`; }, []); ์ด๊ฑธ ํ•„์š”ํ•œ ํŽ˜์ด์ง€์— ๋„ฃ์–ด์ฃผ๋ฉด ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  list๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” home ์—๋„ ๋ณธ๋ž˜ ํƒ€์ดํ‹€์„ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ, ์ƒˆ๋กœ ์ผ๊ธฐ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  ๋ฆฌ์ŠคํŠธ๋กœ ์˜ค๊ณ  ๋‚˜์„œ๋„ ํƒ€์ดํ‹€์ด ๋ฐ”๋€๋‹ค๋Š”๊ฑฐ ๋ช…์‹ฌ๋ช…์‹ฌ ..
์ตœ์ ํ™” ์ตœ์ ํ™”์—๋Š” ์ง์ ‘ ์ฝ”๋“œ๋ฅผ ๋ˆˆ์œผ๋กœ ํ•˜๋‚˜ํ•˜๋‚˜ ๋ณด๊ณ  ํŒ๋‹จํ•˜๋Š” ์ •์ ์ธ ๋ถ„์„๊ณผ์ •์ด ์žˆ๊ณ , ํ”„๋กœ๊ทธ๋žจ ๋„๊ตฌ๋ฅผ ์ด์šฉํ•ด ์ฐพ์•„๋‚ด๋Š” ๋™์  ๋ถ„์„์ด ์žˆ๋‹ค ๊ทผ๋ฐ ๋‚œ ์•„์ง ๋ฐ”๋ณด๋‹ˆ๊นŒ ๋™์  ๋ถ„์„์„ ์ด์šฉํ•ด๋ณด๊ธฐ๋กœ ํ•จ..ใ…Ž ์ปดํฌ๋„ŒํŠธ ํƒญ์—์„œ Highlight updates when components render ๋ถ€๋ถ„์„ ์ฒดํฌํ•ด ์ฐพ์•„๋ณด๋„๋ก ํ•˜์ž ์ด ๊ธฐ๋Šฅ์€ ๋ญ”๊ฐ€๊ฐ€ ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ ์–ด๋–ค state๋“ค์ด ๋ณ€ํ™”๊ฐ€ ๋˜๋Š”์ง€ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค. ๋‚ ์งœ ๋ณ€ํ™” ๋‚ ์งœ ๋ณ€ํ™”์‹œ์— ์ƒ๋‹จ์— ํ•„ํ„ฐ์™€ ์ƒˆ ๊ธ€์“ฐ๋Š” ๋ฒ„ํŠผ์ด ๊ณ„์† ๋ Œ๋”๊ฐ€ ๋˜๊ณ  ์žˆ๋Š” ๋ชจ์Šต์„ ๋ณผ ์ˆ˜ ์žˆ์Œ ๊ทผ๋ฐ ์‚ฌ์‹ค ์›”์„ ๋ฐ”๊พผ๋‹ค๊ณ  ํ•ด์„œ ๊ทธ๋ถ€๋ถ„์ด ์ƒˆ๋กœ ๋ Œ๋” ๋  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ทธ ๋ถ€๋ถ„์€ controlMenu๋กœ, Home์ปดํฌ๋„ŒํŠธ์—์„œ ์ผ๋‹จ increaseMonth, decreaseMonth๋กœ ๋‚ ์งœ๊ฐ€ ๋ฐ”๋€Œ๊ณ , ๋˜ ๊ทธ ์ž์‹ ์š”์†Œ..
Dong _ hwa
'Project/Toy-project' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๊ธ€ ๋ชฉ๋ก