본문 바로가기
노마드코더/REACT 크롬 앱

CHROME APP

by 갱생angel 2024. 2. 5.

componenet

  -Input.jsx

  -Button.jsx

  -Checkbox.jsx

module

  -Login.jsx

  -Clock.jsx

  -Weather.jsx

  -ToDoList.jsx

page

  -ChromeApp.jsx

css

  -List.css

img

  -1.jpg, 2.jpg, 3.jpg, 4.jpg, 5.jpg

App.js

 

component - <Input.jsx>

import React from 'react'

function Input({className, type, name, value, onChange, maxLength, placeholder, checked}) {
  return (
    <div>
      <input
        className={className}
        type={type}
        name={name}
        value={value}
        onChange={onChange}
        maxLength={maxLength}
        placeholder={placeholder}
        checked={checked}
      />
    </div>
  )
}

export default Input

 

component - <Button.jsx>

import React from 'react'

function Button({type, className, name, onClick}) {
  return (
    <div>
      <button type={type} className={className} onClick={onClick}>
        {name}
      </button>
    </div>
  )
}

export default Button

 

component - <Checkbox.jsx>

import React from 'react'
import '../css/List.css'
import Input from './Input'
import Button from './Button'

function CheckboxList({id, checkBool, listContent, removeList, checkToggle}) {
  const changeCheckBool = () => {
    checkToggle(id)
  }

  const handleRemoveList = () => {
    removeList(id)
  }

  return (
    <div className="checkboxListDiv" key={id}>
      <Input
        type={'checkbox'}
        className={'checkboxInput'}
        checked={checkBool}
        onChange={changeCheckBool}
      />
      <p className={checkBool ? 'checkboxP_2' : 'checkboxP_1'}>{listContent}</p>
      <Button name={'X'} onClick={handleRemoveList} className={'deleteListButton'} />
    </div>
  )
}

export default CheckboxList

module - <Clock.jsx>

import React, {useEffect, useState} from 'react'

function Clock() {
  const [clock, setClock] = useState(new Date())
  const renewTime = () => setClock(clock => new Date())

  const clockHour = String(clock.getHours()).padStart(2, 0)
  const clockMinutes = String(clock.getMinutes()).padStart(2, 0)
  const clockSeconds = String(clock.getSeconds()).padStart(2, 0)

  useEffect(() => {
    const time = setInterval(renewTime, 1000)
    return () => clearInterval(time)
  })

  return (
    <div>
      <h2>{`${clockHour}:${clockMinutes}:${clockSeconds}`}</h2>
    </div>
  )
}

export default Clock

 

module - <Weather.jsx>

import React, {useEffect, useState} from 'react'
import '../css/List.css'

function Weather() {
  const [weather, setWeather] = useState()

  const getWeather = position => {
    const lat = position.coords.latitude
    const lng = position.coords.longitude

    const API_KEY = 'API_키'
    const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${API_KEY}&units=metric`

    fetch(url)
      .then(response => response.json())
      .then(data => {
        setWeather(data)
      })
  }

  useEffect(() => {
    navigator.geolocation.getCurrentPosition(getWeather)
  }, [])

  return (
    <div>
      <span className="weatherName">{weather?.name}</span>
      <div className="weatherDiv">
        <img
          src={`http://openweathermap.org/img/wn/${weather?.weather[0].icon}.png`}
          alt="아이콘"
          className="weatherIcon"
        />
        <span className="weatherTemp">{`${weather?.main.temp}°C`}</span>
      </div>
    </div>
  )
}

export default Weather

 

module - <ToDoList.jsx>

import React, {useEffect, useRef, useState} from 'react'
import '../css/List.css'
import Input from '../component/Input'
import Button from '../component/Button'
import Checkbox from '../component/Checkbox'

