댓글 검색 목록

[Nodejs] React.js, Node.js 및 MongoDB # 10을 사용하여 간단한 POS 생성 : CRUD Supplier

페이지 정보

작성자 운영자 작성일 20-08-02 10:08 조회 712 댓글 0

Create simple POS with React.js, Node.js, and MongoDB #10: CRUD Supplier 


https://blog.soshace.com/create-simple-pos-with-react-js-node-js-and-mongodb-10-crud-supplier/ 


방어 : POS –“판매 시점”. 판매 시점에서 판매자는 고객이 지불해야 할 금액을 계산하고 그 금액을 나타내며 고객에 대한 송장을 작성할 수 있습니다 (현금 등록기 출력물 일 수 있음). 고객이 지불 할 수 있는 옵션을 나타냅니다.


이전 장에서는 식료품 점의 일반 정보에 대한 CRUD 작업을 성공적으로 구현했습니다. 이 장에서는 식료품 점의 공급 업체 정보에 대한 CRUD 작업을 계속 구현할 것입니다.


이 과정은 이전 장과 비슷합니다. 각 반복 단계에서 개선 된 기능을 통해 CRUD 작업을 보다 자세하게 이해하는 데 도움이 됩니다. Redux 작업을 반복하면 유창하고 자연스럽게 Redux 메커니즘 사용 사례가 됩니다.


1. 상수 추가 


Redux 구현에 대한 이전 자습서와 마찬가지로 상수 정의부터 시작합니다. 이를 위해 ./constants 폴더를 열고 아래 코드 스니펫에 표시된 대로 상태 이름을 지정하는 데 사용되는 상수를 추가해야 합니다.


1
2
3
4
5
// SUPPLIER
export const SUPPLIER_FETCHING = "SUPPLIER_FETCHING";
export const SUPPLIER_SUCCESS = "SUPPLIER_SUCCESS";
export const SUPPLIER_FAILED = "SUPPLIER_FAILED";
export const SUPPLIER_CLEAR = "SUPPLIER_CLEAR";


2. Reducer 추가 


Reducer를 구현하려면 ./reducer 폴더로 이동해야 합니다. 그런 다음 supplier.reducer.js라는 리듀서를 만들어야 합니다. 이 과정은 이전에 만든 감속기와 유사합니다. 감속기 파일에서 상수를 가져온 다음 아래 코드 스니펫에 표시된 것처럼 초기 상태 및 감속기 함수를 정의해야 합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import {
    SUPPLIER_FETCHING,
    SUPPLIER_SUCCESS,
    SUPPLIER_FAILED,
    SUPPLIER_CLEAR,
} from "../constants";
 
const initialState = {
    isFetching: false,
    isError: false,
    result: null,
};
 
export default (state = initialState, { type, payload }) => {
    switch (type) {
        case SUPPLIER_FETCHING:
            return { ...state, isFetching: true, isError: false, result: null };
        case SUPPLIER_FAILED:
            return { ...state, isFetching: false, isError: true, result: null };
        case SUPPLIER_SUCCESS:
            return { ...state, isFetching: false, isError: false, result: payload };
        case SUPPLIER_CLEAR:
            return { ...state, result: null, isFetching: false, isError: false };
        default:
            return state;
    }
};


3. Register Reducer 


이제 index.reducer.js 파일에서 감속기를 루트 감속기에 등록해야 합니다. 이를 위해 index.reducer.js 파일을 열고 supplierReducer를 포함 시켜 아래 코드 스니펫에 표시된 대로 Reducers 함수를 결합해야 합니다.



2
3
4
5
6
7
8
9
10
import supplierReducer from './supplier.reducer'
export default combineReducers({
  loginReducer,
  registerReducer,
  forgotpasswordReducer,
  resetpasswordReducer,
  posmachineReducer,
  branchReducer,
  supplierReducer
});


4. Creating Action 


다음으로 ./actions 폴더에 supplier.action.js 파일이라는 새 작업 파일을 만들어야 합니다. 먼저 아래 코드 스니펫에 표시된 대로 필요한 상수, 구성 요소 및 모듈을 가져와야 합니다.


JavaScript
1
2
3
4
5
6
7
8
import {
    SUPPLIER_FETCHING,
    SUPPLIER_SUCCESS,
    SUPPLIER_FAILED,
    SUPPLIER_CLEAR,
} from "../constants";
import swal from "sweetalert";
import { httpClient } from "./../utils/HttpClient";



JavaScript
1
2
3
4
5
6
7
8
import {
    SUPPLIER_FETCHING,
    SUPPLIER_SUCCESS,
    SUPPLIER_FAILED,
    SUPPLIER_CLEAR,
} from "../constants";
import swal from "sweetalert";
import { httpClient } from "./../utils/HttpClient";


이제 CRUD 작업을 구현할 수 있습니다.


