diff --git a/codeidaca_client/src/Routes.js b/codeidaca_client/src/Routes.js index ae6b8cc..bc23713 100644 --- a/codeidaca_client/src/Routes.js +++ b/codeidaca_client/src/Routes.js @@ -20,6 +20,7 @@ import Location from './views/app/setting/MasterLocation/indexLocation' import Category from './views/app/setting/MasterCategory/indexCategory' import Module from './views/app/setting/MasterModule/indexModule' import Skill from './views/app/setting/MasterSkill/indexSkill' +import BatchEva from './views/app/batch/BatchStudentEvaluation'; @@ -57,6 +58,7 @@ export default function Routes(isLoggedIn) { { path: 'dashboard', element: isLoggedIn ? : }, { path: 'candidat', element: isLoggedIn ? : }, { path: 'batch', element: isLoggedIn ? : }, + { path: 'batch/evaluation/:id', element: }, { path: 'placement', element: isLoggedIn ? : }, { path: 'talent', element: isLoggedIn ? : }, { path: 'curriculum', element: isLoggedIn ? : }, diff --git a/codeidaca_client/src/api/api-bateva.js b/codeidaca_client/src/api/api-bateva.js new file mode 100644 index 0000000..26522e1 --- /dev/null +++ b/codeidaca_client/src/api/api-bateva.js @@ -0,0 +1,49 @@ +import axios from "axios"; +import config from "../config/config"; + +const list = async()=> { + + try { + const result = await axios.get(`${config.domain}/batch/evaluation/cari/aua`) + return result.data + } catch (error) { + return await error.message + } + +} + +const create = async(payload)=>{ + try { + // for (var pair of payload.entries()) { + // console.log(pair[0]+ ' - ' + pair[1]); + // } + const result = await axios.post(`${config.domain}/batch/evaluation`,payload) + // console.log(result.data) + return result.data + } catch (error) { + return await error.message + } +} + +const findOne = async(id)=>{ + try { + // const result = await axios.get(`${config.domain}/batch/evaluation/a/${id}`) + const result = await axios.get(`${config.domain}/batch/evaluation/${id}`) + return result.data + } catch (error) { + return error + } +} + +const findOne1 = async(id)=>{ + try { + const result = await axios.get(`${config.domain}/batch/evaluation/a/${id}`) + return result.data + } catch (error) { + return error + } +} + + +export default {list,create,findOne,findOne1,} + diff --git a/codeidaca_client/src/redux-saga/actions/BatEvaAction.js b/codeidaca_client/src/redux-saga/actions/BatEvaAction.js new file mode 100644 index 0000000..1e814df --- /dev/null +++ b/codeidaca_client/src/redux-saga/actions/BatEvaAction.js @@ -0,0 +1,30 @@ +import * as ActionType from "../constants/BatEvaConstant"; + +export const GetBatEvaRequest = () => ({ + type: ActionType.GET_BATEVA_REQUEST, +}); + +export const GetBatEvaSuccess = (payload) => ({ + type: ActionType.GET_BATEVA_SUCCESS, + payload, +}); + +export const GetBatEvaFailed = (payload) => ({ + type: ActionType.GET_BATEVA_FAILED, + payload, +}); + +export const AddBatEvaRequest = (payload) => ({ + type: ActionType.ADD_BATEVA_REQUEST, + payload, +}) + +export const AddBatEvaSuccess = (payload) => ({ + type: ActionType.ADD_BATEVA_SUCCESS, + payload, +}) + +export const AddBatEvaFailed = (payload) =>({ + type : ActionType.ADD_BATEVA_FAILED, + payload, +}) diff --git a/codeidaca_client/src/redux-saga/constants/BatEvaConstant.js b/codeidaca_client/src/redux-saga/constants/BatEvaConstant.js new file mode 100644 index 0000000..921d378 --- /dev/null +++ b/codeidaca_client/src/redux-saga/constants/BatEvaConstant.js @@ -0,0 +1,8 @@ +export const GET_BATEVA_REQUEST = "evaluation/get/request"; +export const GET_BATEVA_SUCCESS = "evaluation/get/success"; +export const GET_BATEVA_FAILED = "evaluation/get/failed"; + +export const ADD_BATEVA_REQUEST = 'evaluation/add/request' +export const ADD_BATEVA_SUCCESS = 'evaluation/add/success' +export const ADD_BATEVA_FAILED = 'evaluation/add/failed' + diff --git a/codeidaca_client/src/redux-saga/middleware/BatEvaMiddle.js b/codeidaca_client/src/redux-saga/middleware/BatEvaMiddle.js new file mode 100644 index 0000000..3fb86d1 --- /dev/null +++ b/codeidaca_client/src/redux-saga/middleware/BatEvaMiddle.js @@ -0,0 +1,36 @@ +import { + all, call, fork, put, takeEvery, takeLatest, + } from 'redux-saga/effects'; +import apiBateva from '../../api/api-bateva'; + + +import { + GetBatEvaSuccess, + GetBatEvaFailed, + AddBatEvaSuccess, + AddBatEvaFailed + +} from '../actions/BatEvaAction'; + +function* handleGetBatEva() { + try { + const result = yield call(apiBateva.findOne); + yield put(GetBatEvaSuccess(result)); + } catch (error) { + yield put(GetBatEvaFailed(error)); + } +} + +function* handleAddBatEva(action){ + const { payload } = action; + try { + const result = yield call(apiBateva.create, payload); + yield put(AddBatEvaSuccess(result)); + } catch (error) { + yield put(AddBatEvaFailed(error)); + } +} + + + +export { handleGetBatEva, handleAddBatEva}; \ No newline at end of file diff --git a/codeidaca_client/src/redux-saga/middleware/index.js b/codeidaca_client/src/redux-saga/middleware/index.js index 170a5df..51e3378 100644 --- a/codeidaca_client/src/redux-saga/middleware/index.js +++ b/codeidaca_client/src/redux-saga/middleware/index.js @@ -5,7 +5,7 @@ import * as ActionTypeProgramEntity from '../constants/ProgramEntity'; // import * as ActionCountryType from '../constants/Country' // import * as ActionProvince from '../constants/Province' import * as ActionMasterLocation from '../constants/MasterLocation' - +import * as ActionTypeBatEva from '../constants/BatEvaConstant' import {handleSignup,handleSignin,handleSignout} from './UserSaga' import {handleGetFourProgram,handleGetThreeCourse,handleGetAlumniTestimony} from './ProgramEntitySaga' @@ -20,7 +20,7 @@ import { handleAddCity,handleDelCity,handleEditCity,handleGetCity,handleGetOneCity } from './MasterLocationSaga' - +import {handleGetBatEva,handleAddBatEva} from './BatEvaMiddle' function *watchAll() { yield all([ takeEvery(ActionTypeUser.ADD_SIGNUP_REQUEST, handleSignup), @@ -55,6 +55,9 @@ function *watchAll() { takeEvery(ActionMasterLocation.ADD_CITY_REQUEST,handleAddCity), takeEvery(ActionMasterLocation.GETONE_CITY_REQUEST,handleGetOneCity), takeEvery(ActionMasterLocation.EDIT_CITY_REQUEST,handleEditCity), + + takeEvery(ActionTypeBatEva.GET_BATEVA_REQUEST, handleGetBatEva), + takeEvery(ActionTypeBatEva.ADD_BATEVA_REQUEST, handleAddBatEva) ]) } diff --git a/codeidaca_client/src/redux-saga/reducers/BatEvaReducer.js b/codeidaca_client/src/redux-saga/reducers/BatEvaReducer.js new file mode 100644 index 0000000..00af5c1 --- /dev/null +++ b/codeidaca_client/src/redux-saga/reducers/BatEvaReducer.js @@ -0,0 +1,58 @@ +import * as ActionType from "../constants/BatEvaConstant"; + +const INIT_STATE = { + BatEva: [], + status : {} +}; + +const BatEvaReducer = (state = INIT_STATE, action) => { + switch (action.type) { + case ActionType.GET_BATEVA_REQUEST: + return { + ...state, + status:"", + isLoading: true + + }; + + case ActionType.GET_BATEVA_SUCCESS: { + return GetBatEvaSucceed(state,action) + } + + case ActionType.ADD_BATEVA_REQUEST: { + return { + ...state, + status:"", + // isLoading: true, + // isRefresh: true + + }; + } + + case ActionType.ADD_BATEVA_SUCCESS: { + return AddBatEvaSucceed(state, action); + } + + + default: + return state; +} +}; + +const GetBatEvaSucceed = (state, action) => { + return { + ...state, + BatEva: action.payload, + }; +}; + +const AddBatEvaSucceed = (state,action) =>{ + const hasil = action.payload + return { + ...state, + BatEva:hasil, + status: hasil + }; +} + +export default BatEvaReducer; diff --git a/codeidaca_client/src/redux-saga/reducers/index.js b/codeidaca_client/src/redux-saga/reducers/index.js index cc9cf65..62f2f29 100644 --- a/codeidaca_client/src/redux-saga/reducers/index.js +++ b/codeidaca_client/src/redux-saga/reducers/index.js @@ -6,6 +6,7 @@ import CountryReduce from './CountryReducer'; import ProvinceReduce from './ProvinceReducer'; import CityReduce from './CityReducer'; import MasterLocationReduce from './MasterLocationReducer'; +import BatEvaReducer from './BatEvaReducer'; const rootReducer = combineReducers({ userState : userReducer, @@ -14,7 +15,8 @@ const rootReducer = combineReducers({ countryState:CountryReduce, provinceState:ProvinceReduce, cityState:CityReduce, - masterLocationState:MasterLocationReduce + masterLocationState:MasterLocationReduce, + BatEvaState : BatEvaReducer }); export default rootReducer; \ No newline at end of file diff --git a/codeidaca_client/src/views/app/batch/BatchStudentEvaluation.js b/codeidaca_client/src/views/app/batch/BatchStudentEvaluation.js new file mode 100644 index 0000000..7ea49ef --- /dev/null +++ b/codeidaca_client/src/views/app/batch/BatchStudentEvaluation.js @@ -0,0 +1,297 @@ +import Page from '../../../component/commons/Page'; +import React, { useState, useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { useFormik } from 'formik' +import { useNavigate, NavLink, Link, useParams, useLocation } from 'react-router-dom'; +import BatEvaApi from '../../../api/api-bateva' + +import * as Yup from "yup"; + +import { + GetBatEvaRequest, + DelBatEvaRequest, + AddBatEvaRequest, + AddBatEvaSuccess +} from "../../../redux-saga/actions/BatEvaAction"; + +export default function BatchStudentEvaluation(props) { + const dispatch = useDispatch() + const [BatEva, setBatEva] = useState() + let navigate = useNavigate(); + const {id} = useParams() + +// Get Data + +useEffect(() => { + BatEvaApi.findOne(id).then((data) => { + setBatEva(data) + }); +}, []) + + +const validationSchema = Yup.object().shape({ + base_grade: Yup.string("Enter Base Grade").required("Grade Fundamental is required"), + base_grade1: Yup.string("Enter Base Grade").required("Grade OOP is required"), + base_grade2: Yup.string("Enter Base Grade").required("Grade Database is required"), + base_grade3: Yup.string("Enter Base Grade").required("Grade Communication is required"), + base_grade4: Yup.string("Enter Base Grade").required("Grade Team Work is required"), + base_grade5: Yup.string("Enter Base Grade").required("Grade Self Learning is required"), + +}); + + +//Maping Untuk base_id +const BaseId = BatEva && + BatEva.map((count) => {return count.bast_id}) + +const formik = useFormik({ + + enableReinitialize: true, + initialValues: { + base_type : 'Technical', + base_type1 : 'Technical', + base_type2 : 'Technical', + base_type3 : 'Softskill', + base_type4 : 'Softskill', + base_type5 : 'Softskill', + + base_skill : 'Fundamental', + base_skill1 : 'Database', + base_skill2 : 'OOP', + base_skill3 : 'Communication', + base_skill4 : 'Teamwork', + base_skill5 : 'Self-Learning', + + base_grade : '', + base_grade1 : '', + base_grade2 : '', + base_grade3 : '', + base_grade4 : '', + base_grade5 : '', + + base_bast_id : BaseId, + + + + }, + validationSchema: validationSchema, + onSubmit: async (values) => { + let payload = new FormData(); + payload.append("base_type",values.base_type ); + payload.append("base_skill", values.base_skill); + payload.append("base_grade", parseInt(values.base_grade)); + payload.append("base_bast_id", parseInt(values.base_bast_id)); + + payload.append("base_type1",values.base_type1); + payload.append("base_skill1", values.base_skill1); + payload.append("base_grade1", parseInt(values.base_grade1)); + payload.append("base_bast_id1", parseInt(values.base_bast_id)); + + payload.append("base_type2",values.base_type2); + payload.append("base_skill2", values.base_skill2); + payload.append("base_grade2", parseInt(values.base_grade2)); + payload.append("base_bast_id2", parseInt(values.base_bast_id)); + + + payload.append("base_type3",values.base_type3); + payload.append("base_skill3", values.base_skill3); + payload.append("base_grade3", parseInt(values.base_grade3)); + payload.append("base_bast_id3", parseInt(values.base_bast_id)); + + + payload.append("base_type4",values.base_type4); + payload.append("base_skill4", values.base_skill4); + payload.append("base_grade4", parseInt(values.base_grade4)); + payload.append("base_bast_id4", parseInt(values.base_bast_id)); + + payload.append("base_type5",values.base_type5); + payload.append("base_skill5", values.base_skill5); + payload.append("base_grade5", parseInt(values.base_grade5)); + payload.append("base_bast_id5", parseInt(values.base_bast_id)); + + + window.alert("Data Berhasil Disimpan"); + dispatch(AddBatEvaRequest(payload)); + + navigate('/app/batch') + + }, +}); + + + return ( + + + {BatEva && + BatEva.map((count) => { + return ( + +
+
+ +
+
+

+ {count.batch_name} Bootcamp. NET Framework Evaluation +

+
+
+ + +
+
+
+
+
+ Avatar +
+
+

{count.user_first_name}

+

{count.batch_name}, {count.bast_status}

+

{count.batch_start_date} until {count.batch_end_date}

+
+
+

{count.usdu_school}

+

Jurusan {count.usdu_field_study}

+

IPK : {count.usdu_grade}

+ +
+
+

Score : {count.bast_total_score}

+
+
+ +
+
+
+
+
+ +

Technical

+
+
+
+
+
+
+

Fundamental

+

Object Oriented Programming (OOP)

+

Database

+
+
+ + {formik.touched.base_grade && formik.errors.base_grade ? ( + {formik.errors.base_grade} + ) : null} + + {formik.touched.base_grade1 && formik.errors.base_grade1 ? ( + {formik.errors.base_grade1} + ) : null} + + {formik.touched.base_grade2 && formik.errors.base_grade2 ? ( + {formik.errors.base_grade2} + ) : null} + +
+
+
+
+
+ +

Softskill

+
+
+
+
+
+
+

Communication

+

Teamwork

+

Self-Learning

+
+
+ + {formik.touched.base_grade3 && formik.errors.base_grade3 ? ( + {formik.errors.base_grade3} + ) : null} + + + {formik.touched.base_grade4 && formik.errors.base_grade4 ? ( + {formik.errors.base_grade4} + ) : null} + + {formik.touched.base_grade5 && formik.errors.base_grade5 ? ( + {formik.errors.base_grade5} + ) : null} + +
+
+
+
+
+ +

Presentation

+
+
+
+
+
+
+ +
+ + +
+
+ + +
+
+ ); + })} + +
+ ) +} diff --git a/codeidaca_server/server/config/config.js b/codeidaca_server/server/config/config.js index 6474522..2a629b0 100644 --- a/codeidaca_server/server/config/config.js +++ b/codeidaca_server/server/config/config.js @@ -2,9 +2,9 @@ const config = { env: process.env.NODE_ENV || 'development', port: 3001, jwtSecret: process.env.JWT_SECRET || "YOUR_secret_key", - db_name : "BootcampRevamp", + db_name : "bootcamp", db_username : "postgres", - db_password: "kevingreat", + db_password: "admin", URL_DOMAIN : '/codeid', URL_IMAGE : '/codeid/images/', URL_API : '/codeid/api', diff --git a/codeidaca_server/server/controller/BatchEvaluationController.js b/codeidaca_server/server/controller/BatchEvaluationController.js new file mode 100644 index 0000000..57e18eb --- /dev/null +++ b/codeidaca_server/server/controller/BatchEvaluationController.js @@ -0,0 +1,142 @@ + +import { sequelize } from "../models/init-models" + +const findOne = async (req,res)=>{ + try { + const batcheva = await req.context.models.batch_student.findOne({ + raw : true, + attributes: [ + 'bast_entity_id', + 'bast_id' + + ], + + where:{bast_entity_id : req.params.id} + }) + return res.send(batcheva) + } catch (error) { + return res.status(404).send(error) + } +} + + +const findAll = async(req,res) => { + try { + const result = await req.context.models.batch_student_evaluation.findAll({ + + attributes: [[sequelize.fn('max', sequelize.col('base_id')), 'base_id']], + + }) + res.send(result) + } catch (error) { + res.status(404).json(error.message); + } +} + +const create = async (req,res)=>{ + + try { + const { files, fields } = req.fileAttrb; + const result = await req.context.models.batch_student_evaluation.bulkCreate([{ + + base_type : fields[0].value, + base_skill : fields[1].value, + base_grade : parseInt(fields[2].value), + base_bast_id : parseInt(fields[3].value), + base_modified_date : new Date() + + }, { + + base_type : fields[4].value, + base_skill : fields[5].value, + base_grade : parseInt(fields[6].value), + base_bast_id : parseInt(fields[7].value), + base_modified_date : new Date() + }, + { + base_type : fields[8].value, + base_skill : fields[9].value, + base_grade : parseInt(fields[10].value), + base_bast_id : parseInt(fields[11].value), + base_modified_date : new Date() + }, + { + base_type : fields[12].value, + base_skill : fields[13].value, + base_grade : parseInt(fields[14].value), + base_bast_id : parseInt(fields[15].value), + base_modified_date : new Date() + }, + { + base_type : fields[16].value, + base_skill : fields[17].value, + base_grade : parseInt(fields[18].value), + base_bast_id : parseInt(fields[19].value), + base_modified_date : new Date() + }, + { + base_type : fields[20].value, + base_skill : fields[21].value, + base_grade : parseInt(fields[22].value), + base_bast_id : parseInt(fields[23].value), + base_modified_date : new Date() + } + ]) + return res.send(result) + } catch (error) { + return res.status(404).send(error) + } +} + +// const create = async (req,res)=>{ + +// try { +// const {files, fields} = req.fileAttrb; +// const result = await req.context.models.batch_student_evaluation.create({ + +// base_type : fields[0].value, +// base_skill :fields[1].value, +// base_grade : parseInt(fields[2].value), +// base_bast_id : parseInt(fields[3].value), +// } +// ) +// return res.send(result) +// } catch (error) { +// return res.status(404).send(error) +// } +// } +//Query Join +const querySQL = async(req,res)=>{ + try { + await sequelize.query(`SELECT + users.user_entity_id, users.user_first_name, + users.user_photo, + users_education.usdu_school, users_education.usdu_field_study, + users_education.usdu_grade, + batch.batch_name, batch.batch_start_date, + batch_end_date, + batch_student.bast_id, batch_student.bast_status, + batch_student.bast_total_score + FROM entity + INNER JOIN users ON entity.entity_id = users.user_entity_id + INNER JOIN users_education ON entity.entity_id = users_education.usdu_entity_id + INNER JOIN batch_student ON entity.entity_id = batch_student.bast_entity_id + INNER JOIN batch on batch_student.bast_batch_id = batch.batch_id + where entity_id = :entityId`, + {replacements : {entityId : req.params.id},type : sequelize.QueryTypes.SELECT}) + .then(result =>{ + return res.send(result) + }) + } catch (error) { + return res.status(404).send(error) + } +} + + +export default { + + findOne, + findAll, + create, + querySQL +} \ No newline at end of file diff --git a/codeidaca_server/server/index.js b/codeidaca_server/server/index.js index 842ca0f..7eecd12 100644 --- a/codeidaca_server/server/index.js +++ b/codeidaca_server/server/index.js @@ -49,6 +49,8 @@ app.use(config.URL_DOMAIN+"/country",routes.CountryRoute) app.use(config.URL_DOMAIN+"/province",routes.ProvinceRoute) app.use(config.URL_DOMAIN+"/city",routes.CityRoute) +app.use(config.URL_API+'/batch/evaluation',routes.BatEvaRoute) + //use middleware to handle error from others modules app.use(middleware.handleError); app.use(middleware.notFound); diff --git a/codeidaca_server/server/models/batch_student_evaluation.js b/codeidaca_server/server/models/batch_student_evaluation.js index 94e8453..3eebd8e 100644 --- a/codeidaca_server/server/models/batch_student_evaluation.js +++ b/codeidaca_server/server/models/batch_student_evaluation.js @@ -1,9 +1,6 @@ -import _sequelize from 'sequelize'; -const { Model, Sequelize } = _sequelize; - -export default class batch_student_evaluation extends Model { - static init(sequelize, DataTypes) { - return super.init({ +const Sequelize = require('sequelize'); +module.exports = function(sequelize, DataTypes) { + return sequelize.define('batch_student_evaluation', { base_id: { autoIncrement: true, type: DataTypes.INTEGER, @@ -57,5 +54,4 @@ export default class batch_student_evaluation extends Model { }, ] }); - } -} +}; diff --git a/codeidaca_server/server/routes/BatchEvaluationRoute.js b/codeidaca_server/server/routes/BatchEvaluationRoute.js new file mode 100644 index 0000000..a5fec18 --- /dev/null +++ b/codeidaca_server/server/routes/BatchEvaluationRoute.js @@ -0,0 +1,16 @@ +import { Router } from "express"; +import IndexController from "../controller/IndexController"; +import FormData from "../helpers/UploadDownloadHelper"; +const router = Router() + +router.get('/:id',IndexController.BatEvaController.querySQL) +router.get('/a/:id',IndexController.BatEvaController.findOne) +router.get('/b',IndexController.BatEvaController.findAll) +// router.get('/:id',IndexController.BatEvaController.findOne) +// router.get('/sql/:id',IndexController.BatEvaController.querySQL) +router.post('/',FormData.uploadSingleFile,IndexController.BatEvaController.create) +// router.get('/cari/aua',IndexController.BatEvaController.findAll) + + + +export default router \ No newline at end of file