function ToDoList() {
  const [listValue, setListValue] = useState('')
  const [todoList, setToDoList] = useState(
    JSON.parse(localStorage.getItem('todoList')) || []
  )

  const listKey = useRef(parseInt(localStorage.getItem('ListKey')) || 0)

  const changeListValue = event => {
    setListValue(event.target.value)
  }

  const addList = event => {
    event.preventDefault()
    const checkBool = false
    if (listValue === '') {
      alert('할 일 목록을 입력해주세요.')
    } else {
      const newList = {
        listContent: listValue,
        id: listKey.current,
        checked: checkBool
      }
      listKey.current += 1
      setToDoList([newList, ...todoList])
      setListValue('')
    }
  }

  const removeList = id => {
    const remainList = todoList.filter(remove => remove.id !== id)
    setToDoList(remainList)
  }

  const checkToggle = id => {
    setToDoList(
      todoList.map(toggle =>
        toggle.id === id ? {...toggle, checked: !toggle.checked} : toggle
      )
    )
  }

  useEffect(() => {
    localStorage.setItem('todoList', JSON.stringify(todoList))
    localStorage.setItem('ListKey', parseInt(listKey.current))
  })

  return (
    <div>
      <div>
        <form className="todoListForm">
          <Input
            type={'text'}
            className={'todoListInput'}
            value={listValue || ''}
            onChange={changeListValue}
            placeholder={'Write your List...'}
          />
          <Button
            className={'addListButton'}
            name={'+'}
            type={'submit'}
            onClick={addList}
          />
        </form>
      </div>
      <div className="checkboxDiv">
        {todoList.map(listData => {
          return (
            <Checkbox
              key={listData.id}
              {...listData}
              checkBool={listData.checked}
              removeList={removeList}
              checkToggle={checkToggle}
            />
          )
        })}
      </div>
    </div>
  )
}

export default ToDoList

 

module - <Login.jsx>

import React, {useEffect, useState} from 'react'
import '../css/List.css'
import Input from '../component/Input'
import Button from '../component/Button'
import ToDoList from './ToDoList'
import Clock from './Clock'
import Weather from './Weather'

function Login() {
  const checkUsername = localStorage.getItem('username')

  const [loginValue, setLoginValue] = useState(checkUsername)
  const [loginBool, setLoginBool] = useState(true)
  const [timeTitle, setTimeTitle] = useState('')

  const time = new Date().getHours()

  const onChangeLogin = event => {
    setLoginValue(event.target.value)
  }

  const handleLogin = e => {
    e.preventDefault()
    if (loginValue === '') {
      alert('이름을 입력해주세요.')
    } else {
      setLoginBool(false)
      localStorage.setItem('username', loginValue)
    }
  }

  const handleLogout = () => {
    setLoginBool(true)
    setLoginValue('')
    localStorage.removeItem('username')
  }

  useEffect(() => {
    if (checkUsername === null) {
      setLoginBool(true)
    } else {
      setLoginBool(false)
    }
  }, [checkUsername])

  useEffect(() => {
    if (6 <= time && time < 12) {
      setTimeTitle('Good Morning')
    } else if (12 <= time && time < 18) {
      setTimeTitle('Good Afternoon')
    } else if (18 <= time && time < 21) {
      setTimeTitle('Good Evening')
    } else if ((21 <= time && time <= 23) || (0 <= time && time < 6)) {
      setTimeTitle('Good Night')
    }
  }, [time])

  return (
    <div>
      <div className="loginWeatherDiv">
        <Weather />
      </div>
      {loginBool ? (
        <div>
          <div className="logoutClockDiv">
            <Clock />
          </div>
          <form className="logoutDiv" onSubmit={handleLogin}>
            <Input
              className={'loginInput'}
              type={'text'}
              value={loginValue}
              onChange={onChangeLogin}
              maxLength={15}
              placeholder={'What your name...?'}
            />
            <Button className={'loginButton'} name={'≪'} />
          </form>
        </div>
      ) : (
        <div className="loginDiv">
          <div className="loginClockDiv">
            <Clock />
          </div>
          <div className="loginNameDiv">
            <h1 className="loginName">{`${timeTitle}, ${loginValue}`}</h1>
            <Button className={'loginButton'} name={'≫'} onClick={handleLogout} />
          </div>
          <div>
            <ToDoList />
          </div>
        </div>
      )}
    </div>
  )
}

export default Login

Page - <ChromeApp.jsx >

import React from 'react'
import '../css/List.css'
import Login from '../module/Login'
import Image1 from '../img/1.jpg'
import Image2 from '../img/2.jpg'
import Image3 from '../img/3.jpg'
import Image4 from '../img/4.jpg'
import Image5 from '../img/5.jpg'

