2023. 7. 22. 23:25

Car.js

 

import {useState, useEffect} from 'react'
import {useParams, useNavigate} from "react-router-dom"
import Layout from '../components/Layout';
import FormInput from '../components/FormInput';

let BASE_URL = "http://localhost:8000/car/"

const Car = () => {
    let {id} = useParams()
    const navigate = useNavigate()

    const [car, setCar] = useState(null)
    const [price, setPrice] = useState(null)
    const [error, setError] = useState([])

    const getCar = async() => {
        const res = await fetch(`${BASE_URL}${id}`)
        if (!res.ok) {
            setError(["Error fetching car"])
        } else {
            const data = await res.json()
            setCar(data)
        }
    }

    const onChange = (event)=>{
        setPrice(event.target.value)
    }

    const updatePrice = async() => {
        const res = await fetch(`${BASE_URL}${id}`,{
            method: "PUT",
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({price})
        })

        const data = await res.json()
        if (!res.ok) {
            alert("수정 에러!")
        }else {
            alert("가격 수정이 완료되었습니다!")
            getCar()
        }
    }

    const handleDelete = async () => {
        const res = await fetch(`${BASE_URL}${id}`,{
            method: "DELETE",
            headers: {
                'Content-Type': 'application/json'
            }
        })

        if (!res.ok) {
            alert("삭제 에러!")
        }else {
            alert("삭제가 완료되었습니다!")
            navigate("/cars")
        }

    }

    useEffect(()=>{
        getCar()
    },[])

    return (
        <Layout>
            {error && <ul className="flex flex-col mx-auto text-center">
            { error && error.map(
                (el, index)=>(                            
                    <li key={index} className="my-2 p-1 border-2 border-red-700 max-w-md mx-auto">{el}</li>
                    )
                )
            }      
        </ul>}
        {car&&<div>              
            <div className="flex flex-col justify-between min-h-full items-center">
                <div className="font-bold text-xl text-gray-600 my-3">
                    {car.brand} {car.make}
                </div>              
       
                <div className="flex flex-col items-center font-normal text-lg">
                    <div>Price: <span className="font-semibold text-orange-600 text-xl">{car.price}</span></div>
                    <div>Year: {car.year}</div>
                    <div>Km: {car.km}</div>
                </div>
            </div></div>}

            <div className="flex flex-row">
                 
                    <FormInput
                            label='change price'
                            placeholder={price}
                            type="number"
                            value={price}
                            onChange={onChange}
                            required />
                   
                    <button
                        onClick={updatePrice}
                        className="bg-yellow-500 text-white p-2 rounded-md m-3 transition-opacity hover:opacity-80">
                            Edit price
                    </button>
                    <button
                        onClick={handleDelete}
                        className="bg-red-700 text-white p-2 rounded-md m-3 transition-opacity hover:opacity-80">
                            Delete Car
                    </button>        
                </div>
        </Layout>
    )
}

export default Car

 

 

car.py

 

from fastapi import FastAPI, Body, HTTPException, status

from typing import Dict, List

from decouple import config
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from motor.motor_asyncio import AsyncIOMotorClient

from bson import ObjectId

from fastapi.middleware.cors import CORSMiddleware

from models import CarBase, CarUpdate

origins = [
    "http://localhost:3000",
]



DB_URL = config('DB_URL', cast=str)
DB_NAME = config('DB_NAME', cast=str)

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins = origins,
    allow_credentials = True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.on_event("startup")
async def startup_db_client():
    app.mongodb_client = AsyncIOMotorClient(DB_URL)
    app.mongodb = app.mongodb_client[DB_NAME]

@app.on_event("shutdown")
async def shutdown_db_client():
    app.mongodb_client.close()


@app.get("/car/{id}")
async def root(id:str):
    if (car := await app.mongodb["cars"].find_one({"_id": ObjectId(id)})) is not None:
        return get_ids(car)
    raise HTTPException(status_code=404, detail=f"Car with {id} not found")
    # car = await app.mongodb["cars"].find_one({"_id": ObjectId(id)})
    # # print(car)
    # return get_ids(car)

@app.get("/cars/price")
async def cars_by_price(min_price:int=0, max_price:int=100000):
    list = app.mongodb["cars"].find({
        "$and": [{"price":{"$gte": min_price}},{"price":{"$lte": max_price}}]  
    })
    result = [get_ids(car) async for car in list]
    return result

@app.get("/cars")
async def list_all_cars(
    min_price: int=0,
    max_price: int=100000,
    brand:str=None,
    page:int=1):

    RESULT_PER_PAGE = 25
    skip = (page - 1) * RESULT_PER_PAGE

    query = {"price": {"$lte":max_price, "$gte":min_price}}
    if brand:
        query["brand"] = brand

    list = app.mongodb["cars"].find(query).sort("_id", -1).skip(skip).limit(RESULT_PER_PAGE)
    result = [get_ids(car) async for car in list]
    return result

def get_ids(car: Dict) -> Dict:
    # print(car)
    id = car["_id"]
    car["_id"] = str(id)
    return car


@app.post("/cars")
async def new_car(car: CarBase = Body(...)):
    # print(car)
    car = jsonable_encoder(car)
    new_car = await app.mongodb["cars"].insert_one(car)
    # print(new_car)
    # print(new_car.inserted_id)
    created_car = await app.mongodb["cars"].find_one({"_id": ObjectId(new_car.inserted_id)})
    #return {"message": "new_car created"}
    return JSONResponse(status_code=status.HTTP_201_CREATED, content=get_ids(created_car))

@app.put("/car/{id}")
async def update_car(id: str, car: CarUpdate = Body(...)):
    print(car.model_dump())
    await app.mongodb["cars"].update_one(
        {"_id": ObjectId(id)}, {"$set": car.model_dump()}
    )

    if (car := await app.mongodb["cars"].find_one({"_id": ObjectId(id)})) is not None:
        return get_ids(car)
    raise HTTPException(status_code=404, detail=f"Car with {id} not found")

@app.delete("/car/{id}")
async def delete_car(id: str):
    delete_result = await app.mongodb["cars"].delete_one({"_id": ObjectId(id)})

    if (delete_result.deleted_count == 1):
        return JSONResponse(status_code=status.HTTP_204_NO_CONTENT, content=None)
   
    raise HTTPException(status_code=404, detail=f"Car with {id} not found")


'html,css' 카테고리의 다른 글

table colgroup  (0) 2023.11.07
11/02, 7~9  (0) 2023.11.02
Fullstack 자동차 브랜드 검색  (1) 2023.07.19
movie list  (0) 2023.07.18
react + tailwind.css  (0) 2023.07.17
Posted by 다만사