4. Create Operation 


먼저 create 작업을 구현합니다. 이를 위해 ./supplier라는 새 구성 요소 폴더를 작성하고 그 안에 action이라는 파일을 작성해야 합니다.


이 동작에 대한 흥미로운 점은 디스패치를 ​​사용하여 감속기가 아닌 다른 기능을 트리거 하는 방법을 배우는 것입니다. 인덱스 페이지로 다시 리디렉션하면서 디스패치를 ​​사용하여 새 데이터를 다시 로드하려고 합니다. 코딩 구현은 아래 코드 스니펫에 제공됩니다.


export const Create = (values, history) => {

    return async (dispatch) => {

        dispatch(setSupplierStateToFetching());

        const response = await httpClient.post(

            process.env.REACT_APP_API_URL + "supplier",

            values

        );

        if (response.data.result == "success") {

            dispatch(setSupplierStateToSuccess(response.data));

            swal("Success!", response.data.message, "success").then((value) => {

                dispatch(setSupplierStateToClear());

                history.goBack();

                dispatch(Index());

            });

        } else if (response.data.result === "error") {

            dispatch(setSupplierStateToFailed());

            swal("Error!", response.data.message, "error");

        }

    };

};


다음으로 create.js라는 새 파일을 만들고 아래 코드 스니펫에 표시된 대로 필요한 구성 요소를 가져와야 합니다.


import React, { useState, useEffect } from "react";

import { Formik } from "formik";

import { useDispatch } from "react-redux";

import * as supplierActions from "../../actions/supplier.action";

import * as Yup from "yup";

import { server } from "../../constants";


그런 다음 아래 코드 스니펫에 표시된 대로 Yup 모듈을 사용하여 유효성 검증 스키마를 정의해야 합니다.


const Create_Schema = Yup.object().shape({

    name: Yup.string()

        .min(2, "name is Too Short!")

        .max(50, "name is Too Long!")

        .required("name is Required"),

    address: Yup.string().required(),

    email: Yup.string()

        .email("Invalid email")

        .required("Email is Required"),

    tel: Yup.string().required("Telephone number is required"),

    vat: Yup.string().required("VAT number is required"),

});


이제 이 컴포넌트를 처음 탐색하기 위해 아래 코드 스니펫에 표시된 대로 사용자 세션을 확인하려고 합니다.