const randomImage = [Image1, Image2, Image3, Image4, Image5]

function ChromeApp() {
  const bgImage = randomImage[Math.floor(Math.random() * randomImage.length)]

  return (
    <div style={{backgroundImage: `url(${bgImage})`}} className="ChromeAppDiv">
      <Login />
    </div>
  )
}

export default ChromeApp

List.css

body {
  margin: 0;
}
//로그인
.loginDiv {
  margin-left: 570px;
}
.loginInput {
  background-color: transparent;
  border: 0px;
  border-bottom: 1px solid white;
  color: white;
  width: 400px;
  height: 50px;
  font-size: 30px;
  outline: none;
}
.loginInput::placeholder {
  color: white;
}
.loginNameDiv {
  display: flex;
  align-items: center;
  color: white;
  text-shadow: 0px 0px 10px black;
}
.loginName {
  font-size: 40px;
}
.loginClockDiv {
  color: white;
  display: flex;
  font-size: 70px;
  height: 200px;
  padding-top: 20px;
  padding-left: 0px;
  text-shadow: 0px 0px 10px black;
}
.loginWeatherDiv {
  color: white;
  display: flex;
  float: right;
  margin-right: 20px;
  margin-top: 10px;
  text-shadow: 0px 0px 10px black;
}
.logoutDiv {
  display: flex;
  align-items: center;
  color: white;
  padding-top: 50px;
  padding-left: 550px;
}
.logoutClockDiv {
  color: white;
  font-size: 70px;
  height: 200px;
  padding-top: 90px;
  padding-left: 560px;
  text-shadow: 0px 0px 10px black;
}
//체크박스
.checkboxDiv {
  margin-top: 10px;
  margin-bottom: 20px;
}
.checkboxListDiv {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  width: 440px;
}
.checkboxInput {
  margin-right: 20px;
  width: 18px;
  height: 18px;
}
.checkboxP_1 {
  margin-right: auto;
  color: white;
  font-size: 20px;
  text-shadow: 0px 0px 10px black;
}
.checkboxP_2 {
  margin-right: auto;
  color: gray;
  text-decoration: line-through;
  font-size: 20px;
  text-shadow: 0px 0px 10px black;
}
//투두리스트
.todoListForm {
  display: flex;
  justify-content: flex-start;
  align-items: center;
}
.todoListInput {
  margin-right: 20px;
  background: transparent;
  border: 0px;
  border-bottom: 1px solid white;
  outline: none;
  width: 390px;
  height: 50px;
  font-size: 25px;
  color: white;
}
.todoListInput::placeholder {
  color: white;
}
//날씨
.weatherName {
  margin-left: 18px;
  font-size: 20px;
}
.weatherDiv {
  display: flex;
}
.weatherIcon {
  height: 50px;
}
.weatherTemp {
  font-size: 18px;
  padding-top: 13px;
}
//버튼
.loginButton {
  margin-left: 55px;
  background-color: transparent;
  border: 0px;
  color: white;
  font-size: 30px;
}
.loginButton:hover {
  color: orange;
}
.addListButton {
  background-color: transparent;
  border: 0px;
  color: white;
  font-size: 30px;
}
.addListButton:hover {
  color: aqua;
}
.deleteListButton {
  background-color: transparent;
  border: 0px;
  font-size: 20px;
  color: white;
}
.deleteListButton:hover {
  color: red;
}
//크롬앱
.ChromeAppDiv {
  background-size: 100% 100%;
  width: 100vw;
  height: 100vh;
  overflow: auto;
}

App.JS

import React from 'react'
import ChromeApp from './page/ChromeApp.jsx'

function App() {
  return (
    <div>
      <ChromeApp />
    </div>
  )
}

export default App

 

 

최종 완성본

'노마드코더 > REACT 크롬 앱' 카테고리의 다른 글

11. 시간에 따른 Title  (0) 2024.02.04
10. 체크박스 체크 유무 확인  (0) 2024.02.04
9. 오늘의 할 일 추가, 삭제  (0) 2024.02.03
8. OpenWeatherMap API 가져오기  (0) 2024.02.01
7. 위도, 경도 불러오기  (0) 2024.02.01