export default (props) => {

    const dispatch = useDispatch();


    useEffect(() => {

        if (localStorage.getItem(server.TOKEN_KEY) === null) {

            return props.history.push("/login");

        }

    }, []);


다음으로 아래 코드 스니펫에 표시된 것처럼 Formik 구성 요소를 사용하여 양식을 작성해야 합니다.


const showForm = ({

        values,

        errors,

        touched,

        handleChange,

        handleSubmit,

        isSubmitting,

    }) => {

        return (

            <form role="form" onSubmit={handleSubmit}>

                <div class="card-body">

                    <div class="row">

                        <div className="form-group col-md-6 input-group has-feedback">

                            <input

                                type="text"

                                name="name"

                                onChange={handleChange}

                                value={values.name}

                                className="form-control"

                                placeholder="Supplier Name"

                                className={

                                    errors.name && touched.name

                                        ? "form-control is-invalid"

                                        : "form-control"

                                }

                            />

                            <div class="input-group-append">

                                <div class="input-group-text">

                                    <span class="fas fa-user"></span>

                                </div>

                            </div>

                            {errors.name && touched.name ? (

                                <small id="passwordHelp" class="text-danger">

                                    {errors.name}

                                </small>

                            ) : null}

                        </div>

                    </div>

                    <div class="row">

                        <div className="form-group col-md-8 input-group has-feedback">

                            <textarea

                                name="address"

                                onChange={handleChange}

                                value={values.address}

                                className="form-control"

                                placeholder="Supplier Address"

                                className={

                                    errors.address && touched.address

                                        ? "form-control is-invalid"

                                        : "form-control"

                                }

                            ></textarea>

                            <div class="input-group-append">

                                <div class="input-group-text">

                                    <span class="fas fa-building"></span>

                                </div>

                            </div>

                            {errors.address && touched.address ? (

                                <small id="passwordHelp" class="text-danger">

                                    {errors.address}

                                </small>

                            ) : null}

                        </div>

                    </div>

                    <div className="form-group input-group has-feedback">

                        <input

                            type="text"

                            name="tel"

                            onChange={handleChange}

                            value={values.tel}

                            className="form-control"

                            placeholder="Supplier Telephone"

                            className={

                                errors.tel && touched.tel

                                    ? "form-control is-invalid"

                                    : "form-control"

                            }

                        />

                        {errors.tel && touched.tel ? (

                            <small id="passwordHelp" class="text-danger">

                                {errors.tel}

                            </small>

                        ) : null}

                    </div>

                    <div class="row">

                        <div className="form-group col-md-6 input-group has-feedback">

                            <input

                                type="email"

                                name="email"

                                onChange={handleChange}

                                value={values.email}

                                className="form-control "

                                placeholder="Supplier E-mail"

                                className={

                                    errors.email && touched.email

                                        ? "form-control is-invalid"

                                        : "form-control"

                                }

                            />

                            <div class="input-group-append">

                                <div class="input-group-text">

                                    <span class="fas fa-envelope"></span>

                                </div>

                            </div>

                            {errors.email && touched.email ? (

                                <small id="passwordHelp" class="text-danger">

                                    {errors.email}

                                </small>

                            ) : null}

                        </div>

                    </div>

                    <div class="row">

                        <div className="form-group col-md-6 input-group has-feedback">

                            <input

                                type="text"

                                name="vat"

                                onChange={handleChange}

                                value={values.vat}

                                className="form-control"

                                placeholder="Supplier Vat Number"

                                className={

                                    errors.vat && touched.vat

                                        ? "form-control is-invalid"

                                        : "form-control"

                                }

                            />

                            <div class="input-group-append">

                                <div class="input-group-text">

                                    <span class="fas fa-user"></span>

                                </div>

                            </div>

                            {errors.vat && touched.vat ? (

                                <small id="passwordHelp" class="text-danger">

                                    {errors.vat}

                                </small>

                            ) : null}

                        </div>


                    </div>

                    <div class="row">

                        <div class="offset-md-1 col-4">

                            <button

                                type="submit"

                                disabled={isSubmitting}

                                class="btn btn-primary btn-block"

                            >

                                Add

                             </button>

                        </div>

                    </div>

                </div>

            </form>

        );

    };


마지막으로 객체의 모든 구성을 래핑하고 supplierActions.action.js에 데이터를 보내는 기본 render() 함수를 추가해야 합니다. 여기에는 유효성 검사도 포함됩니다. render() 함수 내부의 코딩 구현은 아래 코드 스니펫에 제공됩니다.


return (

        <div className="content-wrapper">

            <div className="content-header">

                <div className="container-fluid">

                    <div className="row mb-2">

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


                            <h1 className="m-0 text-dark">Create Supplier</h1>

                        </div>

                    </div>

                    {/* /.row */}

                </div>

                {/* /.container-fluid */}

            </div>

            <div className="content">

                <div class="card card-success">

                    <div class="card-header">

                    </div>

                    <Formik

                        initialValues={{

                            name: "",

                            address: "",

                            tel: '',


                        }}

                        onSubmit={(values, { setSubmitting }) => {

                            console.log(values)

           dispatch(supplierActions.Create(values, props.history));

                            setSubmitting(false);

                        }}

                        validationSchema={Create_Schema}

                    >

                        {/* {this.showForm()}            */}

                        {(props) => showForm(props)}

                    </Formik>

                </div>

                {/* /.card */}

            </div>

        </div>

    );


따라서 결과 양식은 아래 스크린 샷과 같이 나타납니다.

"Supplier create" page 


5. 데이터베이스 스키마 


여기서 백엔드 프로젝트를 열어야 합니다. 백엔드 파트의 경우 아래 코드 스니펫에 표시된대로 mongoose 패키지를 사용하여 새 데이터베이스 스키마를 작성하는 것으로 시작하십시오.


const mongoose = require("mongoose");

const schema = mongoose.Schema({

    name: String,

    address: String,

    tel: String,

    email: String,

    vat: Number,

    created: { type: Date, default: Date.now },

});


module.exports = mongoose.model("supplier", schema);


이제 공급 업체 데이터를 저장하는 새로운 스키마가 생겼습니다.


6. 백엔드 API 구현 


다음으로 supplier_schema.js라는 새 파일을 만들고 아래 코드 스니펫에 표시된대로 API 엔드 포인트를 빌드 하는 데 필요한 컴포넌트를 가져와야 합니다.


const express = require("express");

const router = express.Router();

const supplier = require("./models/supplier_schema");

const jwt = require("./jwt");


그런 다음 클라이언트에서 데이터를 수신하고 새 행을 작성하려면 post post 메소드를 추가해야 합니다. post 함수의 구현은 아래 코드 스니펫에 나와 있습니다.


router.post("/supplier", async (req, res) => {

  try {


    let doc = await supplier.create(req.body);


    res.json({

      result: "success",

      message: "Create new Supplier data Successfully",

    });

  } catch (err) {

    console.log(err)

    res.json({ result: "error", message: err.msg });

  }

});


따라서 아래의 시뮬레이션 스크린 샷에 표시된 대로 양식에서 새 항목을 추가 할 수 있습니다.


Result of creating new supplier data 


따라서 Create 작업을 성공적으로 구현했습니다. 이제 인덱스 작업을 시작해야 합니다.


.....





댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.