Before Width: | Height: | Size: 77 KiB |
Before Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 37 KiB |
Before Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 162 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 173 KiB |
Before Width: | Height: | Size: 328 KiB |
@ -1,101 +0,0 @@
|
||||
{ |
||||
"type": "FeatureCollection", |
||||
"totalFeatures": "unknown", |
||||
"features": [ |
||||
{ |
||||
"type": "Feature", |
||||
"id": "paxel_area_code_20210426.5083", |
||||
"geometry": { |
||||
"type": "MultiPolygon", |
||||
"coordinates": [ |
||||
[ |
||||
[ |
||||
[ |
||||
106.522270001261, |
||||
-6.66321000044036 |
||||
], |
||||
[ |
||||
106.536260000699, |
||||
-6.66382999935416 |
||||
], |
||||
[ |
||||
106.556582195013, |
||||
-6.68497003983464 |
||||
], |
||||
[ |
||||
106.541310000657, |
||||
-6.71486999865072 |
||||
], |
||||
[ |
||||
106.542630000375, |
||||
-6.74058999942815 |
||||
], |
||||
[ |
||||
106.550740756582, |
||||
-6.7473471734325 |
||||
], |
||||
[ |
||||
106.533284161136, |
||||
-6.75148465469226 |
||||
], |
||||
[ |
||||
106.524773753407, |
||||
-6.76232523192311 |
||||
], |
||||
[ |
||||
106.498398062322, |
||||
-6.75218427058684 |
||||
], |
||||
[ |
||||
106.46682763259, |
||||
-6.75104031405846 |
||||
], |
||||
[ |
||||
106.459021692598, |
||||
-6.73381922767441 |
||||
], |
||||
[ |
||||
106.481760000125, |
||||
-6.72494999944212 |
||||
], |
||||
[ |
||||
106.504030000085, |
||||
-6.70412999979885 |
||||
], |
||||
[ |
||||
106.51431934866, |
||||
-6.65951255475977 |
||||
], |
||||
[ |
||||
106.522270001261, |
||||
-6.66321000044036 |
||||
] |
||||
] |
||||
] |
||||
] |
||||
}, |
||||
"geometry_name": "the_geom", |
||||
"properties": { |
||||
"fid": 37287, |
||||
"desa": "MALASARI", |
||||
"provinsi": "JAWA BARAT", |
||||
"kabkot": "BOGOR", |
||||
"kecamatan": "NANGGUNG", |
||||
"post_code": null, |
||||
"city_code": "", |
||||
"ph_code": "", |
||||
"locker_cod": "", |
||||
"area_code": "", |
||||
"id": 37287, |
||||
"cluster_area_code": "", |
||||
"service_ty": null |
||||
} |
||||
} |
||||
], |
||||
"crs": { |
||||
"type": "name", |
||||
"properties": { |
||||
"name": "urn:ogc:def:crs:EPSG::4326" |
||||
} |
||||
} |
||||
} |
@ -1,7 +0,0 @@
|
||||
{ |
||||
"routes": [ |
||||
{ |
||||
"geometry": "hldhx@lnau`BCG_EaC??cFjAwDjF??uBlKMd@}@z@??aC^yk@z_@se@b[wFdE??wFfE}NfIoGxB_I\\gG}@eHoCyTmPqGaBaHOoD\\??yVrGotA|N??o[N_STiwAtEmHGeHcAkiA}^aMyBiHOkFNoI`CcVvM??gG^gF_@iJwC??eCcA]OoL}DwFyCaCgCcCwDcGwHsSoX??wI_EkUFmq@hBiOqBgTwS??iYse@gYq\\cp@ce@{vA}s@csJqaE}{@iRaqE{lBeRoIwd@_T{]_Ngn@{PmhEwaA{SeF_u@kQuyAw]wQeEgtAsZ}LiCarAkVwI}D??_}RcjEinPspDwSqCgs@sPua@_OkXaMeT_Nwk@ob@gV}TiYs[uTwXoNmT{Uyb@wNg]{Nqa@oDgNeJu_@_G}YsFw]kDuZyDmm@i_@uyIJe~@jCg|@nGiv@zUi_BfNqaAvIow@dEed@dCcf@r@qz@Egs@{Acu@mCum@yIey@gGig@cK_m@aSku@qRil@we@{mAeTej@}Tkz@cLgr@aHko@qOmcEaJw~C{w@kai@qBchBq@kmBS{kDnBscBnFu_Dbc@_~QHeU`IuyDrC_}@bByp@fCyoA?qMbD}{AIkeAgBk_A_A{UsDke@gFej@qH{o@qGgb@qH{`@mMgm@uQus@kL{_@yOmd@ymBgwE}x@ouBwtA__DuhEgaKuWct@gp@cnBii@mlBa_@}|Asj@qrCg^eaC}L{dAaJ_aAiOyjByH{nAuYu`GsAwXyn@ywMyOyqD{_@cfIcDe}@y@aeBJmwA`CkiAbFkhBlTgdDdPyiB`W}xDnSa}DbJyhCrXitAhT}x@bE}Z_@qW_Kwv@qKaaAiBgXvIm}A~JovAxCqW~WanB`XewBbK{_A`K}fBvAmi@xBycBeCauBoF}}@qJioAww@gjHaPopA_NurAyJku@uGmi@cDs[eRaiBkQstAsQkcByNmaCsK_uBcJgbEw@gkB_@ypEqDoqSm@eZcDwjBoGw`BoMegBaU_`Ce_@_uBqb@ytBwkFqiT_fAqfEwe@mfCka@_eC_UmlB}MmaBeWkkDeHwqAoX}~DcBsZmLcxBqOwqE_DkyAuJmrJ\\o~CfIewG|YibQxBssB?es@qGciA}RorAoVajA_nAodD{[y`AgPqp@mKwr@ms@umEaW{dAmb@umAw|@ojBwzDaaJsmBwbEgdCsrFqhAihDquAi`Fux@}_Dui@_eB_u@guCuyAuiHukA_lKszAu|OmaA{wKm}@clHs_A_rEahCssKo\\sgBsSglAqk@yvDcS_wAyTwpBmPc|BwZknFoFscB_GsaDiZmyMyLgtHgQonHqT{hKaPg}Dqq@m~Hym@c`EuiBudIabB{hF{pWifx@snAw`GkFyVqf@y~BkoAi}Lel@wtc@}`@oaXi_C}pZsi@eqGsSuqJ|Lqeb@e]kgPcaAu}SkDwzGhn@gjYh\\qlNZovJieBqja@ed@siO{[ol\\kCmjMe\\isHorCmec@uLebB}EqiBaCg}@m@qwHrT_vFps@kkI`uAszIrpHuzYxx@e{Crw@kpDhN{wBtQarDy@knFgP_yCu\\wyCwyA{kHo~@omEoYmoDaEcPiuAosDagD}rO{{AsyEihCayFilLaiUqm@_bAumFo}DgqA_uByi@swC~AkzDlhA}xEvcBa}Cxk@ql@`rAo|@~bBq{@``Bye@djDww@z_C_cAtn@ye@nfC_eC|gGahH~s@w}@``Fi~FpnAooC|u@wlEaEedRlYkrPvKerBfYs}Arg@m}AtrCkzElw@gjBbh@woBhR{gCwGkgCc[wtCuOapAcFoh@uBy[yBgr@c@iq@o@wvEv@sp@`FajBfCaq@fIipAdy@ewJlUc`ExGuaBdEmbBpBssArAuqBBg}@s@g{AkB{bBif@_bYmC}r@kDgm@sPq_BuJ_s@{X_{AsK_d@eM{d@wVgx@oWcu@??aDmOkNia@wFoSmDyMyCkPiBePwAob@XcQ|@oNdCoSfFwXhEmOnLi\\lbAulB`X_d@|k@au@bc@oc@bqC}{BhwDgcD`l@ed@??bL{G|a@eTje@oS~]cLr~Bgh@|b@}Jv}EieAlv@sPluD{z@nzA_]`|KchCtd@sPvb@wSb{@ko@f`RooQ~e[upZbuIolI|gFafFzu@iq@nMmJ|OeJn^{Qjh@yQhc@uJ~j@iGdd@kAp~BkBxO{@|QsAfYgEtYiGd]}Jpd@wRhVoNzNeK`j@ce@vgK}cJnSoSzQkVvUm^rSgc@`Uql@xIq\\vIgg@~kDyq[nIir@jNoq@xNwc@fYik@tk@su@neB}uBhqEesFjoGeyHtCoD|D}Ed|@ctAbIuOzqB_}D~NgY`\\um@v[gm@v{Cw`G`w@o{AdjAwzBh{C}`Gpp@ypAxn@}mAfz@{bBbNia@??jIab@`CuOlC}YnAcV`@_^m@aeB}@yk@YuTuBg^uCkZiGk\\yGeY}Lu_@oOsZiTe[uWi[sl@mo@soAauAsrBgzBqgAglAyd@ig@asAcyAklA}qAwHkGi{@s~@goAmsAyDeEirB_{B}IsJuEeFymAssAkdAmhAyTcVkFeEoKiH}l@kp@wg@sj@ku@ey@uh@kj@}EsFmG}Jk^_r@_f@m~@ym@yjA??a@cFd@kBrCgDbAUnAcBhAyAdk@et@??kF}D??OL" |
||||
} |
||||
] |
||||
} |
@ -1,257 +0,0 @@
|
||||
{ |
||||
"geocoded_waypoints": [ |
||||
{ |
||||
"geocoder_status": "OK", |
||||
"place_id": "ChIJT2zELKHxaS4RR5fpIKhtekA", |
||||
"types": [ |
||||
"street_address" |
||||
] |
||||
}, |
||||
{ |
||||
"geocoder_status": "OK", |
||||
"place_id": "ChIJdbdzpG7xaS4RUCaaEC6NIOo", |
||||
"types": [ |
||||
"street_address" |
||||
] |
||||
} |
||||
], |
||||
"routes": [ |
||||
{ |
||||
"bounds": { |
||||
"northeast": { |
||||
"lat": -6.245234399999999, |
||||
"lng": 106.8006477 |
||||
}, |
||||
"southwest": { |
||||
"lat": -6.2623544, |
||||
"lng": 106.7885345 |
||||
} |
||||
}, |
||||
"copyrights": "Map data ©2021", |
||||
"legs": [ |
||||
{ |
||||
"distance": { |
||||
"text": "3.0 km", |
||||
"value": 2992 |
||||
}, |
||||
"duration": { |
||||
"text": "9 mins", |
||||
"value": 552 |
||||
}, |
||||
"end_address": "Jl. Melawai 5 No.172, RT.3/RW.1, Melawai, Kec. Kby. Baru, Kota Jakarta Selatan, Daerah Khusus Ibukota Jakarta 12160, Indonesia", |
||||
"end_location": { |
||||
"lat": -6.245234399999999, |
||||
"lng": 106.8006477 |
||||
}, |
||||
"start_address": "Jl. Bri Radio Dalam No.34/4, RT.2/RW.15, Gandaria Utara, Kec. Kby. Baru, Kota Jakarta Selatan, Daerah Khusus Ibukota Jakarta 12140, Indonesia", |
||||
"start_location": { |
||||
"lat": -6.2623544, |
||||
"lng": 106.7885345 |
||||
}, |
||||
"steps": [ |
||||
{ |
||||
"distance": { |
||||
"text": "1.5 km", |
||||
"value": 1495 |
||||
}, |
||||
"duration": { |
||||
"text": "4 mins", |
||||
"value": 221 |
||||
}, |
||||
"end_location": { |
||||
"lat": -6.2493628, |
||||
"lng": 106.7918222 |
||||
}, |
||||
"html_instructions": "Head <b>north</b> on <b>Jl. Radio Dalam Raya</b> toward <b>Jl. Dwijaya Raya</b><div style=\"font-size:0.9em\">Pass by Alfamart Radio Dalam 4 (on the right)</div>", |
||||
"polyline": { |
||||
"points": "tbfe@icxjSOEs@M}@K}C]m@KUKg@G[EKAQCaAO_@GGAoB[SEaCa@e@Ga@GuB]yA[{Ba@iAYkA[a@KqAi@w@WaA[KCgAYQCMAw@I}AKUCeAOQCoAUMCoAQyAQc@EcBKe@C}@IC?g@E_AG" |
||||
}, |
||||
"start_location": { |
||||
"lat": -6.2623544, |
||||
"lng": 106.7885345 |
||||
}, |
||||
"travel_mode": "DRIVING" |
||||
}, |
||||
{ |
||||
"distance": { |
||||
"text": "0.5 km", |
||||
"value": 532 |
||||
}, |
||||
"duration": { |
||||
"text": "2 mins", |
||||
"value": 99 |
||||
}, |
||||
"end_location": { |
||||
"lat": -6.2491213, |
||||
"lng": 106.7959681 |
||||
}, |
||||
"html_instructions": "Turn <b>right</b> onto <b>Jl. Kramat Pela</b>", |
||||
"maneuver": "turn-right", |
||||
"polyline": { |
||||
"points": "nqce@{wxjSMA\\sBJm@JOBQFa@h@cC@EN_@Le@Hc@?QBQBIDQ@Q@O?UASCSAMCGEGU]QSWWQUq@q@MGQEGAKA" |
||||
}, |
||||
"start_location": { |
||||
"lat": -6.2493628, |
||||
"lng": 106.7918222 |
||||
}, |
||||
"travel_mode": "DRIVING" |
||||
}, |
||||
{ |
||||
"distance": { |
||||
"text": "25 m", |
||||
"value": 25 |
||||
}, |
||||
"duration": { |
||||
"text": "1 min", |
||||
"value": 4 |
||||
}, |
||||
"end_location": { |
||||
"lat": -6.249124, |
||||
"lng": 106.7961904 |
||||
}, |
||||
"html_instructions": "Turn <b>right</b> toward <b>Jl. Barito II</b>", |
||||
"maneuver": "turn-right", |
||||
"polyline": { |
||||
"points": "~oce@yqyjSAK@_@" |
||||
}, |
||||
"start_location": { |
||||
"lat": -6.2491213, |
||||
"lng": 106.7959681 |
||||
}, |
||||
"travel_mode": "DRIVING" |
||||
}, |
||||
{ |
||||
"distance": { |
||||
"text": "0.2 km", |
||||
"value": 154 |
||||
}, |
||||
"duration": { |
||||
"text": "1 min", |
||||
"value": 36 |
||||
}, |
||||
"end_location": { |
||||
"lat": -6.249612600000001, |
||||
"lng": 106.7974484 |
||||
}, |
||||
"html_instructions": "Turn <b>right</b> onto <b>Jl. Barito II</b>", |
||||
"maneuver": "turn-right", |
||||
"polyline": { |
||||
"points": "~oce@esyjS`@_@P[JSJ]DM@KH}@Bu@" |
||||
}, |
||||
"start_location": { |
||||
"lat": -6.249124, |
||||
"lng": 106.7961904 |
||||
}, |
||||
"travel_mode": "DRIVING" |
||||
}, |
||||
{ |
||||
"distance": { |
||||
"text": "0.4 km", |
||||
"value": 414 |
||||
}, |
||||
"duration": { |
||||
"text": "1 min", |
||||
"value": 77 |
||||
}, |
||||
"end_location": { |
||||
"lat": -6.2459198, |
||||
"lng": 106.7979545 |
||||
}, |
||||
"html_instructions": "Turn <b>left</b> onto <b>Jl. Panglima Polim</b> (signs for <b>Senayan</b>/<wbr/><b>Semanggi</b>)<div style=\"font-size:0.9em\">Pass by ATM Bank UOB (on the left)</div>", |
||||
"maneuver": "turn-left", |
||||
"polyline": { |
||||
"points": "`sce@a{yjSmBMgDUyBQGAyDW[CgAIk@E" |
||||
}, |
||||
"start_location": { |
||||
"lat": -6.249612600000001, |
||||
"lng": 106.7974484 |
||||
}, |
||||
"travel_mode": "DRIVING" |
||||
}, |
||||
{ |
||||
"distance": { |
||||
"text": "0.2 km", |
||||
"value": 220 |
||||
}, |
||||
"duration": { |
||||
"text": "1 min", |
||||
"value": 48 |
||||
}, |
||||
"end_location": { |
||||
"lat": -6.245905899999999, |
||||
"lng": 106.7999397 |
||||
}, |
||||
"html_instructions": "Turn <b>right</b> onto <b>Jl. Melawai Raya</b><div style=\"font-size:0.9em\">Pass by MM Juice Melawai (on the right)</div>", |
||||
"maneuver": "turn-right", |
||||
"polyline": { |
||||
"points": "~{be@e~yjS?SAq@?S?A?]Cg@AKD_F" |
||||
}, |
||||
"start_location": { |
||||
"lat": -6.2459198, |
||||
"lng": 106.7979545 |
||||
}, |
||||
"travel_mode": "DRIVING" |
||||
}, |
||||
{ |
||||
"distance": { |
||||
"text": "74 m", |
||||
"value": 74 |
||||
}, |
||||
"duration": { |
||||
"text": "1 min", |
||||
"value": 33 |
||||
}, |
||||
"end_location": { |
||||
"lat": -6.2452361, |
||||
"lng": 106.7999455 |
||||
}, |
||||
"html_instructions": "Turn <b>left</b> after HAZEL Brew Coffee (on the right)", |
||||
"maneuver": "turn-left", |
||||
"polyline": { |
||||
"points": "|{be@sjzjSO?C?_@?qAA" |
||||
}, |
||||
"start_location": { |
||||
"lat": -6.245905899999999, |
||||
"lng": 106.7999397 |
||||
}, |
||||
"travel_mode": "DRIVING" |
||||
}, |
||||
{ |
||||
"distance": { |
||||
"text": "78 m", |
||||
"value": 78 |
||||
}, |
||||
"duration": { |
||||
"text": "1 min", |
||||
"value": 34 |
||||
}, |
||||
"end_location": { |
||||
"lat": -6.245234399999999, |
||||
"lng": 106.8006477 |
||||
}, |
||||
"html_instructions": "Turn <b>right</b> onto <b>Jl. Melawai 9</b><div style=\"font-size:0.9em\">Destination will be on the left</div>", |
||||
"maneuver": "turn-right", |
||||
"polyline": { |
||||
"points": "vwbe@ujzjSAkC" |
||||
}, |
||||
"start_location": { |
||||
"lat": -6.2452361, |
||||
"lng": 106.7999455 |
||||
}, |
||||
"travel_mode": "DRIVING" |
||||
} |
||||
], |
||||
"traffic_speed_entry": [], |
||||
"via_waypoint": [] |
||||
} |
||||
], |
||||
"overview_polyline": { |
||||
"points": "tbfe@icxjScAS{Ei@m@KUKcAM_C]mGeAgAOoEy@eE{@mBg@iCaAmA_@yA]eAKsBOwAS}AYiDc@kF_@yBOh@aDJOBQFa@h@cCPe@ViABc@H[Ba@Ai@Ea@IOg@q@i@m@q@q@MGYGKAAK@_@`@_@\\o@Pk@JiABu@mBMaHg@eHg@k@E?SAeAEsAD_FO?c@?qAAAkC" |
||||
}, |
||||
"summary": "Jl. Radio Dalam Raya", |
||||
"warnings": [], |
||||
"waypoint_order": [] |
||||
} |
||||
], |
||||
"status": "OK" |
||||
} |
@ -1,259 +0,0 @@
|
||||
{ |
||||
"type": "FeatureCollection", |
||||
"features": [ |
||||
{ |
||||
"id": "sales.1", |
||||
"geometry_name": "the_geom", |
||||
"type": "Feature", |
||||
"properties": { |
||||
"id": "sales.1", |
||||
"name": "Sales 1" |
||||
}, |
||||
"geometry": { |
||||
"type": "LineString", |
||||
"coordinates": [ |
||||
[ |
||||
106.78853, |
||||
-6.26235 |
||||
], |
||||
[ |
||||
106.78863, |
||||
-6.26201 |
||||
], |
||||
[ |
||||
106.78884, |
||||
-6.26091 |
||||
], |
||||
[ |
||||
106.7889, |
||||
-6.26068 |
||||
], |
||||
[ |
||||
106.78896, |
||||
-6.26057 |
||||
], |
||||
[ |
||||
106.78903, |
||||
-6.26023 |
||||
], |
||||
[ |
||||
106.78918, |
||||
-6.25959 |
||||
], |
||||
[ |
||||
106.78953, |
||||
-6.25824 |
||||
], |
||||
[ |
||||
106.78961, |
||||
-6.25788 |
||||
], |
||||
[ |
||||
106.7899, |
||||
-6.25684 |
||||
], |
||||
[ |
||||
106.7902, |
||||
-6.25585 |
||||
], |
||||
[ |
||||
106.7904, |
||||
-6.2553 |
||||
], |
||||
[ |
||||
106.79073, |
||||
-6.25461 |
||||
], |
||||
[ |
||||
106.79089, |
||||
-6.25422 |
||||
], |
||||
[ |
||||
106.79104, |
||||
-6.25377 |
||||
], |
||||
[ |
||||
106.7911, |
||||
-6.25342 |
||||
], |
||||
[ |
||||
106.79118, |
||||
-6.25284 |
||||
], |
||||
[ |
||||
106.79128, |
||||
-6.2524 |
||||
], |
||||
[ |
||||
106.79141, |
||||
-6.25193 |
||||
], |
||||
[ |
||||
106.79159, |
||||
-6.25108 |
||||
], |
||||
[ |
||||
106.79175, |
||||
-6.2499 |
||||
], |
||||
[ |
||||
106.79183, |
||||
-6.24929 |
||||
], |
||||
[ |
||||
106.79264, |
||||
-6.2495 |
||||
], |
||||
[ |
||||
106.79272, |
||||
-6.24956 |
||||
], |
||||
[ |
||||
106.79281, |
||||
-6.24958 |
||||
], |
||||
[ |
||||
106.79298, |
||||
-6.24962 |
||||
], |
||||
[ |
||||
106.79364, |
||||
-6.24983 |
||||
], |
||||
[ |
||||
106.79383, |
||||
-6.24992 |
||||
], |
||||
[ |
||||
106.7942, |
||||
-6.25004 |
||||
], |
||||
[ |
||||
106.79438, |
||||
-6.25006 |
||||
], |
||||
[ |
||||
106.79452, |
||||
-6.25011 |
||||
], |
||||
[ |
||||
106.79469, |
||||
-6.25013 |
||||
], |
||||
[ |
||||
106.7949, |
||||
-6.25012 |
||||
], |
||||
[ |
||||
106.79507, |
||||
-6.25009 |
||||
], |
||||
[ |
||||
106.79515, |
||||
-6.25004 |
||||
], |
||||
[ |
||||
106.7954, |
||||
-6.24984 |
||||
], |
||||
[ |
||||
106.79563, |
||||
-6.24963 |
||||
], |
||||
[ |
||||
106.79588, |
||||
-6.24938 |
||||
], |
||||
[ |
||||
106.79592, |
||||
-6.24931 |
||||
], |
||||
[ |
||||
106.79596, |
||||
-6.24918 |
||||
], |
||||
[ |
||||
106.79597, |
||||
-6.24912 |
||||
], |
||||
[ |
||||
106.79603, |
||||
-6.24911 |
||||
], |
||||
[ |
||||
106.79619, |
||||
-6.24912 |
||||
], |
||||
[ |
||||
106.79635, |
||||
-6.24929 |
||||
], |
||||
[ |
||||
106.79659, |
||||
-6.24944 |
||||
], |
||||
[ |
||||
106.79681, |
||||
-6.24953 |
||||
], |
||||
[ |
||||
106.79718, |
||||
-6.24959 |
||||
], |
||||
[ |
||||
106.79745, |
||||
-6.24961 |
||||
], |
||||
[ |
||||
106.79752, |
||||
-6.24906 |
||||
], |
||||
[ |
||||
106.79772, |
||||
-6.24761 |
||||
], |
||||
[ |
||||
106.79792, |
||||
-6.24614 |
||||
], |
||||
[ |
||||
106.79795, |
||||
-6.24592 |
||||
], |
||||
[ |
||||
106.79805, |
||||
-6.24592 |
||||
], |
||||
[ |
||||
106.7984, |
||||
-6.24591 |
||||
], |
||||
[ |
||||
106.79882, |
||||
-6.24588 |
||||
], |
||||
[ |
||||
106.79994, |
||||
-6.24591 |
||||
], |
||||
[ |
||||
106.79994, |
||||
-6.24583 |
||||
], |
||||
[ |
||||
106.79994, |
||||
-6.24565 |
||||
], |
||||
[ |
||||
106.79995, |
||||
-6.24524 |
||||
], |
||||
[ |
||||
106.80065, |
||||
-6.24523 |
||||
] |
||||
] |
||||
} |
||||
} |
||||
] |
||||
} |
@ -1,85 +0,0 @@
|
||||
{ |
||||
"type": "FeatureCollection", |
||||
"features": [ |
||||
{ |
||||
"id": "sales.1", |
||||
"geometry_name": "the_geom", |
||||
"type": "Feature", |
||||
"properties": { |
||||
"id": "sales.1", |
||||
"name": "Sales 1" |
||||
}, |
||||
"geometry": { |
||||
"type": "Point", |
||||
"coordinates": [ |
||||
106.79569244384766, |
||||
-6.2395378839383016 |
||||
] |
||||
} |
||||
}, |
||||
{ |
||||
"id": "sales.2", |
||||
"geometry_name": "the_geom", |
||||
"type": "Feature", |
||||
"properties": { |
||||
"id": "sales.2", |
||||
"name": "Sales 2" |
||||
}, |
||||
"geometry": { |
||||
"type": "Point", |
||||
"coordinates": [ |
||||
106.78788185119627, |
||||
-6.2620624718682665 |
||||
] |
||||
} |
||||
}, |
||||
{ |
||||
"id": "sales.3", |
||||
"geometry_name": "the_geom", |
||||
"type": "Feature", |
||||
"properties": { |
||||
"id": "sales.3", |
||||
"name": "Sales 3" |
||||
}, |
||||
"geometry": { |
||||
"type": "Point", |
||||
"coordinates": [ |
||||
106.81011199951172, |
||||
-6.249349850172153 |
||||
] |
||||
} |
||||
}, |
||||
{ |
||||
"id": "sales.4", |
||||
"geometry_name": "the_geom", |
||||
"type": "Feature", |
||||
"properties": { |
||||
"id": "sales.4", |
||||
"name": "Sales 4" |
||||
}, |
||||
"geometry": { |
||||
"type": "Point", |
||||
"coordinates": [ |
||||
106.81543350219727, |
||||
-6.215817763782759 |
||||
] |
||||
} |
||||
}, |
||||
{ |
||||
"id": "sales.5", |
||||
"geometry_name": "the_geom", |
||||
"type": "Feature", |
||||
"properties": { |
||||
"id": "sales.5", |
||||
"name": "Sales 5" |
||||
}, |
||||
"geometry": { |
||||
"type": "Point", |
||||
"coordinates": [ |
||||
106.80745124816895, |
||||
-6.2746041510497355 |
||||
] |
||||
} |
||||
} |
||||
] |
||||
} |
@ -1,37 +0,0 @@
|
||||
import React from 'react'; |
||||
const ChatDashboard = (props) => { |
||||
const { dataParams } = props; |
||||
|
||||
const renderComment = (items) => { |
||||
return items.map((item, idx) => { |
||||
return ( |
||||
<div className="chat-content" key={idx}> |
||||
<div className='chat-body'> |
||||
<div className='chat-header'> |
||||
{item.comment_by} |
||||
</div> |
||||
<div className='chat-body-content'> |
||||
{item.comment} |
||||
</div> |
||||
<div className='chat-footer'> |
||||
{item.comment_created} |
||||
</div> |
||||
</div> |
||||
</div> |
||||
) |
||||
}) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<div style={{ margin: '0 5px' }} className="box-header-dashboard-project"> |
||||
<div style={{ display: 'flex', justifyContent: 'center' }}> |
||||
<div style={{ marginBottom: '5px', fontSize: '0.8rem', fontWeight: '500' }}>COMMUNICATION</div> |
||||
</div> |
||||
<div className='chat'> |
||||
{renderComment(dataParams)} |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
export default ChatDashboard; |
@ -1,34 +0,0 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react'; |
||||
import Timeline from 'react-calendar-timeline' |
||||
// make sure you include the timeline stylesheet or the timeline will not be styled
|
||||
import 'react-calendar-timeline/lib/Timeline.css' |
||||
import { useParams } from 'react-router-dom'; |
||||
// import moment from 'moment';
|
||||
// import { USER_VERSION_GANTT_SEARCH, BASE_SIMPRO_LUMEN } from '../../../const/ApiConst';
|
||||
// import axios from "../../../const/interceptorApi"
|
||||
const token = localStorage.getItem("token") |
||||
|
||||
const Gantt = (props) => { |
||||
const { ID } = useParams(); |
||||
const { GANTTID } = useParams(); |
||||
const url = `https://konstruksi-gantt.ospro.id/view-mode/index.html?base_url=${BASE_OSPRO}/api&gantt_id=${GANTT_ID}&proyek_id=${PROJECT_ID}&token=${token}&ro=1` |
||||
|
||||
const RenderGantt = () => ( |
||||
<iframe |
||||
id="frame-gantt" |
||||
src={url} |
||||
style={{ |
||||
width: '100%', |
||||
height: '50vh', |
||||
}} |
||||
scrolling="no" |
||||
frameBorder="0" |
||||
></iframe> |
||||
) |
||||
return ( |
||||
<div> |
||||
<RenderGantt /> |
||||
</div> |
||||
); |
||||
} |
||||
export default Gantt; |
@ -1,275 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react'; |
||||
import { Row, Col, Select, Divider } from 'antd'; |
||||
import moment from 'moment' |
||||
import Gantt from './ganttDashboard'; |
||||
import ChatDashboard from './chatDashboard'; |
||||
import axios from 'axios' |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { useParams } from 'react-router-dom'; |
||||
import { Badge } from 'reactstrap'; |
||||
import { BASE_OSPRO, BASE_INTEGRATION_V1, TOKEN_ADW } from '../../const/ApiConst'; |
||||
import {formatRibuanDecimal} from "../../const/CustomFunc"; |
||||
import ProgressBar from "./progressBar"; |
||||
import numeral from 'numeral'; |
||||
|
||||
function BoxDashboard({ value, title, secondaryTitle, icon, bgColor }) { |
||||
return ( |
||||
<div style={{ backgroundColor: bgColor }} className='box-header-dashboard-project'> |
||||
<div style={{ display: 'flex', justifyContent: 'space-between' }}> |
||||
<div style={{ fontSize: '0.8rem', fontWeight: 500, color: '#fff', textTransform: 'uppercase' }}>{title}</div> |
||||
<div>{icon}</div> |
||||
</div> |
||||
<div style={{ fontSize: '1rem', fontWeight: 500, color: '#fff' }}>{value}</div> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
function RenderHealthProject({params}){ |
||||
if (params == "on-budget") { |
||||
return (<Badge style = {{fontSize:"18px"}} color="success">On Budget</Badge>) |
||||
} else if (params == "warning") { |
||||
return (<Badge style = {{fontSize:"18px"}} color="warning">Warning</Badge>) |
||||
} else { |
||||
return (<Badge style = {{fontSize:"18px"}} color="danger">Danger</Badge>) |
||||
} |
||||
} |
||||
|
||||
const DashboardProject = () => { |
||||
|
||||
const { ID } = useParams(); |
||||
const [STATUSPROJECT, SET_STATUSPROJECT] = useState([]) |
||||
const [PROJECTMGR, SET_PROJECTMGR] = useState([]) |
||||
const [RO, SET_RO] = useState([]) |
||||
// Schedule
|
||||
const [STARTDATE, SET_STARTDATE] = useState([]) |
||||
const [BASELINEFINISHDATE, SET_BASELINEFINISHDATE] = useState([]) |
||||
const [ESTFINISHDATE, SET_ESTFINISHDATE] = useState([]) |
||||
// Financials
|
||||
const [BCWP, SET_BCWP] = useState([]) |
||||
const [ACWP, SET_ACWP] = useState([]) |
||||
const [VARIANCE, SET_VARIANCE] = useState([]) |
||||
const [PROGRESS, SET_PROGRESS] = useState([]) |
||||
const [BUDGET, SET_BUDGET] = useState([]) |
||||
const [PROJECTNAME, SET_PROJECTNAME] = useState([]) |
||||
const [CURRENCYSYMBOL, SET_CURRENCYSYMBOL] = useState([]) |
||||
const [BUDGETHEALTH, SET_BUDGETHEALTH] = useState([]) |
||||
const [COMMENT, SET_COMMENT] = useState([]) |
||||
const [MANPOWER, SET_MANPOWER] = useState([0]) |
||||
|
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
|
||||
const HEADER_INTEGRASI = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `${TOKEN_ADW}` |
||||
} |
||||
} |
||||
|
||||
const getProjectDetail = async () => { |
||||
const URL = `${BASE_OSPRO}/api/project/dashboard/${ID}` |
||||
const result = await axios.get(URL, HEADER).then(res => res).catch(err => err.response) |
||||
|
||||
if (result.data.code !== 200) { |
||||
NotificationManager.error(result.data.message, 'Failed'); |
||||
} |
||||
|
||||
if(result.data.code == 200) { |
||||
let resData = result.data.data; |
||||
SET_BUDGET(resData.rencana_biaya) |
||||
SET_PROJECTMGR(resData.pm) |
||||
SET_RO(resData.company) |
||||
SET_PROJECTNAME(resData.name_project) |
||||
SET_STARTDATE(resData.start) |
||||
SET_BASELINEFINISHDATE(resData.finish) |
||||
SET_CURRENCYSYMBOL(resData.currency_symbol) |
||||
SET_BUDGETHEALTH(resData.budget_health) |
||||
SET_ACWP(resData.actual_cost) |
||||
SET_PROGRESS(resData.progress) |
||||
SET_COMMENT(resData.comment) |
||||
SET_MANPOWER(resData.man_power) |
||||
getDataCostActual(resData.kode_sortname); |
||||
} |
||||
} |
||||
|
||||
const getDataCostActual = async (kode_project) => { |
||||
const URL = `${BASE_INTEGRATION_V1}/api/project_cost?project_no=${kode_project}` |
||||
const result = await axios.get(URL, HEADER_INTEGRASI).then(res => res).catch(err => err.response) |
||||
if (!result.data.data) { |
||||
NotificationManager.error('Integrasi Cost Actual Failed', 'Failed'); |
||||
}else { |
||||
SET_ACWP(result.data.data.total_cost) |
||||
} |
||||
|
||||
} |
||||
|
||||
useEffect(() => { |
||||
getProjectDetail(); |
||||
}, []) |
||||
|
||||
|
||||
return ( |
||||
<div style={{ margin: "10px" }}> |
||||
<Row> |
||||
<Col span={9}> |
||||
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '0 5px' }} className="box-header-dashboard-project"> |
||||
<div><i style={{ color: 'teal' }} class="zmdi zmdi-assignment zmdi-hc-lg"></i></div> |
||||
<div style={{ textTransform: 'uppercase' }}>Project </div> |
||||
<div style={{ fontWeight: 500, color: '#404040', textTransform: 'uppercase' }}> {PROJECTNAME}</div> |
||||
</div> |
||||
</Col> |
||||
<Col span={4}> |
||||
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '0 5px' }} className="box-header-dashboard-project"> |
||||
<div><i style={{ color: '#0284c7' }} class="zmdi zmdi-account zmdi-hc-lg"></i></div> |
||||
<div style={{ textTransform: 'uppercase' }}>PM</div> |
||||
<div style={{ fontWeight: 500, color: '#404040', textTransform: 'uppercase' }}>{PROJECTMGR}</div> |
||||
</div> |
||||
</Col> |
||||
<Col span={7}> |
||||
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '0 5px' }} className="box-header-dashboard-project"> |
||||
<div><i style={{ color: '#b91c1c' }} class="zmdi zmdi-home zmdi-hc-lg"></i></div> |
||||
<div style={{ textTransform: 'uppercase' }}>Customer</div> |
||||
<div style={{ fontWeight: 500, color: '#404040', textTransform: 'uppercase' }}>{RO}</div> |
||||
</div> |
||||
</Col> |
||||
<Col span={4}> |
||||
<div style={{ display: 'flex', justifyContent: 'space-between', margin: '0 5px' }} className="box-header-dashboard-project"> |
||||
<div><i style={{ color: '#e68a00' }} class="zmdi zmdi-calendar-alt zmdi-hc-lg"></i></div> |
||||
<div style={{ textTransform: 'uppercase' }}>Date</div> |
||||
<div style={{ fontWeight: 500, color: '#404040' }}>{moment().format("DD-MM-YYYY")}</div> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
<div style={{ paddingTop: 20 }}> |
||||
<Row> |
||||
<Col span={9}> |
||||
<div style={{ margin: '0 5px' }} className="box-header-dashboard-project"> |
||||
<div style={{ margin: '5px 0' }}><h6>SCHEDULE</h6></div> |
||||
<div style={{ padding: '5px 0' }}> |
||||
<Row> |
||||
<Col span={2}><i style={{ color: 'teal' }} class="zmdi zmdi-calendar-alt zmdi-hc-lg"></i></Col> |
||||
<Col span={22}> |
||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
||||
<div>Start Date</div> |
||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{moment(STARTDATE).format("LL")}</div> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<div style={{ padding: '5px 0' }}> |
||||
<Row> |
||||
<Col span={2}><i style={{ color: 'teal' }} class="zmdi zmdi-calendar-alt zmdi-hc-lg"></i></Col> |
||||
<Col span={22}> |
||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
||||
<div>Baseline Finish Date</div> |
||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{moment(BASELINEFINISHDATE).format("LL")}</div> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<div style={{ padding: '5px 0' }}> |
||||
<Row> |
||||
<Col span={2}><i style={{ color: 'teal' }} class="zmdi zmdi-calendar-alt zmdi-hc-lg"></i></Col> |
||||
<Col span={22}> |
||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
||||
<div>Estimated Finish Date</div> |
||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{moment(ESTFINISHDATE).format("LL")}</div> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
</div> |
||||
</Col> |
||||
<Col span={10}> |
||||
<div style={{ margin: '0 5px' }} className="box-header-dashboard-project"> |
||||
<div style={{ margin: '5px 0' }}><h6>FINANCIALS</h6></div> |
||||
<div style={{ padding: '5px 0' }}> |
||||
<Row> |
||||
<Col span={2}><i style={{ color: '#059669' }} class="zmdi zmdi-money zmdi-hc-lg"></i></Col> |
||||
<Col span={22}> |
||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
||||
<div>Budget Proyek</div> |
||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{`${formatRibuanDecimal(BUDGET)}`}</div> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<div style={{ padding: '5px 0' }}> |
||||
<Row> |
||||
<Col span={2}><i style={{ color: '#059669' }} class="zmdi zmdi-money zmdi-hc-lg"></i></Col> |
||||
<Col span={22}> |
||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
||||
<div>Actual Cost</div> |
||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{`${formatRibuanDecimal(ACWP)}`}</div> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<div style={{ padding: '5px 0' }}> |
||||
<Row> |
||||
<Col span={2}><i style={{ color: '#059669' }} class="zmdi zmdi-money zmdi-hc-lg"></i></Col> |
||||
<Col span={22}> |
||||
<div style={{ textTransform: 'uppercase', display: 'flex', justifyContent: 'space-between' }}> |
||||
<div>Variance</div> |
||||
<div style={{ fontWeight: 500, color: '#8c8c8c' }}>{`${formatRibuanDecimal(BUDGET - ACWP)}`}</div> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
</div> |
||||
|
||||
</Col> |
||||
<Col span={5}> |
||||
<div style={{ backgroundColor: "#059669" }} className='box-header-dashboard-project'> |
||||
<div style={{ display: 'flex', justifyContent: 'center' }}> |
||||
<div style={{ fontSize: '0.8rem', fontWeight: 500, color: '#fff', textTransform: 'uppercase' }}>Progress</div> |
||||
</div> |
||||
<ProgressBar bgcolor="#ffc355" completed={PROGRESS} /> |
||||
</div> |
||||
<Row> |
||||
<Col span={12}> |
||||
<div style={{ margin: '5px 0' }} className="box-header-dashboard-project"> |
||||
<div style={{ display: 'flex', justifyContent: 'center' }}> |
||||
<div style={{ marginBottom: '5px', fontSize: '0.7rem', fontWeight: '500' }}>HEALTH PROJECT</div> |
||||
</div> |
||||
<div style={{ display: 'flex', justifyContent: 'space-evenly', }}> |
||||
<RenderHealthProject params = {`${BUDGETHEALTH}`}/> |
||||
</div> |
||||
</div> |
||||
</Col> |
||||
<Col span={12}> |
||||
<div style={{ margin: '5px 0' }} className="box-header-dashboard-project"> |
||||
<div style={{ display: 'flex', justifyContent: 'center' }}> |
||||
<div style={{ marginBottom: '5px', fontSize: '0.7rem', fontWeight: '500' }}>MANPOWER</div> |
||||
</div> |
||||
<div style={{ display: 'flex', justifyContent: 'space-evenly', }}> |
||||
<div style={{ fontWeight: 500, color: '#404040', fontSize: '18px', textTransform: 'uppercase' }}>{MANPOWER}</div> |
||||
</div> |
||||
</div> |
||||
</Col> |
||||
</Row> |
||||
{/* </div> */} |
||||
|
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
<div style={{ paddingTop: 20 }}> |
||||
<Row> |
||||
<Col span={19}> |
||||
</Col> |
||||
<Col span={5}> |
||||
<ChatDashboard |
||||
dataParams = {COMMENT}/> |
||||
</Col> |
||||
</Row> |
||||
</div> |
||||
</div> |
||||
); |
||||
} |
||||
|
||||
export default DashboardProject; |
@ -1,37 +0,0 @@
|
||||
import React from "react"; |
||||
|
||||
const ProgressBar = (props) => { |
||||
const { bgcolor, completed } = props; |
||||
|
||||
const containerStyles = { |
||||
height: 25, |
||||
width: '100%', |
||||
backgroundColor: "#e0e0de", |
||||
borderRadius: 50, |
||||
margin: 0 |
||||
} |
||||
|
||||
const fillerStyles = { |
||||
height: '100%', |
||||
width: `${completed}%`, |
||||
backgroundColor: bgcolor, |
||||
borderRadius: 'inherit', |
||||
textAlign: 'right' |
||||
} |
||||
|
||||
const labelStyles = { |
||||
padding: 5, |
||||
color: 'white', |
||||
fontWeight: 'bold' |
||||
} |
||||
|
||||
return ( |
||||
<div style={containerStyles}> |
||||
<div style={fillerStyles}> |
||||
<span style={labelStyles}>{`${completed}%`}</span> |
||||
</div> |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
export default ProgressBar; |
@ -1,72 +0,0 @@
|
||||
import React from 'react'; |
||||
import { Table, Tag, Space } from 'antd'; |
||||
const columns = [ |
||||
{ |
||||
title: 'No', |
||||
dataIndex: 'carNo', |
||||
key: 'carNo', |
||||
fixed: 'left', |
||||
}, |
||||
{ |
||||
title: 'Description', |
||||
dataIndex: 'description', |
||||
key: 'description', |
||||
width: 350 |
||||
}, |
||||
{ |
||||
title: 'Severity', |
||||
dataIndex: 'severity', |
||||
key: 'severity', |
||||
render: text => { |
||||
return text == 'low' ? <div className="badge" style={{ backgroundColor: '#e6e600' }}>LOW</div> : |
||||
text == 'medium' ? <div className="badge badge-orange" style={{ backgroundColor: 'orange' }}>MEDIUM</div> : |
||||
<div className="badge badge-danger">HIGH</div> |
||||
}, |
||||
}, |
||||
{ |
||||
title: 'Status', |
||||
dataIndex: 'status', |
||||
key: 'status', |
||||
render: text => { |
||||
return text == 'open' ? <div className="badge badge-primary">OPEN</div> : |
||||
text == 'on-progress' ? <div className="badge badge-warning">ON PROGRESS</div> : |
||||
<div className="badge badge-success">DONE</div> |
||||
}, |
||||
}, |
||||
{ |
||||
title: 'Assigned', |
||||
dataIndex: 'assigned', |
||||
key: 'assigned', |
||||
}, |
||||
{ |
||||
title: 'Due', |
||||
dataIndex: 'due', |
||||
key: 'due', |
||||
} |
||||
]; |
||||
const data = [ |
||||
{ |
||||
key: '1', |
||||
carNo: 'RIS001', |
||||
description: 'Test Analyst on unplanned leave, risk to project if leave extends pas 5/20', |
||||
severity: 'medium', |
||||
status: 'on-progress', |
||||
due: '05/04/2022', |
||||
assigned: 'John Lennon' |
||||
}, |
||||
{ |
||||
key: '2', |
||||
carNo: 'RIS002', |
||||
description: 'Coffee machine broken, result in extra long breaks to find coffee', |
||||
severity: 'low', |
||||
status: 'open', |
||||
due: '14/011/2022', |
||||
assigned: 'Robert William' |
||||
}, |
||||
]; |
||||
const TableDashboard = () => { |
||||
return ( |
||||
<Table size="small" columns={columns} dataSource={data} scroll={{ y: 300 }} /> |
||||
); |
||||
} |
||||
export default TableDashboard; |
@ -1,51 +0,0 @@
|
||||
import React, { Component } from 'react' |
||||
import DataTable from '../../../components/DataTable' |
||||
import {API_LIST_DATA_COUNTRY, API_INSERT_DATA_COUNTRY, API_UPDATE_DATA_COUNTRY, API_DELETE_DATA_COUNTRY } from '../../../const/ApiConst.js' |
||||
|
||||
|
||||
const columns = [{ |
||||
dataField: 'id', |
||||
alias: "Id", |
||||
showInput: false, |
||||
type: "number", |
||||
state: 0 |
||||
}, { |
||||
dataField: 'country_name', |
||||
alias: "Country Name", |
||||
showInput: true, |
||||
type: "text", |
||||
state: "" |
||||
}, { |
||||
dataField: 'last_updated', |
||||
alias: "Last Updated", |
||||
showInput: false, |
||||
type: "text", |
||||
state: "" |
||||
}]; |
||||
|
||||
class MasterCountry extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = {} |
||||
} |
||||
|
||||
componentDidMount() {} |
||||
|
||||
render() { |
||||
|
||||
return ( |
||||
<div> |
||||
<DataTable |
||||
title="Country" |
||||
columns={columns} |
||||
urlParamGet={API_LIST_DATA_COUNTRY} |
||||
urlParamInsert={API_INSERT_DATA_COUNTRY} |
||||
urlParamUpdate={API_UPDATE_DATA_COUNTRY} |
||||
urlParamDelete={API_DELETE_DATA_COUNTRY} |
||||
/> |
||||
</div> |
||||
) |
||||
} |
||||
} |
||||
|
||||
export default MasterCountry; |
@ -1,6 +0,0 @@
|
||||
{ |
||||
"name": "MasterCountry", |
||||
"version": "0.0.0", |
||||
"private": true, |
||||
"main": "./MasterCountry.js" |
||||
} |
@ -1,156 +0,0 @@
|
||||
import React, { Component } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import axios from 'axios' |
||||
|
||||
|
||||
const BASE_URL = "https://oslog.id/geohr-api/"; |
||||
const formState = { |
||||
dataTable: [], |
||||
openDialog: false, |
||||
name: '', |
||||
description: '', |
||||
id: 0, |
||||
idData: 0, |
||||
nameMessage: "", |
||||
} |
||||
|
||||
const ERROR_NAME = "name cannot be empty" |
||||
export default class DialogForm extends Component { |
||||
state = { |
||||
...formState |
||||
} |
||||
|
||||
componentDidUpdate(prevProps, prevState) { |
||||
const { dataEdit, methodAct } = this.props |
||||
if ((prevProps.dataEdit !== dataEdit) && (methodAct == "Edit" || methodAct == "View")) { |
||||
this.setState({ |
||||
idData: dataEdit.id, |
||||
name: dataEdit.name, |
||||
description: dataEdit.description, |
||||
}) |
||||
} |
||||
} |
||||
|
||||
handleSave = async () => { |
||||
const err = this.handleValidation(); |
||||
let url = BASE_URL + "group-sales/add" |
||||
const { name, description, idData } = this.state |
||||
const { methodAct } = this.props |
||||
console.log(`methodAct`, methodAct) |
||||
if (methodAct === "Add") { |
||||
if (!err) { |
||||
|
||||
const payload = { |
||||
name, |
||||
description, |
||||
} |
||||
const result = await axios.post(url, payload) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
console.log(`result`, result) |
||||
if (result.data.message === "OK") { |
||||
this.props.closeDialog() |
||||
this.setState({ |
||||
...formState, |
||||
}) |
||||
NotificationManager.success('Data group sales berhasil ditambahkan!!', 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(result.data.message); |
||||
} |
||||
} |
||||
} else if (methodAct === "Edit") { |
||||
if (!err) { |
||||
let urlEdit = BASE_URL + `group-sales/${idData}/edit`; |
||||
const payload = { |
||||
name, |
||||
description, |
||||
} |
||||
|
||||
const result = await axios.put(urlEdit, payload) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
console.log(`result edit`, result) |
||||
|
||||
if (result.data.message === "OK") { |
||||
this.props.closeDialog() |
||||
this.setState({ |
||||
...formState, |
||||
}) |
||||
NotificationManager.success('Data group sales berhasil diedit!!', 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(result.data.message); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.props.closeDialog() |
||||
this.setState({ |
||||
...formState |
||||
}) |
||||
} |
||||
|
||||
handleValidation = () => { |
||||
const { name } = this.state |
||||
let isError = false; |
||||
const errors = { |
||||
nameMessage: "", |
||||
} |
||||
if (name === "") { |
||||
isError = true |
||||
errors.nameMessage = ERROR_NAME |
||||
} |
||||
this.setState({ |
||||
nameMessage: "", |
||||
...errors, |
||||
}); |
||||
|
||||
return isError; |
||||
} |
||||
|
||||
renderForm = () => { |
||||
const { name, description, nameMessage } = this.state |
||||
return ( |
||||
<Row form> |
||||
<Col md={12}> |
||||
<FormGroup> |
||||
<Label for="exampleEmail">Name</Label> |
||||
<Input type="text" value={name} onChange={ |
||||
(e) => this.setState({ |
||||
name: e.target.value, |
||||
nameMessage: e.target.value !== "" ? "" : ERROR_NAME |
||||
})} placeholder="name" invalid={nameMessage} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={12}> |
||||
<FormGroup> |
||||
<Label>Description</Label> |
||||
<Input type="text" value={description} onChange={(e) => this.setState({ description: e.target.value })} placeholder="description " /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
) |
||||
} |
||||
|
||||
render() { |
||||
const { openDialog, closeDialog, methodAct } = this.props |
||||
return ( |
||||
<Modal isOpen={openDialog} toggle={openDialog} size="md"> |
||||
<ModalHeader toggle={closeDialog}>{methodAct} Group Sales</ModalHeader> |
||||
<ModalBody> |
||||
<Form> |
||||
{this.renderForm()} |
||||
</Form> |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={this.handleSave}>{methodAct}</Button>{' '} |
||||
<Button color="secondary" onClick={this.handleCancel}>Cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
@ -1,291 +0,0 @@
|
||||
import React, { Component } from 'react'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input, InputGroupButtonDropdown, DropdownToggle, DropdownItem, DropdownMenu, InputGroup } from 'reactstrap'; |
||||
import BootstrapTable from 'react-bootstrap-table-next'; |
||||
import { Button } from 'reactstrap'; |
||||
import axios from 'axios'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import DialogForm from './DialogForm'; |
||||
import paginationFactory from 'react-bootstrap-table2-paginator'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit'; |
||||
import { Pagination } from 'antd'; |
||||
import { Tooltip } from 'reactstrap'; |
||||
|
||||
const BASE_URL = "https://oslog.id/geohr-api/"; |
||||
|
||||
const { SearchBar } = Search; |
||||
|
||||
const NoDataIndication = () => ( |
||||
<div className="spinner"> |
||||
<div className="rect1" /> |
||||
<div className="rect2" /> |
||||
<div className="rect3" /> |
||||
</div> |
||||
); |
||||
|
||||
const column = [ |
||||
{ name: "Name" }, |
||||
{ name: "Description" }, |
||||
] |
||||
|
||||
const LENGTH_DATA = 10 |
||||
export default class index extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
data: [], |
||||
openDialog: false, |
||||
typeDialog: 'Save', |
||||
dataEdit: null, |
||||
alertDelete: false, |
||||
idDelete: 0, |
||||
search: "", |
||||
alert: false, |
||||
methodAct: "Add", |
||||
page: 0, |
||||
totalPage: 0, |
||||
rowsPerPage: LENGTH_DATA, |
||||
currentPage: 1, |
||||
splitButtonOpen: false, |
||||
searchDetail: "All", |
||||
searchDetailField: "name", |
||||
tooltipDelete: false, |
||||
tooltipEdit: false |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
const { page, rowsPerPage } = this.state |
||||
this.getDataGroupSales(page, rowsPerPage); |
||||
} |
||||
async componentDidUpdate(prevProps, prevState) { |
||||
const { search, rowsPerPage, page } = this.state |
||||
|
||||
if (page !== prevState.page) { |
||||
this.getDataGroupSales(page, rowsPerPage) |
||||
} |
||||
|
||||
if (rowsPerPage !== prevState.rowsPerPage) { |
||||
this.getDataGroupSales(0, rowsPerPage) |
||||
this.setState({ page: 0 }) |
||||
} |
||||
|
||||
if (search !== prevState.search) { |
||||
this.getDataGroupSales(0, rowsPerPage) |
||||
this.setState({ page: 0 }) |
||||
} |
||||
}; |
||||
|
||||
handleSearch = e => { |
||||
const value = e.target.value |
||||
this.setState({ search: value, page: 0 }) |
||||
}; |
||||
|
||||
|
||||
getDataGroupSales = async (start, length) => { |
||||
const { search, rowsPerPage, searchDetail, searchDetailField } = this.state |
||||
let url = BASE_URL + "group-sales/search"; |
||||
const obj = { |
||||
"paging": { "start": start, "length": length }, |
||||
...searchDetail === "All" && |
||||
{ |
||||
"filter_columns": [ |
||||
{ "name": "name", "value": search.toString() }, |
||||
{ "name": "description", "value": search.toString() }, |
||||
], |
||||
}, |
||||
...searchDetail !== "All" && |
||||
{ |
||||
"columns": [ |
||||
{ "name": searchDetailField, "logic_operator": "ilike", "operator": "and", "value": search.toString() } |
||||
] |
||||
}, |
||||
"orders": { "columns": ["created_date"], "ascending": false } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(url, obj) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result.data.message == "OK") { |
||||
console.log(`result data`, result.data.data) |
||||
this.setState({ data: result.data.data, totalPage: result.data.totalRecord }); |
||||
} else { |
||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
handleOpenDialog = () => { |
||||
this.setState({ openDialog: true, methodAct: "Add" }) |
||||
} |
||||
|
||||
handleCloseDialog = () => { |
||||
this.setState({ openDialog: false }) |
||||
this.getDataGroupSales() |
||||
} |
||||
|
||||
|
||||
handleEditData = (data) => { |
||||
this.setState({ dataEdit: data, openDialog: true, methodAct: "Edit" }) |
||||
} |
||||
|
||||
|
||||
onDelete = (id) => { |
||||
this.setState({ |
||||
alertDelete: true, |
||||
idDelete: id |
||||
}) |
||||
} |
||||
|
||||
handleDeleted = async (param) => { |
||||
const { idDelete } = this.state |
||||
|
||||
if (param === "delete") { |
||||
const result = await axios.delete(`${BASE_URL}/group-sales/${idDelete}/delete`) |
||||
.then((response) => response) |
||||
.catch((error) => error.response) |
||||
this.setState({ |
||||
alertDelete: false, |
||||
alert: true |
||||
}) |
||||
await this.getDataGroupSales() |
||||
} else { |
||||
this.setState({ |
||||
alertDelete: false |
||||
}) |
||||
} |
||||
} |
||||
|
||||
|
||||
onShowSizeChange = (current, pageSize) => { |
||||
this.setState({ rowsPerPage: pageSize }) |
||||
} |
||||
|
||||
onPagination = (current, pageSize) => { |
||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }) |
||||
} |
||||
|
||||
toggleDropDown = () => { |
||||
this.setState(prevState => ({ splitButtonOpen: !prevState.splitButtonOpen })) |
||||
} |
||||
|
||||
toggle = (param) => { |
||||
if (param === "edit") { |
||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
||||
} else if (param === "delete") { |
||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
||||
} |
||||
} |
||||
render() { |
||||
const { openDialog, data, search, alert, page, totalPage, rowsPerPage, currentPage, searchDetail, searchDetailField, splitButtonOpen, tooltipEdit, tooltipDelete } = this.state |
||||
let noSeq = 0; |
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert show={alert} success title="deleted successfully!" onConfirm={() => this.setState({ alert: false })} onCancel={() => this.setState({ alert: false })}> |
||||
You clicked the button! |
||||
</SweetAlert> |
||||
<SweetAlert |
||||
show={this.state.alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title="Are you sure?" |
||||
onConfirm={() => this.handleDeleted("delete")} |
||||
onCancel={() => this.handleDeleted("cancel")} |
||||
focusCancelBtn |
||||
> |
||||
Data group sales akan terhapus!! |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={this.handleCloseDialog} |
||||
dataEdit={this.state.dataEdit} |
||||
methodAct={this.state.methodAct} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4>Group Sales</h4> |
||||
<Button color="primary" onClick={() => this.handleOpenDialog('Save')}>Add Group Sales</Button> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<InputGroup style={{ maxWidth: "200px", marginBottom: "20px" }}> |
||||
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={`Search ${searchDetail}`} /> |
||||
<InputGroupButtonDropdown addonType="prepend" |
||||
isOpen={splitButtonOpen} |
||||
toggle={this.toggleDropDown} |
||||
> |
||||
<DropdownToggle split outline /> |
||||
<DropdownMenu> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "All", |
||||
searchDetailField: "name" |
||||
})}>All</DropdownItem> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Name", |
||||
searchDetailField: "name" |
||||
})}>Name</DropdownItem> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Description", |
||||
searchDetailField: "description" |
||||
})}>Description</DropdownItem> |
||||
</DropdownMenu> |
||||
</InputGroupButtonDropdown> |
||||
</InputGroup> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
<th>Actions</th> |
||||
{column.map((i) => { |
||||
return ( |
||||
<th scope="row">{i.name}</th> |
||||
) |
||||
})} |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{data.map((n) => { |
||||
return ( |
||||
<tr key={n.id}> |
||||
<td> |
||||
{/* delete */} |
||||
<i id="TooltipDelete" class="cil-trash fa-lg" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => this.onDelete(n.id)}></i> |
||||
<Tooltip placement="right" isOpen={tooltipDelete} target="TooltipDelete" toggle={() => this.toggle("delete")}> |
||||
Delete |
||||
</Tooltip> |
||||
|
||||
{/* edit */} |
||||
<i id="TooltipEdit" class="cil-pencil fa-lg" style={{ color: 'green', cursor: "pointer", marginRight: '10px', }} onClick={() => this.handleEditData(n)}></i> |
||||
<Tooltip placement="right" isOpen={tooltipEdit} target="TooltipEdit" toggle={() => this.toggle("edit")}> |
||||
Edit |
||||
</Tooltip> |
||||
{/* <i class="cil-search fa-lg" style={{ color: 'blue', cursor: "pointer" }} onClick={() => this.handleDetail(n)}></i> */} |
||||
</td> |
||||
<td>{n.name}</td> |
||||
<td>{n.description}</td> |
||||
</tr> |
||||
) |
||||
})} |
||||
</tbody> |
||||
</Table> |
||||
<Pagination |
||||
showSizeChanger |
||||
onShowSizeChange={this.onShowSizeChange} |
||||
onChange={this.onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={totalPage} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
} |
@ -1,581 +0,0 @@
|
||||
import React, { Component } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Col, Row, Button, Form, FormGroup, Label, Input, FormText } from 'reactstrap'; |
||||
import Select from 'react-select' |
||||
import axios from 'axios'; |
||||
import moment from 'moment'; |
||||
import { DatePicker } from 'antd'; |
||||
import 'antd/dist/antd.css'; |
||||
import { BASE_URL_GEOHR_API2 } from '../../../const/ApiConst' |
||||
import '../MasterDataStyles.css' |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
|
||||
|
||||
const format = 'YYYY-MM-DD'; |
||||
let countError = 0; |
||||
const listGender = [ |
||||
{ |
||||
"value": "L", |
||||
"label": "Laki-laki" |
||||
}, |
||||
{ |
||||
"value": "P", |
||||
"label": "Perempuan" |
||||
}] |
||||
|
||||
const listBlood = [ |
||||
{ |
||||
"value": "A", |
||||
"label": "A" |
||||
}, |
||||
{ |
||||
"value": "AB", |
||||
"label": "AB" |
||||
}, |
||||
{ |
||||
"value": "B", |
||||
"label": "B" |
||||
}, |
||||
{ |
||||
"value": "O", |
||||
"label": "O" |
||||
}] |
||||
|
||||
const API = `https://oslog.id/geohr-api` |
||||
|
||||
|
||||
|
||||
export default class DialogForm extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
id: 0, |
||||
idDivision:0, |
||||
idRoles:0, |
||||
name:"", |
||||
email:"", |
||||
phoneNumber:"", |
||||
username:"", |
||||
password:"", |
||||
address:"", |
||||
birthPlace: "", |
||||
birthDate: null, |
||||
currentSelectGender: null,
|
||||
hobby: "", |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
currentSelectVal: null, |
||||
dataDivision:[], |
||||
listDivisionSelect:[], |
||||
selectDisable: false, |
||||
dataRoles:[], |
||||
listRolesSelect:[], |
||||
selectDisableRoles: false, |
||||
currentSelectRoles: null, |
||||
currentSelectBlood: null, |
||||
selectDisableBlood: false, |
||||
nik: "", |
||||
files: [], |
||||
showImg: false, |
||||
getUrl: "", |
||||
namePhoto: "", |
||||
alertDelete: false, |
||||
idDelete: 0 , |
||||
dataPhoto: null |
||||
|
||||
|
||||
} |
||||
} |
||||
|
||||
fileSelectedHandler = (e) => { |
||||
this.setState({ files: [...this.state.files, ...e.target.files] }, () => { |
||||
console.log('test data foto', this.state.files) |
||||
}) |
||||
} |
||||
|
||||
|
||||
async componentDidMount(){ |
||||
this.getDataRoles() |
||||
this.props.showDialog(this.showDialog); |
||||
} |
||||
|
||||
async componentDidUpdate (prevProps, prevState){ |
||||
const { dataEdit } = this.props |
||||
|
||||
if(this.state.isParentClick===true){ |
||||
if(this.props.typeDialog==="Edit" || this.props.typeDialog==="View"){ |
||||
|
||||
if(dataEdit.role_id!=="" && dataEdit.role_id!==null && dataEdit.role_id!==undefined){ |
||||
this.searchRoles(dataEdit.role_id); |
||||
}
|
||||
|
||||
this.getUrlImagery(dataEdit.id) |
||||
|
||||
this.setState({
|
||||
id:dataEdit.id, |
||||
idRoles: dataEdit.role_id, |
||||
idDivision:dataEdit.employee_division_id, |
||||
username:dataEdit.username || "", |
||||
name:dataEdit.name || "", |
||||
email:dataEdit.email || "", |
||||
password:"", |
||||
phoneNumber:dataEdit.phone_number || "", |
||||
address:dataEdit.address || "", |
||||
birthPlace: dataEdit.birth_place || "", |
||||
birthDate: dataEdit.birth_date || null, |
||||
currentSelectGender: dataEdit.gender ? listGender.find((x) => x.value === dataEdit.gender) : null,
|
||||
hobby: dataEdit.hobby || "", |
||||
nik: dataEdit.ktp_number || "", |
||||
currentSelectBlood: dataEdit.blood_type ? listBlood.find((x) => x.value === dataEdit.blood_type) : null,
|
||||
}) |
||||
}else{ |
||||
this.setState({
|
||||
id:0, |
||||
idDivision:0, |
||||
idRoles:0, |
||||
name:"", |
||||
email:"", |
||||
password:"", |
||||
phoneNumber:"", |
||||
address:"", |
||||
username:"", |
||||
birthPlace: "", |
||||
birthDate: null, |
||||
currentSelectGender: null,
|
||||
hobby: "", |
||||
currentSelectVal:null, |
||||
currentSelectRoles:null, |
||||
nik: "", |
||||
currentSelectBlood: null, |
||||
files: [] |
||||
}) |
||||
} |
||||
this.setState({isParentClick:false}); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
closeImg = () => { |
||||
this.setState({ showImg: false }) |
||||
} |
||||
|
||||
getUrlImagery = async (param) => { |
||||
const payload = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ "name": "category", "logic_operator": "=", "value": "employee", "operator": "and" }, |
||||
{ "name": "ref_id", "logic_operator": "=", "value": param.toString(), "operator": "and" } |
||||
], |
||||
"orders": { "columns": ["id"], "ascending": true } |
||||
} |
||||
const resultUrl = await axios.post(`${API}/image/search`, payload).then(response => response).catch(err => err.response) |
||||
this.setState({ files: resultUrl.data.data }) |
||||
console.log(`resultUrl`, resultUrl.data.data) |
||||
|
||||
} |
||||
|
||||
getDataDivision = async () => { |
||||
countError++; |
||||
let url = BASE_URL_GEOHR_API2+`/employee_devision.php?act=get_data`; |
||||
|
||||
const result = await axios |
||||
.get(url) |
||||
.then(res => res) |
||||
.catch((error) => error.response ); |
||||
console.log('cek', result) |
||||
|
||||
if(result && result.data && result.data.code_status === 200){ |
||||
this.setState({ dataDivision:result.data.data },()=>{ |
||||
this.setDataDivision(); |
||||
}) |
||||
}else{ |
||||
if(countError<6){ |
||||
this.getDataDivision(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
getDataRoles = async () => { |
||||
countError++; |
||||
let url = BASE_URL_GEOHR_API2+`/roles.php?act=get_data`; |
||||
|
||||
const result = await axios |
||||
.get(url) |
||||
.then(res => res) |
||||
.catch((error) => error.response ); |
||||
console.log('cek', result) |
||||
|
||||
if(result && result.data && result.data.code_status === 200){ |
||||
this.setState({ dataRoles:result.data.data },()=>{ |
||||
this.setDataRoles(); |
||||
}) |
||||
}else{ |
||||
if(countError<6){ |
||||
this.getDataRoles(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
setDataDivision = () => { |
||||
const { dataDivision } = this.state |
||||
const listDivision = [] |
||||
dataDivision.map((val, index)=> { |
||||
listDivision.push({ |
||||
value:val.id, |
||||
label:val.name |
||||
}) |
||||
}) |
||||
this.setState({ listDivisionSelect:listDivision }) |
||||
} |
||||
|
||||
setDataRoles = () => { |
||||
const { dataRoles } = this.state |
||||
const listRoles = [] |
||||
dataRoles.map((val, index)=> { |
||||
listRoles.push({ |
||||
value:val.id, |
||||
label:val.name |
||||
}) |
||||
}) |
||||
this.setState({ listRolesSelect:listRoles }) |
||||
} |
||||
|
||||
|
||||
searchDivision = (id) => { |
||||
let getIndex = this.getIndexDataDivision(id); |
||||
let data = this.state.dataDivision[getIndex] |
||||
this.setState({ idDivision:data.id,currentSelectVal:{value:data.id,label:data.name} }) |
||||
} |
||||
|
||||
getIndexDataDivision = (val) => { |
||||
let index = this.state.dataDivision.findIndex(obj => obj.id === val); |
||||
return index |
||||
} |
||||
|
||||
searchRoles = (id) => { |
||||
let getIndex = this.getIndexDataRoles(id); |
||||
let data = this.state.dataRoles[getIndex] |
||||
this.setState({ idRoles:data.id,currentSelectRoles:{value:data.id,label:data.name} }) |
||||
} |
||||
|
||||
getIndexDataRoles = (val) => { |
||||
let index = this.state.dataRoles.findIndex(obj => obj.id === val); |
||||
return index |
||||
} |
||||
|
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick : true }); |
||||
} |
||||
|
||||
handleDeletePhoto = (data) => { |
||||
this.setState({ alertDelete: true, dataPhoto: data }, () => { |
||||
console.log('data photo', this.state.dataPhoto) |
||||
}); |
||||
} |
||||
|
||||
|
||||
handleSave = async () => { |
||||
const {
|
||||
id, |
||||
idDivision, |
||||
username, |
||||
name, |
||||
email, |
||||
password, |
||||
address, |
||||
phoneNumber, |
||||
idRoles, |
||||
birthPlace, |
||||
birthDate, |
||||
currentSelectGender, |
||||
hobby, |
||||
currentSelectBlood, |
||||
nik, |
||||
files, |
||||
currentSelectRoles |
||||
} = this.state |
||||
|
||||
let data = ''; |
||||
if(this.props.typeDialog==="Save"){ |
||||
data = { |
||||
idDivision, |
||||
username, |
||||
name, |
||||
email, |
||||
password, |
||||
address, |
||||
phoneNumber, |
||||
idRoles, |
||||
birthPlace, |
||||
birthDate, |
||||
currentSelectGender, |
||||
hobby, |
||||
nik, |
||||
currentSelectBlood, |
||||
files, |
||||
currentSelectRoles |
||||
} |
||||
|
||||
|
||||
this.props.closeDialog('save', data); |
||||
}else{ |
||||
data = { |
||||
id, |
||||
username, |
||||
name, |
||||
email, |
||||
password, |
||||
address, |
||||
phoneNumber, |
||||
idDivision, |
||||
idRoles, |
||||
birthPlace, |
||||
birthDate, |
||||
currentSelectGender, |
||||
hobby, |
||||
nik,
|
||||
currentSelectBlood, |
||||
currentSelectRoles |
||||
|
||||
} |
||||
|
||||
console.log('test log data', data) |
||||
|
||||
if (files.length > 0) { |
||||
const formData = new FormData() |
||||
files.map((res) => { |
||||
if (res) |
||||
formData.append("ref_id", id); |
||||
formData.append("files", res); |
||||
}) |
||||
await axios.post(`${API}/image/employee/upload`, formData).then(response => response).catch(err => err.response) |
||||
} |
||||
|
||||
this.props.closeDialog('edit', data); |
||||
} |
||||
|
||||
|
||||
this.setState({ id:0,idDivision:0,currentSelectVal:null, currentSelectRoles: null, currentSelectGender: null, currentSelectBlood: null }); |
||||
|
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.setState({ id:0,currentSelectVal:null, currentSelectRoles: null, currentSelectGender: null, currentSelectBlood: null }); |
||||
this.props.closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
handleSelectGs = (inputValue, actionMeta) => { |
||||
this.setState({ idDivision:inputValue.value,currentSelectVal:{ value:inputValue.value,label:inputValue.label } }) |
||||
} |
||||
|
||||
handleSelectRoles = (inputValue, actionMeta) => { |
||||
this.setState({ idRoles:inputValue.value,currentSelectRoles:{ value:inputValue.value,label:inputValue.label } }, ()=> { |
||||
console.log("test select role", this.state.currentSelectRoles) |
||||
}) |
||||
} |
||||
|
||||
onConfirmDeletePhoto = async () => { |
||||
const { id, dataPhoto } = this.state |
||||
let url = `https://oslog.id/geohr-api/image/employee/${id}/delete?files=${dataPhoto.image}` |
||||
let result = await axios.delete(url) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result.message!==undefined){ |
||||
|
||||
}else{ |
||||
|
||||
} |
||||
console.log("test data photooo", result) |
||||
|
||||
if (result) { |
||||
this.getUrlImagery(id) |
||||
|
||||
this.setState({ dataPhoto: null, alertDelete: false }) |
||||
NotificationManager.success('Foto berhasil dihapus!!', 'Success!!'); |
||||
} else { |
||||
this.getUrlImagery(id) |
||||
|
||||
this.setState({ dataPhoto: null, alertDelete: false }) |
||||
NotificationManager.error('Foto gagal dihapus!!', 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
|
||||
renderForm = () => { |
||||
const {files} = this.state |
||||
const {typeDialog} = this.props |
||||
let typeRole = localStorage.getItem('role_name') |
||||
|
||||
return( |
||||
<Form> |
||||
<Row> |
||||
<Col md={6} xs={12}> |
||||
{/* <FormGroup> |
||||
<Label className="formLabel">Divisi</Label> |
||||
<Select options={this.state.listDivisionSelect} onChange={this.handleSelectGs} value={this.state.currentSelectVal} isDisabled={typeDialog === "View"} /> |
||||
</FormGroup> */} |
||||
|
||||
<Row> |
||||
<Col md={6} xs={6}> |
||||
<FormGroup> |
||||
<Label className="formLabel">Nama Pengguna</Label> |
||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.username} onChange={(e) => this.setState({username:e.target.value})} placeholder="" /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6} xs={6}> |
||||
<FormGroup> |
||||
<Label className="formLabel">Kata Sandi</Label> |
||||
<Input readOnly={typeDialog === "View"} type="password" value={this.state.password} onChange={(e) => this.setState({password:e.target.value})} placeholder="" /> |
||||
{this.props.typeDialog==="Save" ? "" : <p>*Kosongkan jika tidak ada perubahaan</p>} |
||||
|
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<FormGroup> |
||||
<Label className="formLabel">NIK (KTP)</Label> |
||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.nik} onChange={(e) => this.setState({nik:e.target.value})} placeholder="" /> |
||||
</FormGroup> |
||||
|
||||
<FormGroup> |
||||
<Label className="formLabel">Nama</Label> |
||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.name} onChange={(e) => this.setState({name:e.target.value})} placeholder="" /> |
||||
</FormGroup> |
||||
|
||||
<FormGroup> |
||||
<Label className="formLabel">Email</Label> |
||||
<Input readOnly={typeDialog === "View"} type="email" value={this.state.email} onChange={(e) => this.setState({email:e.target.value})} placeholder="" /> |
||||
</FormGroup> |
||||
|
||||
<FormGroup> |
||||
<Label className="formLabel">Nomor Telepon</Label> |
||||
<Input readOnly={typeDialog === "View"} type="number" value={this.state.phoneNumber} onChange={(e) => this.setState({phoneNumber:e.target.value})} placeholder="" /> |
||||
</FormGroup> |
||||
|
||||
<FormGroup> |
||||
{typeDialog !== "View" && ( |
||||
<> |
||||
<Label for="exampleFile">File</Label> |
||||
<Input type="file" name="file" id="exampleFile" multiple onChange={this.fileSelectedHandler} /> |
||||
<FormText>Max Size 1Mb</FormText> |
||||
</> |
||||
)} |
||||
{files && ( |
||||
<div style={{ maxHeight: "300px", maxWidth: "100%", overflowY: "auto",display: "flex", flexDirection: "row" }}> |
||||
{files.map((item) => { |
||||
let checkImg = null |
||||
if (item.image) { |
||||
checkImg = `${API}/assets/images/employee/${item.image}` |
||||
} else { |
||||
checkImg = URL.createObjectURL(item) |
||||
} |
||||
return ( |
||||
<div> |
||||
{typeDialog === "Edit" && ( |
||||
<div onClick={() => this.handleDeletePhoto(item)} style={{cursor: "pointer", position: "absolute", width: 30, height: 30, borderRadius: 30 / 2, backgroundColor: "grey", marginTop: 10, marginLeft: 10, justifyContent: "center", alignContent: "center", paddingTop: 4, paddingLeft: 5 }}> |
||||
<i className="cil-trash fa-lg" style={{ color: 'red'}}></i> |
||||
</div> |
||||
) |
||||
} |
||||
<img key={item.id} src={checkImg} alt="..." style={{ maxWidth: "150px", maxHeight: "150px" }} /> |
||||
</div> |
||||
) |
||||
})} |
||||
</div> |
||||
) |
||||
} |
||||
</FormGroup> |
||||
</Col> |
||||
|
||||
<Col md={6} xs={12}> |
||||
{typeRole === "Superadmin" && ( |
||||
<FormGroup> |
||||
<Label className="formLabel">Roles</Label> |
||||
<Select options={this.state.listRolesSelect} onChange={this.handleSelectRoles} value={this.state.currentSelectRoles} isDisabled={typeDialog === "View"} /> |
||||
</FormGroup> |
||||
) |
||||
} |
||||
|
||||
<FormGroup> |
||||
<Label className="formLabel">Jenis Kelamin</Label> |
||||
<Select options={listGender} onChange={(inputValue, actionMeta) => this.setState({currentSelectGender: {value: inputValue.value, label: inputValue.label}})} value={this.state.currentSelectGender} isDisabled={typeDialog === "View"} /> |
||||
</FormGroup> |
||||
|
||||
<FormGroup style={{ marginTop: 30 }}> |
||||
<Label className="formLabel">Golongan Darah</Label> |
||||
<Select options={listBlood} onChange={(inputValue, actionMeta) => this.setState({currentSelectBlood: {value: inputValue.value, label: inputValue.label}})} value={this.state.currentSelectBlood} isDisabled={typeDialog === "View"} /> |
||||
</FormGroup> |
||||
|
||||
<Row> |
||||
<Col md={6} xs={12}> |
||||
<FormGroup> |
||||
<Label className="formLabel">Tempat Lahir</Label> |
||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.birthPlace} onChange={(e) => this.setState({birthPlace:e.target.value})} placeholder="" /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6} xs={12}> |
||||
<FormGroup> |
||||
<Label className="formLabel">Tanggal Lahir</Label> |
||||
<Row> |
||||
<Col md={12}> |
||||
<DatePicker disabled={typeDialog === "View"} style={{width: "100%"}} onChange={(e, val) => this.setState({birthDate: val})} defaultValue={this.state.birthDate ? moment(this.state.birthDate, format) : null} /> |
||||
</Col> |
||||
</Row> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
|
||||
<FormGroup> |
||||
<Label className="formLabel">Alamat</Label> |
||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.address} onChange={(e) => this.setState({address:e.target.value})} placeholder="" /> |
||||
</FormGroup> |
||||
|
||||
<FormGroup> |
||||
<Label className="formLabel">Hobby</Label> |
||||
<Input readOnly={typeDialog === "View"} type="text" value={this.state.hobby} onChange={(e) => this.setState({hobby:e.target.value})} placeholder="" /> |
||||
</FormGroup> |
||||
|
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
render() { |
||||
const {typeDialog} = this.props |
||||
return ( |
||||
<Modal size="xl" isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<NotificationContainer /> |
||||
|
||||
<SweetAlert |
||||
show={this.state.alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title="Are you sure?" |
||||
onConfirm={this.onConfirmDeletePhoto} |
||||
onCancel={() => this.setState({ alertDelete: false, dataPhoto: null})} |
||||
focusCancelBtn |
||||
> |
||||
Foto Akan Terhapus!! |
||||
</SweetAlert> |
||||
<ModalHeader toggle={() => this.handleCancel()}>{this.props.typeDialog} Karyawan</ModalHeader> |
||||
<ModalBody> |
||||
{this.renderForm()} |
||||
</ModalBody> |
||||
{typeDialog !== "View" && ( |
||||
|
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => this.handleSave()}>{this.props.typeDialog}</Button>{' '} |
||||
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button> |
||||
</ModalFooter> |
||||
)} |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
@ -1,79 +0,0 @@
|
||||
import React, { Component } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import moment from 'moment'; |
||||
import 'antd/dist/antd.css'; |
||||
|
||||
export default class DialogImport extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
dataImport:null, |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
disable: false |
||||
} |
||||
} |
||||
|
||||
async componentDidMount(){ |
||||
this.props.showDialog(this.showDialog); |
||||
} |
||||
|
||||
async componentDidUpdate (){ |
||||
if(this.state.isParentClick===true){ |
||||
this.setState({isParentClick:false}); |
||||
} |
||||
} |
||||
|
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick : true }); |
||||
} |
||||
|
||||
|
||||
handleSave = () => { |
||||
const {
|
||||
dataImport |
||||
} = this.state |
||||
|
||||
|
||||
this.props.closeDialog('import', dataImport); |
||||
this.setState({ dataImport:null }); |
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.props.closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
importExcel = (e) => { |
||||
e.preventDefault(); |
||||
let file = e.target.files[0]; |
||||
this.setState({dataImport:file}); |
||||
} |
||||
|
||||
renderForm = () => { |
||||
return( |
||||
<Form> |
||||
<FormGroup> |
||||
<Label>Excel</Label> |
||||
<Input type="file" onChange={this.importExcel} /> |
||||
</FormGroup> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.props.closeDialog}>Import Data Karyawan</ModalHeader> |
||||
<ModalBody> |
||||
{this.renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => this.handleSave()}>Import</Button>{' '} |
||||
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
@ -1,607 +0,0 @@
|
||||
import React, { Component } from 'react'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input,InputGroup, InputGroupButtonDropdown, DropdownToggle, DropdownItem, DropdownMenu,ButtonDropdown } from 'reactstrap'; |
||||
import { Button } from 'reactstrap'; |
||||
import axios from 'axios'; |
||||
import moment from 'moment'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import DialogForm from './DialogForm'; |
||||
import DialogImport from './DialogImport'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination } from 'antd'; |
||||
import { Tooltip } from 'reactstrap'; |
||||
import * as XLSX from 'xlsx'; |
||||
import { BASE_URL_GEOHR_API2 } from '../../../const/ApiConst' |
||||
import { Icon, InlineIcon } from '@iconify/react'; |
||||
import eyeFilled from '@iconify/icons-ant-design/eye-filled'; |
||||
import { Link } from 'react-router-dom'; |
||||
|
||||
const id_org = window.localStorage.getItem('id_org'); |
||||
const roleName = window.localStorage.getItem('role_name'); |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
const momentFormat = 'HH:mm'; |
||||
|
||||
const column = [ |
||||
{ name: "Organasi" }, |
||||
{ name: "Nama" },
|
||||
{ name: "Email" },
|
||||
{ name: "Nomor Handphone" },
|
||||
] |
||||
|
||||
const LENGTH_DATA = 10 |
||||
|
||||
const API = `https://oslog.id/geohr-api` |
||||
|
||||
|
||||
export default class index extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
dataTable: [], |
||||
finalData: [], |
||||
openDialog: false, |
||||
typeDialog: 'Save', |
||||
dataEdit: null, |
||||
alertDelete: false, |
||||
idDelete: 0, |
||||
dataGs: [], |
||||
dataIdHo: [], |
||||
search: "", |
||||
page: 0, |
||||
rowsPerPage: LENGTH_DATA, |
||||
currentPage: 1, |
||||
totalPage: 0, |
||||
tooltipEdit: false, |
||||
tooltipDelete: false, |
||||
splitButtonOpen:false, |
||||
searchDetail: "Nama", |
||||
searchDetailField: "name", |
||||
tooltipDetail: false, |
||||
tooltipTambah:false, |
||||
tooltipImport:false, |
||||
tooltipExport:false, |
||||
dataImport: null, |
||||
aksiDropdown:false, |
||||
openDialogImport:false, |
||||
dataExport:false, |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.getDataEmployee(); |
||||
} |
||||
|
||||
async componentDidUpdate(prevProps, prevState) { |
||||
const { search } = this.state |
||||
if (search !== prevState.search) this.getDataEmployee() |
||||
} |
||||
|
||||
toggleAksiDropdown = () => { |
||||
this.setState({aksiDropdown:!this.state.aksiDropdown}); |
||||
} |
||||
|
||||
handleSearch = e => { |
||||
const value = e.target.value |
||||
this.setState({ search: value, currentPage: 1 }) |
||||
}; |
||||
|
||||
getDataEmployee = async () => { |
||||
let start = 0; |
||||
if (this.state.currentPage !== 1) { |
||||
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage |
||||
} |
||||
let url = BASE_URL_GEOHR_API2 + `/employee.php?act=get_data&start=${start}&length=${this.state.rowsPerPage}&role_name=${roleName}`; |
||||
const formData = new FormData(); |
||||
formData.append("id_org", id_org); |
||||
formData.append('field', this.state.searchDetailField); |
||||
formData.append('value', this.state.search); |
||||
const result = await axios |
||||
.post(url,formData) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.statusText == "OK") { |
||||
this.setState({ dataTable: result.data.data, totalPage: result.data.total_record }); |
||||
} else { |
||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
setListIdHo = (data) => { |
||||
let list = []; |
||||
data.map((val, index) => { |
||||
list.push(val.sales) |
||||
}) |
||||
this.setState({ dataIdHo: list }, () => { |
||||
}) |
||||
} |
||||
|
||||
handleOpenDialog = (type) => { |
||||
this.setState({ openDialog: true, typeDialog: type }) |
||||
this.showChildDialog(); |
||||
} |
||||
|
||||
handleCloseDialog = async (type, data) => { |
||||
let result = false; |
||||
if (type === "save") { |
||||
result = await this.saveEmployee(data); |
||||
} else if (type === "edit") { |
||||
result = await this.editEmployee(data); |
||||
} |
||||
else if (type === "cancel") { |
||||
result = true; |
||||
} |
||||
|
||||
if (result) { |
||||
this.setState({ openDialog: false }) |
||||
} |
||||
} |
||||
|
||||
toggleAddDialog = () => { |
||||
this.setState({ openDialog: !this.state.openDialog }) |
||||
} |
||||
|
||||
onConfirmDelete = async () => { |
||||
const { idDelete } = this.state |
||||
let url = BASE_URL_GEOHR_API2 + `/employee.php?act=delete&id=${idDelete}`; |
||||
let result = await axios.get(url) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result.message!==undefined){ |
||||
|
||||
}else{ |
||||
|
||||
} |
||||
|
||||
if (result.data.message === "Data Has Been Deleted") { |
||||
this.getDataEmployee() |
||||
this.setState({ idDelete: 0, alertDelete: false }) |
||||
NotificationManager.success('Data employee berhasil dihapus!!', 'Success!!'); |
||||
} else { |
||||
this.setState({ idDelete: 0, alertDelete: false }) |
||||
NotificationManager.error('Data employee gagal dihapus!!', 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
saveEmployee = async (data) => { |
||||
let url = BASE_URL_GEOHR_API2 + "/employee.php?act=input"; |
||||
const formData = new FormData(); |
||||
formData.append('name', data.name); |
||||
formData.append('username', data.username); |
||||
formData.append('phone_number', data.phoneNumber); |
||||
formData.append('email', data.email); |
||||
formData.append('address', data.name); |
||||
formData.append('password', data.password); |
||||
formData.append('birth_place', data.birthPlace); |
||||
formData.append('birth_date', data.birthDate); |
||||
formData.append('gender', data.currentSelectGender ? data.currentSelectGender.value : ""); |
||||
formData.append('hobby', data.hobby); |
||||
formData.append('blood_type', data.currentSelectBlood ? data.currentSelectBlood.value: ""); |
||||
formData.append('ktp_number', data.nik); |
||||
formData.append('role_id', data.currentSelectRoles ? data.currentSelectRoles.value: ""); |
||||
|
||||
|
||||
|
||||
if(data.idRoles!==undefined && data.idRoles!==0 && data.idRoles!==null){ |
||||
formData.append('roles_id', data.idRoles); |
||||
} |
||||
|
||||
let result = await axios.post(url, formData) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (!result) { |
||||
return false; |
||||
} |
||||
|
||||
if(result && result.message!==undefined){ |
||||
if (result.message === "Data Has Been Saved") { |
||||
this.getDataEmployee(); |
||||
NotificationManager.success('Data employee berhasil ditambahkan!!', 'Success!!'); |
||||
return true; |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
return false; |
||||
} |
||||
}else{ |
||||
if (result.data.message === "Data Has Been Saved") { |
||||
this.getDataEmployee(); |
||||
NotificationManager.success('Data employee berhasil ditambahkan!!', 'Success!!'); |
||||
return true; |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
let ref_id = parseInt(result.data.data.id) |
||||
if (ref_id) { |
||||
if (data.files.length > 0) { |
||||
const formData = new FormData() |
||||
data.files.map((res) => { |
||||
console.log('test data upload photo', res) |
||||
if (res) |
||||
formData.append("ref_id", ref_id); |
||||
formData.append("files", res); |
||||
}) |
||||
await axios.post(`${API}/image/employee/upload`, formData).then(response => response).catch(err => err.response) |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
} |
||||
|
||||
editEmployee = async (data) => { |
||||
let url = BASE_URL_GEOHR_API2 + `/employee.php?act=edit&id=${data.id}&role_name=${roleName}`; |
||||
const formData = new FormData(); |
||||
formData.append('name', data.name); |
||||
formData.append('username', data.username); |
||||
formData.append('phone_number', data.phoneNumber); |
||||
formData.append('email', data.email); |
||||
formData.append('address', data.address); |
||||
formData.append('birth_place', data.birthPlace); |
||||
formData.append('birth_date', data.birthDate); |
||||
formData.append('gender', data.currentSelectGender ? data.currentSelectGender.value : ""); |
||||
formData.append('hobby', data.hobby); |
||||
formData.append('blood_type', data.currentSelectBlood ? data.currentSelectBlood.value: ""); |
||||
formData.append('role_id', data.currentSelectRoles ? data.currentSelectRoles.value: ""); |
||||
|
||||
formData.append('ktp_number', data.nik); |
||||
|
||||
|
||||
if(data.password!==""){ |
||||
formData.append('password', data.password); |
||||
} |
||||
|
||||
if(data.idRoles!==undefined && data.idRoles!==0 && data.idRoles!==null){ |
||||
formData.append('role_id', data.idRoles); |
||||
} |
||||
|
||||
|
||||
|
||||
let result = await axios.post(url, formData) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (!result) { |
||||
return false; |
||||
} |
||||
|
||||
if(result && result.message!==undefined){ |
||||
if (result.message === "Data Has Been Edited") { |
||||
this.getDataEmployee(); |
||||
NotificationManager.success('Data karyawan berhasil diedit!!', 'Success!!'); |
||||
return true; |
||||
} else { |
||||
NotificationManager.error('Data karyawan gagal diedit!!', 'Failed!!'); |
||||
return false |
||||
} |
||||
}else{ |
||||
if (result.data.message === "Data Has Been Edited") { |
||||
this.getDataEmployee(); |
||||
NotificationManager.success('Data karyawan berhasil diedit!!', 'Success!!'); |
||||
return true; |
||||
} else { |
||||
NotificationManager.error('Data karyawan gagal diedit!!', 'Failed!!'); |
||||
return false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
|
||||
handleEdit = (data) => { |
||||
this.setState({ dataEdit: data }); |
||||
this.handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
handleDetail = (data) => { |
||||
this.setState({ dataEdit: data }) |
||||
this.handleOpenDialog('View'); |
||||
|
||||
} |
||||
|
||||
handleDelete = (id) => { |
||||
this.setState({ alertDelete: true, idDelete: id }); |
||||
} |
||||
|
||||
onShowSizeChange = (current, pageSize) => { |
||||
this.setState({ rowsPerPage: pageSize }, () => { |
||||
this.getDataEmployee(); |
||||
}) |
||||
|
||||
} |
||||
|
||||
onPagination = (current, pageSize) => { |
||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { |
||||
this.getDataEmployee(); |
||||
}) |
||||
} |
||||
|
||||
toggle = (param) => { |
||||
if (param === "edit") { |
||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
||||
} else if (param === "delete") { |
||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
||||
} else if (param === "detail") { |
||||
this.setState(prevState => ({ tooltipDetail: !prevState.tooltipDetail })) |
||||
} else if (param === "tambah") { |
||||
this.setState(prevState => ({ tooltipTambah: !prevState.tooltipTambah })) |
||||
} else if (param === "import") { |
||||
this.setState(prevState => ({ tooltipImport : !prevState.tooltipImport })) |
||||
} else if (param === "export") { |
||||
this.setState(prevState => ({ tooltipExport: !prevState.tooltipExport })) |
||||
} |
||||
|
||||
} |
||||
|
||||
toggleDropDown = () => { |
||||
this.setState({splitButtonOpen:!this.state.splitButtonOpen}) |
||||
} |
||||
|
||||
handleDialogImport = () => { |
||||
this.setState({ openDialogImport: true}) |
||||
this.showImportDialog(); |
||||
} |
||||
|
||||
handleCloseImport = (type, file) => { |
||||
if(type==="import"){ |
||||
if(!file){ |
||||
NotificationManager.error('Silahkan masukan file excel!!', 'Failed!!'); |
||||
return false |
||||
} |
||||
|
||||
if (/\.(xls?x)$/i.test(file.name) === false ) {
|
||||
NotificationManager.error('File yang dimasukan bukan format excel (.xsl/.xslx)!!', 'Failed!!'); |
||||
return false |
||||
} |
||||
|
||||
this.importExcel(file); |
||||
|
||||
}else{ |
||||
this.setState({ openDialogImport:false }); |
||||
} |
||||
} |
||||
|
||||
toggleImportDialog = () => { |
||||
this.setState({ openDialogImport:!this.state.openDialogImport }) |
||||
} |
||||
|
||||
importExcel = async (file) => { |
||||
const url = `${BASE_URL_GEOHR_API2}/employee.php?act=import`;
|
||||
const formData = new FormData(); |
||||
formData.append('file', file); |
||||
const result = await axios |
||||
.post(url, formData) |
||||
.then((res) => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.code_status){ |
||||
if (result.code_status === 200) { |
||||
NotificationManager.success('File imported successfully', 'Success Message'); |
||||
this.getDataEmployee(); |
||||
this.setState({openDialogImport: false}); |
||||
} else { |
||||
NotificationManager.error(result.data.message, "error message"); |
||||
} |
||||
}else{ |
||||
NotificationManager.error("Import data karyawan gagal!!", "error message"); |
||||
} |
||||
|
||||
} |
||||
|
||||
getTemplateExcel = async (event) => { |
||||
event.preventDefault(); |
||||
const url = `${BASE_URL_GEOHR_API2}/dok/template-import-karyawan.xlsx`; |
||||
window.open(url, "_blank"); |
||||
}; |
||||
|
||||
|
||||
handleExportExcel = async () => { |
||||
let start = 0; |
||||
let end = "ALL";
|
||||
let url = BASE_URL_GEOHR_API2 + `/employee.php?act=get_data&start=${start}&length=${end}&role_name=${roleName}`; |
||||
const formData = new FormData(); |
||||
formData.append('field', this.state.searchDetailField); |
||||
formData.append('value', this.state.search); |
||||
const result = await axios |
||||
.post(url,formData) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.statusText == "OK") { |
||||
const dataRes = result.data.data|| []; |
||||
const dataExport = []; |
||||
dataRes.map((val,index)=> { |
||||
let row = { |
||||
Nama:val.name, |
||||
Organisasi:val.organization_name || "-", |
||||
Nik:val.ktp_number, |
||||
Username:val.username, |
||||
Email:val.email, |
||||
"Nomor Handphone":val.phone_number, |
||||
"Tanggal Lahir":val.birth_date, |
||||
"Tempat Lahir":val.birth_place, |
||||
"Hobby":val.hobby, |
||||
"Jenis Kelamin":val.gender, |
||||
"Golongan Data":val.blood_type, |
||||
} |
||||
dataExport.push(row); |
||||
}) |
||||
this.setState({ dataExport:dataExport },()=> { |
||||
this.exportExcel(); |
||||
}); |
||||
} else { |
||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
exportExcel = () => { |
||||
const dataExcel = this.state.dataExport || []; |
||||
const fileName = "Data Karyawan.xlsx"; |
||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, 'Data Karyawan'); |
||||
|
||||
XLSX.writeFile(wb, fileName); |
||||
} |
||||
|
||||
|
||||
render() { |
||||
const { tooltipTambah,tooltipImport,tooltipExport,tooltipDetail, dataTable, searchDetail, splitButtonOpen, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipEdit, tooltipDelete } = this.state |
||||
let dataTable2 = dataTable || []; |
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={this.state.alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title="Are you sure?" |
||||
onConfirm={this.onConfirmDelete} |
||||
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })} |
||||
focusCancelBtn |
||||
> |
||||
Data karyawan akan terhapus!! |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={this.handleCloseDialog} |
||||
toggleDialog={() => this.toggleAddDialog} |
||||
typeDialog={this.state.typeDialog} |
||||
dataEdit={this.state.dataEdit} |
||||
showDialog={showDialog => this.showChildDialog = showDialog} |
||||
dataHs={this.state.dataIdHo} |
||||
/> |
||||
<DialogImport |
||||
openDialog={this.state.openDialogImport} |
||||
closeDialog={this.handleCloseImport} |
||||
toggleDialog={() => this.toggleImportDialog} |
||||
showDialog={showDialog => this.showImportDialog = showDialog} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{margin:0}}> |
||||
<Row style={{padding:0,margin:0}}> |
||||
<Col md={7} xs={7}> |
||||
<h4>Karyawan</h4> |
||||
</Col> |
||||
<Col md={3} xs={3}> |
||||
<InputGroup> |
||||
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={`Search ${searchDetail}`} /> |
||||
<InputGroupButtonDropdown addonType="prepend" |
||||
isOpen={splitButtonOpen} |
||||
toggle={this.toggleDropDown} |
||||
> |
||||
<DropdownToggle split outline /> |
||||
<DropdownMenu> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Nama", |
||||
searchDetailField: "name" |
||||
})}>Nama</DropdownItem> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Nomor Handphone", |
||||
searchDetailField: "phone_number" |
||||
})}>Nomor Handphone</DropdownItem> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Email", |
||||
searchDetailField: "email" |
||||
})}>Email</DropdownItem> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Alamat", |
||||
searchDetailField: "address" |
||||
})}>Alamat</DropdownItem> |
||||
</DropdownMenu> |
||||
</InputGroupButtonDropdown> |
||||
</InputGroup> |
||||
</Col> |
||||
<Col md={2} xs={2} style={{display:"flex",justifyContent:"space-between"}}> |
||||
<Button id="TooltipTambah" color="success" onClick={() => this.handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
<ButtonDropdown id="TooltipImport" direction="down" isOpen={this.state.aksiDropdown} toggle={() => this.toggleAksiDropdown()}> |
||||
<DropdownToggle color="info" caret > |
||||
<i className="fa fa-cloud-upload"></i> |
||||
</DropdownToggle> |
||||
<DropdownMenu> |
||||
<DropdownItem onClick={() => this.handleDialogImport()}>Import Data Karyawan</DropdownItem> |
||||
<DropdownItem onClick={(e) => this.getTemplateExcel(e)}>Download Template</DropdownItem> |
||||
</DropdownMenu> |
||||
</ButtonDropdown> |
||||
<Button id="TooltipExport" color="primary" onClick={()=> this.handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
<Tooltip placement="right" isOpen={tooltipTambah} target="TooltipTambah" toggle={() => this.toggle("tambah")}> |
||||
Tambah |
||||
</Tooltip> |
||||
<Tooltip placement="right" isOpen={tooltipImport} target="TooltipImport" toggle={() => this.toggle("import")}> |
||||
Import Excel |
||||
</Tooltip> |
||||
<Tooltip placement="right" isOpen={tooltipExport} target="TooltipExport" toggle={() => this.toggle("export")}> |
||||
Export Excel |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
<th>Aksi</th> |
||||
{column.map((i, index) => { |
||||
return ( |
||||
<th key={index} scope="row">{i.name}</th> |
||||
) |
||||
})} |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{dataTable2.map((n) => { |
||||
return ( |
||||
<tr key={n.id}> |
||||
<td> |
||||
<i id="TooltipDelete" className="cil-trash fa-lg" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => this.handleDelete(n.id)}></i> |
||||
<Tooltip placement="right" isOpen={tooltipDelete} target="TooltipDelete" toggle={() => this.toggle("delete")}> |
||||
Hapus |
||||
</Tooltip> |
||||
<i id="TooltipEdit" className="cil-pencil fa-lg" style={{ color: 'green', cursor: "pointer" }} onClick={() => this.handleEdit(n)}></i> |
||||
<Tooltip placement="right" isOpen={tooltipEdit} target="TooltipEdit" toggle={() => this.toggle("edit")}> |
||||
Edit |
||||
</Tooltip> |
||||
<i id="TooltipDetail" style={{ marginLeft: 12, color: "blue", cursor: "pointer", }} onClick={() => this.handleDetail(n)}> |
||||
|
||||
<Icon style={{ marginBottom: 6 }} color="blue" width={22} height={22} icon={eyeFilled} /> |
||||
</i> |
||||
|
||||
<Tooltip placement="right" isOpen={tooltipDetail} target="TooltipDetail" toggle={() => this.toggle("detail")}> |
||||
Detail |
||||
</Tooltip> |
||||
</td> |
||||
<td>{n.organization_name===null ? n.chairman_org || "-" : n.organization_name || "-"}</td> |
||||
<td>{n.name}</td> |
||||
<td>{n.email || "-"}</td> |
||||
<td>{n.phone_number || "-"}</td> |
||||
</tr> |
||||
) |
||||
})} |
||||
</tbody> |
||||
</Table> |
||||
<Pagination |
||||
showSizeChanger |
||||
onShowSizeChange={this.onShowSizeChange} |
||||
onChange={this.onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={totalPage} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
} |
||||
|
@ -1,262 +0,0 @@
|
||||
import React, { Component } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import Select from 'react-select' |
||||
|
||||
export default class DialogForm extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
openDialog: false, |
||||
type_sales:'B2B', |
||||
name: '', |
||||
email: '', |
||||
address: '', |
||||
username: '', |
||||
phoneNumber: '', |
||||
password:'', |
||||
id: 0, |
||||
idGs:0, |
||||
isParentClick: false, |
||||
file: [], |
||||
fileObj: [], |
||||
fileArray: [], |
||||
dataGs: [], |
||||
currentSelectVal: null, |
||||
} |
||||
} |
||||
|
||||
async componentDidMount(){ |
||||
this.props.showDialog(this.showDialog); |
||||
this.cekDataGs() |
||||
} |
||||
|
||||
async componentDidUpdate (){ |
||||
if(this.state.isParentClick===true){ |
||||
await this.cekDataGs() |
||||
if(this.props.typeDialog==="Edit"){ |
||||
let dataGs = this.searchGs(this.props.dataEdit.group_sales); |
||||
this.setState({
|
||||
idGs:this.props.dataEdit.group_sales, |
||||
id:this.props.dataEdit.id, |
||||
name:this.props.dataEdit.name, |
||||
type_sales:this.props.dataEdit.type_sales, |
||||
email: this.props.dataEdit.email, |
||||
address: this.props.dataEdit.address, |
||||
username: this.props.dataEdit.username, |
||||
phoneNumber: this.props.dataEdit.phone_number, |
||||
password:this.props.dataEdit.password, |
||||
currentSelectVal:dataGs |
||||
}) |
||||
}else{ |
||||
this.setState({
|
||||
id:0, |
||||
name:'', |
||||
type_sales:'B2B', |
||||
email: '', |
||||
address:'', |
||||
username: '', |
||||
phoneNumber: '', |
||||
password: '', |
||||
currentSelectVal:null |
||||
}) |
||||
} |
||||
this.setState({isParentClick:false}); |
||||
} |
||||
} |
||||
|
||||
searchGs = (idGs) => { |
||||
let getIndex = this.getIndexDataGs(idGs); |
||||
return this.state.dataGs[getIndex]; |
||||
} |
||||
|
||||
getIndexDataGs = (val) => { |
||||
let index = this.state.dataGs.findIndex(obj => obj.value === val); |
||||
return index |
||||
} |
||||
|
||||
cekDataGs = () => { |
||||
if(this.state.dataGs.length===0){ |
||||
let data = []; |
||||
this.props.dataGs.map((val,index) => { |
||||
data.push( |
||||
{ |
||||
value: val.id, |
||||
label: val.name |
||||
} |
||||
) |
||||
}); |
||||
this.setState({ dataGs:data }) |
||||
} |
||||
} |
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick : true }); |
||||
} |
||||
|
||||
|
||||
handleSave = () => { |
||||
const { file, name, email, id, address, phoneNumber, password, username, idGs,type_sales } = this.state |
||||
let data = ''; |
||||
if(this.props.typeDialog==="Save"){ |
||||
data = { |
||||
username, |
||||
password, |
||||
name,
|
||||
email,
|
||||
address,
|
||||
phone_number:phoneNumber, |
||||
group_sales:idGs, |
||||
type_sales |
||||
} |
||||
this.props.closeDialog('save', data, file); |
||||
}else{ |
||||
data = { |
||||
id, |
||||
username, |
||||
password, |
||||
name,
|
||||
email,
|
||||
address,
|
||||
phone_number:phoneNumber, |
||||
group_sales:idGs, |
||||
type_sales |
||||
} |
||||
this.props.closeDialog('edit', data, file); |
||||
} |
||||
|
||||
this.setState({ id:'',username:'',password:'',name:'',email:'',address:'',phoneNumber:'',file:[],idGs:0,type_sales:'B2B',currentSelectVal:null }); |
||||
|
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.setState({ id:'',username:'',password:'',name:'',email:'',address:'',phoneNumber:'',file:[],idGs:0,type_sales:'B2B' }); |
||||
this.props.closeDialog('cancel', 'none', 'none') |
||||
} |
||||
|
||||
uploadMultipleImage = (event) => { |
||||
this.setState({ fileObj: [...this.state.fileObj, event.target.files],file: [...this.state.file, event.target.files] }, ()=> { |
||||
this.setUrl() |
||||
}) |
||||
|
||||
} |
||||
|
||||
setUrl = () => { |
||||
for (let i = 0; i < this.state.fileObj[0].length; i++) { |
||||
this.setState({ fileArray: [...this.state.fileArray, URL.createObjectURL(this.state.fileObj[0][i])],fileObj:[] }) |
||||
} |
||||
} |
||||
|
||||
handleSelectGs = (inputValue, actionMeta) => { |
||||
this.setState({ idGs:inputValue.value,currentSelectVal:{ value:inputValue.value,label:inputValue.label } }) |
||||
} |
||||
|
||||
handleTypeSales = (e) => { |
||||
this.setState({ type_sales:e.target.value }) |
||||
} |
||||
|
||||
renderForm = () => { |
||||
return( |
||||
<Form> |
||||
<Row form> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label for="exampleEmail">Group Sales </Label> |
||||
<Select options={this.state.dataGs} onChange={this.handleSelectGs} value={this.state.currentSelectVal} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label for="examplePassword">Username</Label> |
||||
<Input type="text" value={this.state.username} onChange={(e)=> this.setState({ username:e.target.value })} placeholder="username " /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row form> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label for="exampleEmail">Password </Label> |
||||
<Input type="password" value={this.state.password} onChange={(e)=> this.setState({ password:e.target.value })} placeholder="password" /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label for="examplePassword">Name</Label> |
||||
<Input type="text" value={this.state.name} onChange={(e)=> this.setState({ name:e.target.value })} placeholder="name " /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row form> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label for="exampleEmail">Email</Label> |
||||
<Input type="email" value={this.state.email} onChange={(e)=> this.setState({ email:e.target.value })} placeholder="email" /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label for="examplePassword">Address</Label> |
||||
<Input type="text" value={this.state.address} onChange={(e)=> this.setState({ address:e.target.value })} placeholder="address " /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
<Row form> |
||||
<Col md={6}> |
||||
<FormGroup> |
||||
<Label for="exampleEmail">Phone Number</Label> |
||||
<Input type="number"value={this.state.phoneNumber} onChange={(e)=> this.setState({ phoneNumber:e.target.value })} placeholder="phone number" /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<Label>Type Sales</Label> |
||||
<Row> |
||||
<Col md={6}> |
||||
<FormGroup check> |
||||
<Label check> |
||||
<Input type="radio" name="radioTypeC" value="B2B" onChange={this.handleTypeSales} checked={this.state.type_sales==="B2B"} />{' '} |
||||
B2B |
||||
</Label> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col md={6}> |
||||
<FormGroup check> |
||||
<Label check> |
||||
<Input type="radio" name="radioTypeC" value="B2C" onChange={this.handleTypeSales} checked={this.state.type_sales==="B2C"} />{' '} |
||||
B2C |
||||
</Label> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</Col> |
||||
</Row> |
||||
<FormGroup> |
||||
<div style={{overflowY:"auto "}}> |
||||
{(this.state.fileArray || []).map((url,index) => ( |
||||
<img key={index} src={url} alt="..." style={{ maxWidth:"150px",maxHeight:"150px" }} /> |
||||
))} |
||||
</div> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label for="exampleAddress">Images</Label> |
||||
<Input type="file" onChange={this.uploadMultipleImage} /> |
||||
</FormGroup> |
||||
|
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog} size="xl"> |
||||
<ModalHeader toggle={this.props.closeDialog}>Add Sales</ModalHeader> |
||||
<ModalBody> |
||||
{this.renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => this.handleSave()}>{this.props.typeDialog}</Button>{' '} |
||||
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
@ -1,347 +0,0 @@
|
||||
import React, { Component } from 'react'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input, Modal, ModalHeader, ModalBody, ModalFooter, FormGroup, Label } from 'reactstrap'; |
||||
import { Button } from 'reactstrap'; |
||||
import axios from 'axios'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import DialogForm from './DialogForm'; |
||||
import { NotificationContainer, NotificationManager} from 'react-notifications'; |
||||
import { Pagination } from 'antd'; |
||||
import { Icon, InlineIcon } from '@iconify/react'; |
||||
import settingOutlined from '@iconify/icons-ant-design/setting-outlined'; |
||||
import {Link} from 'react-router-dom' |
||||
import Select from 'react-select' |
||||
|
||||
import { SketchPicker } from 'react-color'; |
||||
|
||||
|
||||
const BASE_URL = "https://oslog.id/geohr-api/"; |
||||
|
||||
|
||||
const column = [ |
||||
{ name: "Group Sales" }, |
||||
{ name: "Name" }, |
||||
{ name: "Phone Number" }, |
||||
{ name: "Email" }, |
||||
{ name: "Address" }, |
||||
] |
||||
|
||||
const layerSales = [ |
||||
{ |
||||
"id": 1, |
||||
"rule_name": "sales yang incomenya lebih dari 1000000", |
||||
"style": { |
||||
"fill_color": "#22194D", |
||||
}, |
||||
"rule": { |
||||
"column": "income", |
||||
"operator": ">", |
||||
"value": 1000000, |
||||
} |
||||
}, |
||||
{ |
||||
"id": 2, |
||||
"rule_name": "sales yang punya nama mohammad", |
||||
"style": { |
||||
"fill_color": "#22194D", |
||||
}, |
||||
"rule": { |
||||
"column": "name", |
||||
"operator": "like", |
||||
"value": "mohammad" |
||||
} |
||||
}, |
||||
|
||||
|
||||
] |
||||
|
||||
const options = [ |
||||
{ value: 'group-sales', label: 'Group Sales' }, |
||||
{ value: 'name', label: 'Name' }, |
||||
{ value: 'phone-number', label: 'Phone Number' }, |
||||
{ value: 'email', label: 'Email' }, |
||||
{ value: 'address', label: 'Address' } |
||||
|
||||
] |
||||
|
||||
const logicOperator = [ |
||||
{ value: '>', label: '>' }, |
||||
{ value: '>=', label: '>=' }, |
||||
{ value: '<', label: '<' }, |
||||
{ value: '<=', label: '<=' }, |
||||
{ value: '==', label: '==' }, |
||||
{ value: '<>', label: '<>' }, |
||||
] |
||||
|
||||
|
||||
const LENGTH_DATA = 10 |
||||
export default class SettingSales extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
dataTable: [], |
||||
openDialog: false, |
||||
typeDialog: 'Save', |
||||
dataEdit: null, |
||||
alertDelete: false, |
||||
idDelete: 0, |
||||
dataGs: [], |
||||
search: "", |
||||
page: 0, |
||||
rowsPerPage: LENGTH_DATA, |
||||
currentPage: 1, |
||||
totalPage: 0, |
||||
layersSales: [], |
||||
modalEdit: false, |
||||
modalAdd: false, |
||||
id: 0, |
||||
fill_color: "#000", |
||||
column: "", |
||||
operator: "", |
||||
value: "", |
||||
dataEdit: null, |
||||
|
||||
} |
||||
} |
||||
|
||||
|
||||
async componentDidMount (){ |
||||
this.getRuleSales() |
||||
} |
||||
|
||||
async componentDidUpdate (prevProps, prevState){ |
||||
const { search } = this.state |
||||
if (search !== prevState.search) this.getRuleSales() |
||||
} |
||||
|
||||
handleOpenDialog = (type) => { |
||||
this.setState({modalEdit: true, typeDialog: type }) |
||||
this.handleSetData() |
||||
} |
||||
|
||||
handleSetData = () => { |
||||
const { dataEdit, typeDialog} = this.state |
||||
if(typeDialog === "Edit") { |
||||
this.setState({ |
||||
id: dataEdit.id, |
||||
rule_name: dataEdit.rule_name, |
||||
fill_color: dataEdit.style.fill_color, |
||||
column: dataEdit.rule.column, |
||||
value: dataEdit.rule.value, |
||||
operator: dataEdit.rule.operator |
||||
|
||||
}) |
||||
} else { |
||||
this.setState({ |
||||
id: 0, |
||||
rule_name: "", |
||||
fill_color: "#000", |
||||
column: null, |
||||
value:"", |
||||
operator: null |
||||
|
||||
}) |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
handleEdit = (data) => { |
||||
this.setState({dataEdit: data}) |
||||
this.handleOpenDialog('Edit') |
||||
console.log('test data edit', data) |
||||
|
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.setState({ |
||||
|
||||
rule_name: "", |
||||
fill_color: "#000", |
||||
column: null, |
||||
value:"", |
||||
operator: null, |
||||
modalEdit: false |
||||
}) |
||||
|
||||
|
||||
|
||||
|
||||
} |
||||
|
||||
handleSave = () => { |
||||
this.setState({ |
||||
|
||||
rule_name: "", |
||||
fill_color: "#000", |
||||
column: null, |
||||
value:"", |
||||
operator: null, |
||||
modalEdit: false }) |
||||
|
||||
|
||||
} |
||||
|
||||
toggleAdd = () => { |
||||
this.setState({modalAdd: !this.state.modalAdd}) |
||||
} |
||||
|
||||
getRuleSales = () => { |
||||
this.setState({layersSales: layerSales}) |
||||
} |
||||
|
||||
handleChangeComplete = (color, event) => { |
||||
|
||||
console.log('handleChangeComplete',color, event); |
||||
this.setState({fill_color: color.hex}); |
||||
} |
||||
|
||||
|
||||
render() { |
||||
const {layersSales, modalEdit, modalAdd, search, openDialog, currentPage, rowsPerPage,totalPage, dataTable } = this.state |
||||
let noSeq = 0; |
||||
return ( |
||||
<div> |
||||
<NotificationContainer/> |
||||
<SweetAlert |
||||
show={this.state.alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title="Are you sure?" |
||||
onConfirm={()=> this.setState({ alertDelete:false })} |
||||
onCancel={()=> this.setState({ alertDelete:false })} |
||||
focusCancelBtn |
||||
> |
||||
Rule sales akan terhapus!! |
||||
</SweetAlert> |
||||
|
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4>Rules Sales</h4> |
||||
<div> |
||||
<Button onClick={this.handleOpenDialog} color="primary" >Add Rule</Button> |
||||
</div> |
||||
</CardHeader> |
||||
|
||||
|
||||
|
||||
<CardBody> |
||||
{layersSales.map((n) => { |
||||
return( |
||||
<Row key={n.id}> |
||||
<Col > |
||||
|
||||
<Card className="layer-list"> |
||||
<CardBody> |
||||
<Row> |
||||
<Col xs={2}> |
||||
<div style={{width: 20, height: 20, backgroundColor: n.style.fill_color }} /> |
||||
</Col> |
||||
|
||||
<Col xs={8} > |
||||
<span className="layer-title">{n.rule_name}</span> |
||||
</Col> |
||||
<Col > |
||||
<div style={{ flexDirection: "row", justifyContent: "flex-end", }}> |
||||
<Button onClick={()=> this.handleEdit(n)} color="success">Edit</Button> |
||||
<Button onClick={()=> this.setState({alertDelete: true})} style={{ marginLeft: 16 }} color="danger">Hapus</Button> |
||||
|
||||
</div> |
||||
|
||||
</Col> |
||||
|
||||
</Row> |
||||
</CardBody> |
||||
</Card> |
||||
|
||||
</Col> |
||||
|
||||
</Row> |
||||
|
||||
|
||||
) |
||||
}) |
||||
|
||||
} |
||||
|
||||
|
||||
</CardBody> |
||||
</Card> |
||||
<Modal isOpen={modalEdit} toggle={this.handleCancel} > |
||||
<ModalHeader toggle={modalEdit}>Edit Rule Name</ModalHeader> |
||||
<ModalBody> |
||||
<div className="modal-body-container"> |
||||
<FormGroup> |
||||
<Label>Layer Name</Label> |
||||
<Input value={this.state.rule_name} onChange={(e)=> this.setState({ rule_name :e.target.value })} /> |
||||
</FormGroup> |
||||
|
||||
<FormGroup> |
||||
<Label>Fill Color</Label> |
||||
<SketchPicker |
||||
color={ this.state.fill_color } |
||||
onChangeComplete={ this.handleChangeColorComplete } |
||||
/> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>Rule</Label> |
||||
<Row> |
||||
<Col > |
||||
<Select value={this.state.column} options={options} /> |
||||
</Col> |
||||
<Col> |
||||
<Select value={this.state.operator} options={logicOperator} /> |
||||
|
||||
</Col> |
||||
<Col > |
||||
<Input value={this.state.value} onChange={(e)=> this.setState({ value :e.target.value })} /> |
||||
</Col> |
||||
</Row> |
||||
</FormGroup> |
||||
</div> |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={this.handleSave}>Update</Button>{' '} |
||||
<Button color="secondary" onClick={this.handleCancel}>Cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
{/* <Modal isOpen={modalAdd} toggle={this.toggleAdd} > |
||||
<ModalHeader toggle={modalEdit}>Add Rule Name</ModalHeader> |
||||
<ModalBody> |
||||
<div className="modal-body-container"> |
||||
<FormGroup> |
||||
<Label>Rule Name</Label> |
||||
<Input /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>Fill Color</Label> |
||||
<SketchPicker /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>Rule</Label> |
||||
<Row> |
||||
<Col> |
||||
<Select options={options} /> |
||||
</Col> |
||||
<Col> |
||||
<Select options={logicOperator} /> |
||||
|
||||
</Col> |
||||
<Col xs={5}> |
||||
<Input /> |
||||
</Col> |
||||
</Row> |
||||
</FormGroup> |
||||
</div> |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={this.toggleAdd}>Save</Button>{' '} |
||||
<Button color="secondary" onClick={this.toggleAdd}>Cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> */} |
||||
|
||||
</div> |
||||
) |
||||
} |
||||
} |
@ -1,399 +0,0 @@
|
||||
import React, { Component } from 'react'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input, InputGroup, InputGroupButtonDropdown, DropdownToggle, DropdownItem, DropdownMenu } from 'reactstrap'; |
||||
import { Button } from 'reactstrap'; |
||||
import axios from 'axios'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import DialogForm from './DialogForm'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination } from 'antd'; |
||||
import { Icon, InlineIcon } from '@iconify/react'; |
||||
import settingOutlined from '@iconify/icons-ant-design/setting-outlined'; |
||||
import { Link } from 'react-router-dom'; |
||||
import { Tooltip } from 'reactstrap'; |
||||
|
||||
|
||||
|
||||
const BASE_URL = "https://oslog.id/geohr-api/"; |
||||
|
||||
|
||||
const column = [ |
||||
{ name: "Group Sales" }, |
||||
{ name: "Name" }, |
||||
{ name: "Phone Number" }, |
||||
{ name: "Email" }, |
||||
{ name: "Address" }, |
||||
] |
||||
|
||||
const LENGTH_DATA = 10 |
||||
export default class index extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
dataTable: [], |
||||
openDialog: false, |
||||
typeDialog: 'Save', |
||||
dataEdit: null, |
||||
alertDelete: false, |
||||
idDelete: 0, |
||||
dataGs: [], |
||||
search: "", |
||||
page: 0, |
||||
rowsPerPage: LENGTH_DATA, |
||||
currentPage: 1, |
||||
totalPage: 0, |
||||
splitButtonOpen: false, |
||||
dropdownOpen: false, |
||||
searchDetail: "All", |
||||
searchDetailField: "name", |
||||
tooltipDelete: false, |
||||
tooltipEdit: false |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.getDataSales(); |
||||
this.getDataGroupSales(); |
||||
} |
||||
|
||||
async componentDidUpdate(prevProps, prevState) { |
||||
const { search } = this.state |
||||
if (search !== prevState.search) this.getDataSales() |
||||
} |
||||
|
||||
getDataGroupSales = async () => { |
||||
let url = BASE_URL + "group-sales/search"; |
||||
const obj = { |
||||
"paging": { "start": 0, "length": -1 }, |
||||
"columns": [ |
||||
{ |
||||
"name": "name", |
||||
"logic_operator": "ilike", |
||||
"value": "", |
||||
"operator": "and" |
||||
} |
||||
], |
||||
"orders": { "columns": ["name"], "ascending": true } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(url, obj) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.message == "OK") { |
||||
this.setState({ dataGs: result.data.data }); |
||||
} else { |
||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
|
||||
getDataSales = async () => { |
||||
const { searchDetail, searchDetailField } = this.state |
||||
let url = BASE_URL + "sales/search"; |
||||
let start = 0 |
||||
if (this.state.currentPage !== 1) { |
||||
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage |
||||
} |
||||
const obj = { |
||||
"paging": { "start": start, "length": this.state.rowsPerPage }, |
||||
...searchDetail === "All" && |
||||
{ |
||||
"filter_columns": [ |
||||
{ "name": "name", "value": this.state.search.toString() }, |
||||
{ "name": "phone_number", "value": this.state.search.toString() }, |
||||
{ "name": "email", "value": this.state.search.toString() }, |
||||
{ "name": "address", "value": this.state.search.toString() }, |
||||
{ "name": "name", "value": this.state.search.toString(), "table_name": "m_group_sales" }, |
||||
], |
||||
}, |
||||
...searchDetail !== "All" && searchDetail !== "Group Sales" && |
||||
{ |
||||
"columns": [ |
||||
{ "name": searchDetailField, "logic_operator": "ilike", "operator": "and", "value": this.state.search.toString() } |
||||
] |
||||
}, |
||||
...searchDetail === "Group Sales" && |
||||
{ |
||||
"columns": [ |
||||
{ "name": searchDetailField, "logic_operator": "ilike", "operator": "and", "value": this.state.search.toString(), "table_name": "m_group_sales" } |
||||
] |
||||
}, |
||||
|
||||
"joins": [ |
||||
{ "name": "group_sales", "column_results": ["name", "description"] } |
||||
], |
||||
"orders": { "columns": ["name"], "ascending": true } |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(url, obj) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.message == "OK") { |
||||
this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord }); |
||||
} else { |
||||
NotificationManager.error('Failed retreiving data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
handleOpenDialog = (type) => { |
||||
this.setState({ openDialog: true, typeDialog: type }) |
||||
this.showChildDialog(); |
||||
} |
||||
|
||||
handleCloseDialog = (type, data, files) => { |
||||
if (type === "save") { |
||||
this.saveSales(data, files); |
||||
} else if (type === "edit") { |
||||
this.editSales(data, files); |
||||
this.uploadImage(files, data.id); |
||||
} |
||||
|
||||
this.setState({ openDialog: false }) |
||||
} |
||||
|
||||
toggleAddDialog = () => { |
||||
this.setState({ openDialog: !this.state.openDialog }) |
||||
} |
||||
|
||||
onConfirmDelete = async () => { |
||||
const { idDelete } = this.state |
||||
let url = BASE_URL + `sales/${idDelete}/delete`; |
||||
const result = await axios.delete(url) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.message === "OK") { |
||||
this.getDataSales() |
||||
this.setState({ idDelete: 0, alertDelete: false }) |
||||
NotificationManager.success('Data group sales berhasil dihapus!!', 'Success!!'); |
||||
} else { |
||||
this.setState({ idDelete: 0, alertDelete: false }) |
||||
NotificationManager.error('Data group sales galal dihapus!!', 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
|
||||
saveSales = async (obj, files) => { |
||||
let url = BASE_URL + "sales/add"; |
||||
let data = JSON.stringify(obj); |
||||
const result = await axios.post(url, data) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.message === "OK") { |
||||
let ref_id = parseInt(result.data.data.id); |
||||
this.uploadImage(files, ref_id); |
||||
NotificationManager.success('Data sales berhasil ditambahkan!!', 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
editSales = async (data) => { |
||||
let url = BASE_URL + `sales/${data.id}/edit`; |
||||
const obj = JSON.stringify(data); |
||||
const result = await axios.put(url, obj) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if (result && result.data && result.data.message === "OK") { |
||||
this.getDataSales(); |
||||
NotificationManager.success('Data sales berhasil diedit!!', 'Success!!'); |
||||
} else { |
||||
NotificationManager.error('Data sales galal diedit!!', 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
uploadImage = async (files, idRef) => { |
||||
if (files.length > 0) { |
||||
let promises = []; |
||||
let response = []; |
||||
let url = BASE_URL + `image/m_sales/upload`; |
||||
files.map((val, index) => { |
||||
let formData = new FormData(); |
||||
formData.append("ref_id", idRef); |
||||
formData.append("files", val[0]); |
||||
promises.push(axios.post(url, formData) |
||||
.then(res => { response.push(res) })) |
||||
}) |
||||
await Promise.all(promises); |
||||
} |
||||
|
||||
this.getDataSales() |
||||
} |
||||
|
||||
handleEdit = (data) => { |
||||
this.setState({ dataEdit: data }); |
||||
this.handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
handleDelete = (id) => { |
||||
this.setState({ alertDelete: true, idDelete: id }); |
||||
} |
||||
|
||||
onShowSizeChange = (current, pageSize) => { |
||||
this.setState({ rowsPerPage: pageSize }, () => { |
||||
this.getDataSales(); |
||||
}) |
||||
} |
||||
|
||||
onPagination = (current, pageSize) => { |
||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { |
||||
this.getDataSales(); |
||||
}) |
||||
} |
||||
|
||||
handleSearch = e => { |
||||
const value = e.target.value |
||||
this.setState({ search: value, currentPage: 1 }) |
||||
}; |
||||
|
||||
toggleDropDown = () => { |
||||
this.setState(prevState => ({ splitButtonOpen: !prevState.splitButtonOpen })) |
||||
} |
||||
|
||||
toggle = (param) => { |
||||
if (param === "edit") { |
||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
||||
} else if (param === "delete") { |
||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
render() { |
||||
const { search, openDialog, currentPage, rowsPerPage, totalPage, dataTable, splitButtonOpen, searchDetail, tooltipDelete, tooltipEdit } = this.state |
||||
let noSeq = 0; |
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={this.state.alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title="Are you sure?" |
||||
onConfirm={this.onConfirmDelete} |
||||
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })} |
||||
focusCancelBtn |
||||
> |
||||
Data group sales akan terhapus!! |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={this.handleCloseDialog} |
||||
toggleDialog={() => this.toggleAddDialog} |
||||
typeDialog={this.state.typeDialog} |
||||
dataEdit={this.state.dataEdit} |
||||
showDialog={showDialog => this.showChildDialog = showDialog} |
||||
dataGs={this.state.dataGs} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4>Sales</h4> |
||||
<div> |
||||
<Button color="primary" onClick={() => this.handleOpenDialog('Save')}>Add Sales</Button> |
||||
<Link style={{ marginLeft: 16 }} to="/sales/setting-sales"> |
||||
<Icon width={35} height={35} icon={settingOutlined} /> |
||||
</Link> |
||||
|
||||
</div> |
||||
</CardHeader> |
||||
|
||||
|
||||
|
||||
<CardBody> |
||||
<InputGroup style={{ maxWidth: "200px", marginBottom: "20px" }}> |
||||
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder={`Search ${searchDetail}`} /> |
||||
<InputGroupButtonDropdown addonType="prepend" |
||||
isOpen={splitButtonOpen} |
||||
toggle={this.toggleDropDown} |
||||
> |
||||
<DropdownToggle split outline /> |
||||
<DropdownMenu> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "All", |
||||
searchDetailField: "name" |
||||
})}>All</DropdownItem> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Name", |
||||
searchDetailField: "name" |
||||
})}>Name</DropdownItem> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Group Sales", |
||||
searchDetailField: "name" |
||||
})}>Group Sales</DropdownItem> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Phone Number", |
||||
searchDetailField: "phone_number" |
||||
})}>Phone Number</DropdownItem> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Email", |
||||
searchDetailField: "email" |
||||
})}>Email</DropdownItem> |
||||
<DropdownItem onClick={ |
||||
() => this.setState({ |
||||
searchDetail: "Address", |
||||
searchDetailField: "address" |
||||
})}>Address</DropdownItem> |
||||
</DropdownMenu> |
||||
</InputGroupButtonDropdown> |
||||
</InputGroup> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
<th>Actions</th> |
||||
{column.map((i, index) => { |
||||
return ( |
||||
<th key={index} scope="row">{i.name}</th> |
||||
) |
||||
})} |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{dataTable.map((n) => { |
||||
return ( |
||||
<tr key={n.id}> |
||||
<td> |
||||
{/* delete */} |
||||
<i id="TooltipDelete" className="cil-trash fa-lg" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => this.handleDelete(n.id)}></i> |
||||
<Tooltip placement="right" isOpen={tooltipDelete} target="TooltipDelete" toggle={() => this.toggle("delete")}> |
||||
Delete |
||||
</Tooltip> |
||||
|
||||
{/* edit */} |
||||
<i id="TooltipEdit" className="cil-pencil fa-lg" style={{ color: 'green', cursor: "pointer" }} onClick={() => this.handleEdit(n)}></i> |
||||
<Tooltip placement="right" isOpen={tooltipEdit} target="TooltipEdit" toggle={() => this.toggle("edit")}> |
||||
Edit |
||||
</Tooltip> |
||||
</td> |
||||
<td>{n.join.group_sales_name}</td> |
||||
<td>{n.name}</td> |
||||
<td>{n.phone_number}</td> |
||||
<td>{n.email}</td> |
||||
<td>{n.address}</td> |
||||
</tr> |
||||
) |
||||
})} |
||||
</tbody> |
||||
</Table> |
||||
<Pagination |
||||
showSizeChanger |
||||
onShowSizeChange={this.onShowSizeChange} |
||||
onChange={this.onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={totalPage} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
} |
@ -1,50 +0,0 @@
|
||||
import React, { Component } from 'react' |
||||
import DataTable from '../../../components/DataTable' |
||||
import { API_LIST_DATA_SUBDISTRICT, API_INSERT_DATA_SUBDISTRICT, API_UPDATE_DATA_SUBDISTRICT, API_DELETE_DATA_SUBDISTRICT } from '../../../const/ApiConst.js' |
||||
|
||||
const columns = [{ |
||||
dataField: 'id', |
||||
alias: "Id", |
||||
showInput: false, |
||||
type: "number", |
||||
state: 0 |
||||
}, { |
||||
dataField: 'subdistrict_name', |
||||
alias: "Subdistrict Name", |
||||
showInput: true, |
||||
type: "text", |
||||
state: "" |
||||
}, { |
||||
dataField: 'last_updated', |
||||
alias: "Last Updated", |
||||
showInput: false, |
||||
type: "text", |
||||
state: "" |
||||
}]; |
||||
|
||||
class MasterSubdistrict extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = {} |
||||
} |
||||
|
||||
componentDidMount() {} |
||||
|
||||
render() { |
||||
|
||||
return ( |
||||
<div> |
||||
<DataTable |
||||
title="Subdistrict" |
||||
columns={columns} |
||||
urlParamGet={API_LIST_DATA_SUBDISTRICT} |
||||
urlParamInsert={API_INSERT_DATA_SUBDISTRICT} |
||||
urlParamUpdate={API_UPDATE_DATA_SUBDISTRICT} |
||||
urlParamDelete={API_DELETE_DATA_SUBDISTRICT} |
||||
/> |
||||
</div> |
||||
) |
||||
} |
||||
} |
||||
|
||||
export default MasterSubdistrict; |
@ -1,6 +0,0 @@
|
||||
{ |
||||
"name": "MasterSubdistrict", |
||||
"version": "0.0.0", |
||||
"private": true, |
||||
"main": "./MasterSubdistrict.js" |
||||
} |
@ -1,50 +0,0 @@
|
||||
import React, { Component } from 'react' |
||||
import DataTable from '../../../components/DataTable' |
||||
import { API_LIST_DATA_VILLAGE, API_INSERT_DATA_VILLAGE, API_UPDATE_DATA_VILLAGE, API_DELETE_DATA_VILLAGE } from '../../../const/ApiConst.js' |
||||
|
||||
const columns = [{ |
||||
dataField: 'id', |
||||
alias: "Id", |
||||
showInput: false, |
||||
type: "number", |
||||
state: 0 |
||||
}, { |
||||
dataField: 'village_name', |
||||
alias: "Village Name", |
||||
showInput: true, |
||||
type: "text", |
||||
state: "" |
||||
}, { |
||||
dataField: 'last_updated', |
||||
alias: "Last Updated", |
||||
showInput: false, |
||||
type: "text", |
||||
state: "" |
||||
}]; |
||||
|
||||
class MasterVillage extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = {} |
||||
} |
||||
|
||||
componentDidMount() {} |
||||
|
||||
render() { |
||||
|
||||
return ( |
||||
<div> |
||||
<DataTable |
||||
title="VILLAGE" |
||||
columns={columns} |
||||
urlParamGet={API_LIST_DATA_VILLAGE} |
||||
urlParamInsert={API_INSERT_DATA_VILLAGE} |
||||
urlParamUpdate={API_UPDATE_DATA_VILLAGE} |
||||
urlParamDelete={API_DELETE_DATA_VILLAGE} |
||||
/> |
||||
</div> |
||||
) |
||||
} |
||||
} |
||||
|
||||
export default MasterVillage; |
@ -1,6 +0,0 @@
|
||||
{ |
||||
"name": "MasterVillage", |
||||
"version": "0.0.0", |
||||
"private": true, |
||||
"main": "./MasterVillage.js" |
||||
} |
@ -1,106 +0,0 @@
|
||||
import React, { Component } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import Select from 'react-select' |
||||
import axios from 'axios'; |
||||
import moment from 'moment'; |
||||
import { TimePicker } from 'antd'; |
||||
import 'antd/dist/antd.css'; |
||||
|
||||
export default class DialogForm extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
id: 0, |
||||
lat:"", |
||||
lon:"", |
||||
status:"", |
||||
name:"", |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
disable: false |
||||
} |
||||
} |
||||
|
||||
async componentDidMount(){ |
||||
this.props.showDialog(this.showDialog); |
||||
} |
||||
|
||||
async componentDidUpdate (){ |
||||
if(this.state.isParentClick===true){ |
||||
const { dataEdit } = this.props |
||||
console.log("cek", dataEdit); |
||||
this.setState({
|
||||
id:dataEdit.id, |
||||
lat:dataEdit.lat, |
||||
lon:dataEdit.lon, |
||||
status:dataEdit.status_response, |
||||
name:dataEdit.employee_name |
||||
}) |
||||
|
||||
this.setState({isParentClick:false}); |
||||
} |
||||
} |
||||
|
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick : true }); |
||||
} |
||||
|
||||
|
||||
handleSave = () => { |
||||
const {
|
||||
lat, |
||||
lon, |
||||
status, |
||||
id |
||||
} = this.state |
||||
|
||||
let data = { |
||||
lat, |
||||
lon, |
||||
status_response:status, |
||||
id |
||||
} |
||||
this.props.closeDialog('save', data); |
||||
this.setState({ id:0,lat:"",lon:"",status:'active' }); |
||||
|
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.props.closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
renderForm = () => { |
||||
return( |
||||
<Form> |
||||
<FormGroup> |
||||
<Label>Name</Label> |
||||
<Input type="text" value={this.state.name} readOnly /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>Status Approval</Label> |
||||
<Input type="select" disabled={this.state.disable} value={this.state.status} onChange={(e)=>this.setState({ status:e.target.value })}> |
||||
<option value="active">Active</option> |
||||
<option value="non active">Non Active</option> |
||||
</Input> |
||||
</FormGroup> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.props.closeDialog}>Edit Status Response</ModalHeader> |
||||
<ModalBody> |
||||
{this.renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => this.handleSave()}>Save</Button>{' '} |
||||
<Button color="secondary" onClick={() => this.handleCancel()}>Cancel</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
@ -1,85 +0,0 @@
|
||||
import React, { Component } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Col, Row, Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import Map from './Map' |
||||
import 'antd/dist/antd.css'; |
||||
|
||||
const ERROR_LATLON = "Geom cannot be empty" |
||||
const ERROR_COMPANY = "Company cannot be empty" |
||||
const ERROR_NAME = "name cannot be empty" |
||||
const ERROR_RADIUS = "Buffer Radius cannot be empty" |
||||
|
||||
export default class DialogForm extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
id: 0, |
||||
lat:0, |
||||
lon:0, |
||||
openDialog: false, |
||||
isParentClick: false, |
||||
} |
||||
} |
||||
|
||||
async componentDidMount(){ |
||||
this.props.showDialog(this.showDialog); |
||||
} |
||||
|
||||
async componentDidUpdate (){ |
||||
if(this.state.isParentClick===true){ |
||||
const { dataMap } = this.props |
||||
this.setState({
|
||||
lat:dataMap.lat, |
||||
lon:dataMap.lon |
||||
}) |
||||
this.setState({isParentClick:false}); |
||||
} |
||||
} |
||||
|
||||
|
||||
showDialog = () => { |
||||
this.setState({ isParentClick : true }); |
||||
} |
||||
|
||||
|
||||
handleSave = () => { |
||||
|
||||
} |
||||
|
||||
handleCancel = () => { |
||||
this.props.closeDialog('cancel', 'none') |
||||
} |
||||
|
||||
getLocation = (param) => { |
||||
console.log(`getLocation`, param) |
||||
this.setState({ |
||||
latlonMessage: param != "" ? "" : ERROR_LATLON, |
||||
lat: param.lat, |
||||
lon: param.lng, |
||||
latlon: `lat:${param.lat} lng:${param.lng}` |
||||
}) |
||||
} |
||||
|
||||
renderForm = () => { |
||||
return( |
||||
<div style={{ width: '100%', minHeight: '100px' }}> |
||||
<Map method={'View'} getLocation={this.getLocation} lat={this.state.lat} lng={this.state.lon} /> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
render() { |
||||
return ( |
||||
<Modal isOpen={this.props.openDialog} toggle={this.props.toggleDialog}> |
||||
<ModalHeader toggle={this.props.closeDialog}>Map</ModalHeader> |
||||
<ModalBody> |
||||
{this.renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
{/* <Button color="primary" onClick={() => this.handleSave()}>{this.props.typeDialog}</Button>{' '} */} |
||||
<Button color="secondary" onClick={() => this.handleCancel()}>Close</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
} |
||||
} |
@ -1,104 +0,0 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input, Col, Row } from 'reactstrap'; |
||||
import { Select, Table } from 'antd' |
||||
import { BASE_SIMPRO } from '../../../const/ApiConst'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import 'antd/dist/antd.css'; |
||||
import axios from 'axios'; |
||||
import moment from 'moment'; |
||||
|
||||
const { Option } = Select |
||||
|
||||
const DialogView = ({ openDialog, closeDialog, toggleDialog, dataPlanning, nameProyekParent }) => { |
||||
const token = localStorage.getItem("token") |
||||
const HEADER = { |
||||
headers: { |
||||
"Content-Type": "application/json", |
||||
"Authorization": `Bearer ${token}` |
||||
} |
||||
} |
||||
const [dataPlan, setDataPlan] = useState([]); |
||||
|
||||
useEffect(() => { |
||||
setDataPlan(dataPlanning) |
||||
}, [dataPlanning]); |
||||
|
||||
|
||||
const RenderTableLaporanPlan = (tableData) => { |
||||
const columns = [ |
||||
{ |
||||
title: 'Tanggal', |
||||
dataIndex: 'tanggal', |
||||
key: 'tanggal', |
||||
render: (text, record) => <>{moment(text.tanggal).format("YYYY-MM-DD")}</>, |
||||
}, |
||||
{ title: 'Jumlah Pekerja', dataIndex: 'jumlah_pekerjaan', key: 'jumlah_pekerjaan' }, |
||||
{ title: 'Status', dataIndex: 'status', key: 'status' }, |
||||
{ title: 'deskripsi', dataIndex: 'deskripsi', key: 'deskripsi' }, |
||||
]; |
||||
|
||||
return ( |
||||
<Table |
||||
size="small" |
||||
columns={columns} |
||||
dataSource={tableData} |
||||
/> |
||||
) |
||||
} |
||||
|
||||
const RenderTablePlan = useMemo(() => { |
||||
let idx = 0 |
||||
const columns = [ |
||||
{
|
||||
title: 'No',
|
||||
dataIndex: 'no',
|
||||
key: 'id',
|
||||
render: (text, record) => <>{idx+1}</>, |
||||
}, |
||||
|
||||
{ |
||||
title: 'Waspang', |
||||
dataIndex: 'created_by', |
||||
key: 'created_by', |
||||
render: (text, record) => <>{record.created_by}</>, |
||||
}, |
||||
{ title: 'Jumlah Pekerjaan', dataIndex: 'jumlah_pekerjaan', key: 'jumlah_pekerjaan' }, |
||||
{ |
||||
title: 'Deskripsi', |
||||
dataIndex: 'deskripsi', |
||||
key: 'deskripsi', |
||||
render: (text, record) => <>{record.deskripsi}</>, |
||||
}, |
||||
]; |
||||
|
||||
return ( |
||||
<Table |
||||
size="small" |
||||
columns={columns} |
||||
expandable={{ |
||||
expandedRowRender: record => RenderTableLaporanPlan(record.realisasi), |
||||
rowExpandable: record => record.realisasi, |
||||
}} |
||||
dataSource={dataPlan} |
||||
/> |
||||
) |
||||
}, [dataPlan]) |
||||
|
||||
|
||||
return ( |
||||
<Modal size="xl" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>View Realisasi</ModalHeader> |
||||
<ModalBody> |
||||
{RenderTablePlan} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
{/* <Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} */} |
||||
<Button className="capitalize" color="secondary" onClick={closeDialog}>Close</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogView; |
@ -1,83 +0,0 @@
|
||||
import React, { useState, useRef, useMemo, useCallback, useEffect } from 'react' |
||||
import { MapContainer, TileLayer, Marker, Popup, Polygon } from 'react-leaflet' |
||||
|
||||
const center = { |
||||
lat: -6.200000, |
||||
lng: 106.816666 |
||||
} |
||||
|
||||
const DraggableMarker = (props) => { |
||||
const { method } = props |
||||
let lat = props.lat |
||||
let lng = props.lng |
||||
const currentPos = [lat, lng] |
||||
console.log(`currentPos`, currentPos) |
||||
|
||||
|
||||
|
||||
const [draggable, setDraggable] = useState(true) |
||||
const [position, setPosition] = useState(center) |
||||
|
||||
|
||||
const markerRef = useRef(null) |
||||
const eventHandlers = useMemo( |
||||
() => ({ |
||||
dragend() { |
||||
const marker = markerRef.current |
||||
if (marker != null) { |
||||
setPosition(marker.getLatLng()) |
||||
props.getLocation(marker.getLatLng()) |
||||
} |
||||
}, |
||||
}), |
||||
[], |
||||
) |
||||
return ( |
||||
<> |
||||
|
||||
{method === "View" && ( |
||||
<Marker |
||||
eventHandlers={eventHandlers} |
||||
position={currentPos} |
||||
ref={markerRef}> |
||||
</Marker> |
||||
)} |
||||
|
||||
{method === "Edit" && ( |
||||
<Marker |
||||
draggable={draggable} |
||||
eventHandlers={eventHandlers} |
||||
position={currentPos ? currentPos : position} |
||||
ref={markerRef}> |
||||
</Marker> |
||||
)} |
||||
{method === "Save" && ( |
||||
<Marker |
||||
draggable={draggable} |
||||
eventHandlers={eventHandlers} |
||||
position={position} |
||||
ref={markerRef}> |
||||
</Marker> |
||||
)} |
||||
</> |
||||
) |
||||
} |
||||
|
||||
|
||||
const purpleOptions = { color: 'purple' } |
||||
const RenderMap = (props) => { |
||||
let lat = props.lat |
||||
let lng = props.lng |
||||
const currentPos = (lat !== "" && lng !== "") ? [lat, lng] : center |
||||
return ( |
||||
<MapContainer center={currentPos} zoom={13} scrollWheelZoom={false} style={{ height: '70vh' }}> |
||||
{/* <Polygon pathOptions={purpleOptions} positions={polygon} /> */} |
||||
<TileLayer |
||||
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' |
||||
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" |
||||
/> |
||||
<DraggableMarker {...props} /> |
||||
</MapContainer> |
||||
) |
||||
} |
||||
export default RenderMap; |
@ -1,608 +0,0 @@
|
||||
import React, { Component } from 'react'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input, InputGroup } from 'reactstrap'; |
||||
import { Button } from 'reactstrap'; |
||||
import axios from 'axios'; |
||||
import moment from 'moment'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import DialogForm from './DialogForm'; |
||||
import DialogEdit from './DialogEdit'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Tooltip } from 'antd'; |
||||
import { DatePicker } from 'antd'; |
||||
import * as XLSX from 'xlsx'; |
||||
import { PLANNING_REALISASI_SEARCH, PLANNING_SEARCH } from '../../../const/ApiConst.js'; |
||||
import DialogView from './DialogView'; |
||||
|
||||
|
||||
const { RangePicker } = DatePicker; |
||||
|
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers:
|
||||
{
|
||||
Authorization : `Bearer ${token}`, |
||||
"Content-type" : `application/json` |
||||
} |
||||
}; |
||||
|
||||
const proyek_id = localStorage.getItem('proyek_id'); |
||||
const role_id = localStorage.getItem('role_id'); |
||||
|
||||
const column = [ |
||||
{ name: "No" }, |
||||
{ name: "Proyek" }, |
||||
{ name: "Pekerjaan" }, |
||||
{ name: "Target" }, |
||||
{ name: "Actual" }, |
||||
{ name: "Team Leader" }, |
||||
{ name: "Waspang" }, |
||||
{ name: "Tanggal" }, |
||||
{ name: "Lihat" }, |
||||
] |
||||
|
||||
const LENGTH_DATA = 10 |
||||
|
||||
export default class index extends Component { |
||||
constructor(props) { |
||||
super(props) |
||||
this.state = { |
||||
dataTable: [], |
||||
dataExport: [], |
||||
openDialog: false, |
||||
openDialogEdit:false, |
||||
typeDialog: 'Save', |
||||
dataEdit: null, |
||||
alertDelete: false, |
||||
idDelete: 0, |
||||
dataGs: [], |
||||
dataIdHo: [], |
||||
search: "", |
||||
page: 0, |
||||
rowsPerPage: LENGTH_DATA, |
||||
currentPage: 1, |
||||
totalPage: 0, |
||||
tooltipMap: false, |
||||
tooltipDelete: false, |
||||
typeClock: "All", |
||||
startDate:moment(moment().format("YYYY-M-D")), |
||||
endDate:moment(moment().format("YYYY-M-D")), |
||||
currentDay: 'today', |
||||
dataMap:"", |
||||
tooltipExport:false, |
||||
openDialogPlan: false, |
||||
dataRealisasi: [] |
||||
} |
||||
} |
||||
|
||||
async componentDidMount() { |
||||
this.getDataReportPlanning(); |
||||
} |
||||
|
||||
async componentDidUpdate(prevProps, prevState) { |
||||
const { search,startDate,dataExport } = this.state |
||||
if (search !== prevState.search) this.getDataReportPlanning() |
||||
if (startDate !== prevState.startDate) this.getDataReportPlanning() |
||||
if (dataExport !== prevState.dataExport){ |
||||
if(dataExport.length > 0){ |
||||
this.exportExcel() |
||||
} |
||||
} |
||||
} |
||||
|
||||
handleSearch = e => { |
||||
const value = e.target.value |
||||
this.setState({ search: value, currentPage: 1 }) |
||||
}; |
||||
|
||||
getDataReportPlanning = async () => { |
||||
let start = 0; |
||||
if (this.state.currentPage !== 1 && this.state.currentPage > 1) { |
||||
start = (this.state.currentPage * this.state.rowsPerPage) - this.state.rowsPerPage |
||||
} |
||||
|
||||
let dateStart = moment(this.state.startDate).format("YYYY-MM-DD 00:00:00"); |
||||
let dateEnd = moment(this.state.endDate).format("YYYY-MM-DD 23:59:59"); |
||||
|
||||
|
||||
|
||||
const formData = { |
||||
"columns": [ |
||||
{ |
||||
"name": "created_at", |
||||
"logic_operator": "range", |
||||
"value": dateStart, |
||||
"value1": dateEnd, |
||||
"operator": "AND" |
||||
}, |
||||
{ |
||||
"name": "nama", |
||||
"logic_operator": "ilike", |
||||
"value": this.state.search, |
||||
"operator": "AND", |
||||
} |
||||
], |
||||
"joins": [ |
||||
{ |
||||
"name": "m_proyek", |
||||
"column_join": "proyek_id", |
||||
"column_results": [ |
||||
"nama", |
||||
"biaya", |
||||
"color_progress", |
||||
"jumlah_pekerja", |
||||
"pic", |
||||
"mulai_proyek", |
||||
"akhir_proyek" |
||||
] |
||||
}, |
||||
{ |
||||
"name": "m_subproyek", |
||||
"column_join": "subproyek_id", |
||||
"column_results": [ |
||||
"nama", |
||||
"biaya", |
||||
"color_progress", |
||||
"jumlah_pekerja", |
||||
"pic", |
||||
"mulai_proyek", |
||||
"akhir_proyek" |
||||
] |
||||
}, |
||||
{ |
||||
"name": "m_users", |
||||
"column_join": "user_id", |
||||
"column_results": [ |
||||
"name", |
||||
"username", |
||||
"email", |
||||
"phone_number", |
||||
"gender" |
||||
] |
||||
} |
||||
], |
||||
"orders": { |
||||
"columns": [ |
||||
"planning_id" |
||||
], |
||||
"ascending": true |
||||
}, |
||||
"paging": { |
||||
"start": start, |
||||
"length": this.state.rowsPerPage |
||||
} |
||||
} |
||||
|
||||
if(parseInt(role_id)!==1){ |
||||
formData.columns.push( |
||||
{ |
||||
"name": "id", |
||||
"logic_operator": "=", |
||||
"value": proyek_id, |
||||
"operator": "AND", |
||||
"table_name": "m_proyek" |
||||
} |
||||
) |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(PLANNING_REALISASI_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code==200){ |
||||
console.log("cek res planning", result.data.data) |
||||
this.setState({ dataTable: result.data.data, totalPage: result.data.totalRecord }); |
||||
}else{ |
||||
NotificationManager.error('Gagal Menerima Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
handleCloseDialogPlan = () => { |
||||
this.setState({openDialogPlan: false}) |
||||
} |
||||
|
||||
handleOpenDialogPlan = (param) => { |
||||
this.setState({openDialogPlan: true}) |
||||
this.setState({dataRealisasi: param.realisasi}) |
||||
} |
||||
|
||||
|
||||
toggleAddDialogPlan = () => { |
||||
this.setState({openDialogPlan: !this.stateopenDialogPlan}) |
||||
} |
||||
|
||||
|
||||
handleOpenDialog = (type) => { |
||||
if(type==="Map"){ |
||||
this.setState({ openDialog: true }) |
||||
this.showChildDialog(); |
||||
}else{ |
||||
this.setState({ openDialogEdit: true }) |
||||
this.showDialogEdit(); |
||||
} |
||||
|
||||
} |
||||
|
||||
handleCloseDialog = () => { |
||||
this.setState({ openDialog: false }) |
||||
} |
||||
|
||||
handleCloseDialogEdit = (type, data) => { |
||||
if(type==="save"){ |
||||
this.updateStatusResponse(data); |
||||
} |
||||
this.setState({ openDialogEdit: false }) |
||||
} |
||||
|
||||
toggleMapDialog = () => { |
||||
this.setState({ openDialog: !this.state.openDialog }) |
||||
} |
||||
|
||||
toggleEditDialog = () => { |
||||
this.setState({ openDialogEdit:!this.state.openDialogEdit }); |
||||
} |
||||
|
||||
handleMap = data => { |
||||
this.setState({ dataMap: data }); |
||||
this.handleOpenDialog('Map'); |
||||
} |
||||
|
||||
handleEdit = data => { |
||||
this.setState({ dataEdit:data }); |
||||
this.handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
handleDelete = (id) => { |
||||
this.setState({ alertDelete: true, idDelete: id }); |
||||
} |
||||
|
||||
onShowSizeChange = (current, pageSize) => { |
||||
this.setState({ rowsPerPage: pageSize }, () => { |
||||
this.getDataReportPlanning(); |
||||
}) |
||||
} |
||||
|
||||
onPagination = (current, pageSize) => { |
||||
this.setState({ currentPage: current, page: (current - 1) * pageSize }, () => { |
||||
this.getDataReportPlanning(); |
||||
}) |
||||
} |
||||
|
||||
toggle = (param) => { |
||||
if (param === "map") { |
||||
this.setState(prevState => ({ tooltipMap: !prevState.tooltipMap })) |
||||
}else if(param==="edit"){ |
||||
this.setState(prevState => ({ tooltipEdit: !prevState.tooltipEdit })) |
||||
} else if (param === "delete") { |
||||
this.setState(prevState => ({ tooltipDelete: !prevState.tooltipDelete })) |
||||
} else if (param === "export") { |
||||
this.setState(prevState => ({ tooltipExport: !prevState.tooltipExport })) |
||||
} |
||||
} |
||||
|
||||
handleDatePicker = (date, dateString) => { |
||||
this.setState({ startDate:date[0],endDate:date[1] },()=>{ |
||||
this.getDataReportPlanning(); |
||||
}) |
||||
} |
||||
|
||||
handleTipe = (e) => { |
||||
this.setState({ typeClock:e.target.value }, () => { |
||||
this.getDataReportPlanning(); |
||||
}); |
||||
} |
||||
|
||||
handleExportExcel = async () => { |
||||
let dateStart = moment(this.state.startDate).format("YYYY-MM-DD 00:00:00"); |
||||
let dateEnd = moment(this.state.endDate).format("YYYY-MM-DD 23:59:59"); |
||||
|
||||
const payload = { |
||||
"columns": [ |
||||
{ |
||||
"name": "created_at", |
||||
"logic_operator": "range", |
||||
"value": dateStart, |
||||
"value1": dateEnd, |
||||
"operator": "AND" |
||||
}, |
||||
{ |
||||
"name": "nama", |
||||
"logic_operator": "ilike", |
||||
"value": this.state.search, |
||||
"operator": "AND", |
||||
} |
||||
], |
||||
"joins": [ |
||||
{ |
||||
"name": "m_proyek", |
||||
"column_join": "proyek_id", |
||||
"column_results": [ |
||||
"nama", |
||||
"biaya", |
||||
"color_progress", |
||||
"jumlah_pekerja", |
||||
"pic", |
||||
"mulai_proyek", |
||||
"akhir_proyek" |
||||
] |
||||
}, |
||||
{ |
||||
"name": "m_subproyek", |
||||
"column_join": "subproyek_id", |
||||
"column_results": [ |
||||
"nama", |
||||
"biaya", |
||||
"color_progress", |
||||
"jumlah_pekerja", |
||||
"pic", |
||||
"mulai_proyek", |
||||
"akhir_proyek" |
||||
] |
||||
}, |
||||
{ |
||||
"name": "m_users", |
||||
"column_join": "user_id", |
||||
"column_results": [ |
||||
"name", |
||||
"username", |
||||
"email", |
||||
"phone_number", |
||||
"gender" |
||||
] |
||||
} |
||||
], |
||||
"orders": { |
||||
"columns": [ |
||||
"planning_id" |
||||
], |
||||
"ascending": true |
||||
}, |
||||
"paging": { |
||||
"start": 0, |
||||
"length": -1 |
||||
} |
||||
} |
||||
|
||||
if(parseInt(role_id)!==1){ |
||||
payload.columns.push( |
||||
{ |
||||
"name": "id", |
||||
"logic_operator": "=", |
||||
"value": proyek_id, |
||||
"operator": "AND", |
||||
"table_name": "m_proyek" |
||||
} |
||||
) |
||||
} |
||||
|
||||
const result = await axios |
||||
.post(PLANNING_REALISASI_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
|
||||
if(result && result.data && result.data.code == 200){ |
||||
let resData = result.data.data; |
||||
const excelData = []; |
||||
resData.map((n, index) => { |
||||
let dataRow = { |
||||
"Proyek": n.join ? n.join.m_proyek_nama : "-", |
||||
"Pekerjaan": n.nama ? n.nama : "-", |
||||
"Target" : n.jumlah_titik ? n.jumlah_titik : "0", |
||||
"Actual" : n.realisasi ? this.renderActual(n.realisasi) : "0", |
||||
"Team Leader" : n.join.m_subproyek_pic ? `${n.join.m_subproyek_pic}` : "-", |
||||
"Waspang" : n.join.m_users_name ? `${n.join.m_users_name}` : "-", |
||||
"Tanggal" : n.target_planning ? moment(n.target_planning).format("DD-MM-YYYY") : "-", |
||||
} |
||||
excelData.push(dataRow) |
||||
}) |
||||
this.setState({dataExport:excelData}) |
||||
}else{ |
||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||
}
|
||||
} |
||||
|
||||
exportExcel = () => { |
||||
const dataExcel = this.state.dataExport || []; |
||||
const fileName = `Data Planning vs realisasi.xlsx`; |
||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, `Data Planning vs realisasi`); |
||||
|
||||
XLSX.writeFile(wb, fileName); |
||||
this.setState({dataExport:[] }) |
||||
} |
||||
|
||||
updateStatusResponse = async (data) => { |
||||
let url = ``; |
||||
|
||||
const formData = new FormData(); |
||||
formData.append("lat", data.lat); |
||||
formData.append("lon", data.lon); |
||||
formData.append("status_response", data.status_response); |
||||
|
||||
const result = await axios |
||||
.post(url, formData) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
if(result && result.data){ |
||||
if (result.data.code_status == 200) { |
||||
NotificationManager.success('Berhasil update status response!!', 'Success!'); |
||||
} else { |
||||
NotificationManager.error('Gagal update status response!!', 'Failed'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
renderActual = (realisasi) => { |
||||
let data = realisasi || [] |
||||
let sumActual = 0 |
||||
data.map((val, index) => { |
||||
sumActual += parseInt(val.jumlah_pekerjaan) |
||||
}) |
||||
return sumActual |
||||
} |
||||
|
||||
renderTable = () => { |
||||
const dataTable2 = this.state.dataTable || []; |
||||
return ( |
||||
<tbody> |
||||
{dataTable2.length!==0 ? dataTable2.map((n, index) => { |
||||
return ( |
||||
<tr key={index}> |
||||
<td>{index + 1}</td> |
||||
<td>{ n.join ? n.join.m_proyek_nama : "-" }</td> |
||||
<td>{ n.nama ? n.nama : "-"}</td> |
||||
<td>{ n.jumlah_titik ? n.jumlah_titik : "0" }</td> |
||||
<td>{ n.realisasi ? this.renderActual(n.realisasi) : "0" }</td> |
||||
<td>{ n.join.m_subproyek_pic ? `${n.join.m_subproyek_pic}` : "-" }</td> |
||||
<td>{ n.join.m_users_name ? `${n.join.m_users_name}` : "-" }</td> |
||||
<td>{ n.target_planning ? moment(n.target_planning).format("DD-MM-YYYY") : "-" }</td> |
||||
<td> |
||||
{/* <i id="TooltipDelete" className="cil-trash fa-lg" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => this.handleDelete(n.id)}></i> |
||||
<Tooltip placement="right" isOpen={this.state.tooltipDelete} target="TooltipDelete" toggle={() => this.toggle("delete")}> |
||||
Delete |
||||
</Tooltip>*/} |
||||
{/* <i id="TooltipEdit" className="cil-pencil fa-lg" style={{ color: 'green', cursor: "pointer" }} onClick={() => this.handleEdit(n)}></i> |
||||
<Tooltip placement="right" isOpen={this.state.tooltipEdit} target="TooltipEdit" toggle={() => this.toggle("edit")}> |
||||
Edit |
||||
</Tooltip> |
||||
{' '} */} |
||||
<Tooltip title="View Realisasi"> |
||||
<i onClick={() => this.handleOpenDialogPlan(n)} id="tooltipMap" className="fa fa-eye fa-lg" style={{ color: 'black', cursor: "pointer" }}></i> |
||||
</Tooltip> |
||||
</td> |
||||
</tr> |
||||
) |
||||
}) : <tr> |
||||
<td colSpan="9" align="center">No Data Available</td> |
||||
</tr> |
||||
}
|
||||
</tbody> |
||||
) |
||||
} |
||||
|
||||
handleChangeDay = (e) => { |
||||
const val = e.target.value; |
||||
this.setState({ currentDay:val }); |
||||
if(val==="today"){ |
||||
this.setState({ |
||||
startDate:moment(moment().format("YYYY-M-D")), |
||||
endDate:moment(moment().format("YYYY-M-D")),
|
||||
currentPage: 1 |
||||
}) |
||||
}else if(val==="3 day"){ |
||||
this.setState({ |
||||
startDate:moment(moment().subtract(3, "days").format("YYYY-M-D")), |
||||
endDate:moment(moment().format("YYYY-M-D")),
|
||||
currentPage: 1 |
||||
}) |
||||
}else if(val==="7 day"){ |
||||
this.setState({ |
||||
startDate:moment(moment().subtract(7, "days").format("YYYY-M-D")), |
||||
endDate:moment(moment().format("YYYY-M-D")),
|
||||
currentPage: 1 |
||||
}) |
||||
}else{ |
||||
this.setState({ |
||||
startDate:moment(moment().format("YYYY-M-D")), |
||||
endDate:moment(moment().format("YYYY-M-D")),
|
||||
currentPage: 1 |
||||
}) |
||||
} |
||||
} |
||||
|
||||
render() { |
||||
const { tooltipExport,dataTable, openDialogEdit, openDialog, currentPage, rowsPerPage, totalPage, search, tooltipMap, tooltipDelete } = this.state |
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
{/* <SweetAlert |
||||
show={this.state.alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title="Are you sure?" |
||||
onConfirm={this.onConfirmDelete} |
||||
onCancel={() => this.setState({ alertDelete: false, idDelete: 0 })} |
||||
focusCancelBtn |
||||
> |
||||
Data tipe karyawan akan terhapus!! |
||||
</SweetAlert> */} |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={this.handleCloseDialog} |
||||
toggleDialog={() => this.toggleMapDialog} |
||||
dataMap={this.state.dataMap} |
||||
showDialog={showDialog => this.showChildDialog = showDialog} |
||||
/> |
||||
<DialogEdit |
||||
openDialog={openDialogEdit} |
||||
closeDialog={this.handleCloseDialogEdit} |
||||
toggleDialog={() => this.toggleEditDialog} |
||||
dataEdit={this.state.dataEdit} |
||||
showDialog={showDialog => this.showDialogEdit = showDialog} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4>Planning Vs Realisasi</h4> |
||||
<div> |
||||
{/* <Button color="primary" onClick={() => this.handleOpenDialog('Save')}>Tambah Broadcast</Button>{' '} */} |
||||
<Tooltip title="Export Excel"> |
||||
<Button id="TooltipExport" color="primary" onClick={()=> this.handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</div> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<div style={{ display: "flex", justifyContent: "space-between", marginBottom:"25px" }}> |
||||
<div style={{ width:"100%",display:"inline-flex",alignItems:"center" }}> |
||||
<div style={{ width:"50%",marginRight:"10px",maxWidth:"200px" }}> |
||||
<Input type="select" onChange={(e) => this.handleChangeDay(e)} defaultValue={this.state.currentDay}> |
||||
<option value="today">Hari Ini</option> |
||||
<option value="3 day">3 Hari yang lalu</option> |
||||
<option value="7 day">7 Hari yang lalu</option> |
||||
</Input> |
||||
</div> |
||||
<div style={{ width:"50%" }}> |
||||
<RangePicker size="default" allowClear={false} value={[this.state.startDate, this.state.endDate]} onChange={this.handleDatePicker}/>{' '} |
||||
<Button color="primary" onClick={() => this.getDataReportPlanning()}>Cari</Button> |
||||
</div> |
||||
</div> |
||||
<Input onChange={this.handleSearch} value={search} type="text" name="search" id="search" placeholder="Cari Nama Pekerjaan" style={{ maxWidth: "200px", marginBottom: "20px" }} /> |
||||
</div> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
{/* <th>Actions</th> */} |
||||
{column.map((i, index) => { |
||||
return ( |
||||
<th key={index} scope="row">{i.name}</th> |
||||
) |
||||
})} |
||||
</tr> |
||||
</thead> |
||||
{ this.renderTable() } |
||||
</Table> |
||||
<Pagination |
||||
showSizeChanger |
||||
onShowSizeChange={this.onShowSizeChange} |
||||
onChange={this.onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={parseInt(totalPage)} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
|
||||
<DialogView |
||||
openDialog={this.state.openDialogPlan} |
||||
closeDialog={() => this.handleCloseDialogPlan()} |
||||
toggleDialog={() => this.toggleAddDialogPlan()} |
||||
dataPlanning={this.state.dataRealisasi} |
||||
/> |
||||
</div> |
||||
) |
||||
} |
||||
} |
@ -1,211 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter,Row,Col } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import { DatePicker,Select } from 'antd'; |
||||
import moment from 'moment'; |
||||
import 'antd/dist/antd.css'; |
||||
|
||||
const { Option } = Select |
||||
const DialogForm = ({openDialog, closeDialog, toggleDialog, typeDialog, dataEdit, dataRole}) => { |
||||
const [id, setId] = useState(0) |
||||
const [user_id, setUserId] = useState(0) |
||||
const [name, setName] = useState('') |
||||
const [username, setUsername] = useState('') |
||||
const [birth_place, setBirthPlace] = useState('') |
||||
const [birth_date, setBirthDate] = useState(moment(moment().format('YYYY-MM-DD'))) |
||||
const [email, setEmail] = useState('') |
||||
const [phone_number, setPhoneNumber] = useState('') |
||||
const [address, setAddress] = useState('') |
||||
const [gender, setGender] = useState('Laki-laki') |
||||
const [password, setPassword] = useState('') |
||||
const [role_id,setIdRole] = useState(null) |
||||
useEffect(()=> { |
||||
if(typeDialog==="Edit"){ |
||||
if(dataEdit){ |
||||
setId(dataEdit.id) |
||||
setIdRole(3) |
||||
setUserId(dataEdit.user_id) |
||||
if(dataEdit.join){ |
||||
setName(dataEdit.join.m_users_name) |
||||
setEmail(dataEdit.join.m_users_email) |
||||
setBirthDate(dataEdit.join.m_users_birth_date ? moment(moment(dataEdit.join.m_users_birth_date).format("YYYY-MM-DD")) : moment(moment())) |
||||
setBirthPlace(dataEdit.join.m_users_birth_place) |
||||
setPhoneNumber(dataEdit.join.m_users_phone_number) |
||||
setGender(dataEdit.join.m_users_gender || "Laki-laki") |
||||
setAddress(dataEdit.join.m_users_address) |
||||
setUsername(dataEdit.join.m_users_username) |
||||
} |
||||
} |
||||
}else{ |
||||
setId(0) |
||||
setName('') |
||||
setEmail('') |
||||
setBirthDate(moment(moment().format('YYYY-MM-DD'))) |
||||
setBirthPlace('') |
||||
setPhoneNumber('') |
||||
setGender('Laki-laki') |
||||
setAddress('') |
||||
setUsername('') |
||||
setPassword('') |
||||
setIdRole(3) |
||||
setUserId(0) |
||||
} |
||||
},[dataEdit,openDialog]) |
||||
|
||||
const handleSave = () => { |
||||
let data = ''; |
||||
if(typeDialog==="Save"){ |
||||
data = { |
||||
name, |
||||
username, |
||||
phone_number, |
||||
email, |
||||
birth_date, |
||||
birth_place, |
||||
gender, |
||||
address, |
||||
password, |
||||
role_id, |
||||
user_id |
||||
} |
||||
closeDialog('save', data); |
||||
}else{ |
||||
data = { |
||||
id, |
||||
name, |
||||
username, |
||||
phone_number, |
||||
email, |
||||
birth_date, |
||||
birth_place, |
||||
gender, |
||||
address, |
||||
role_id, |
||||
user_id |
||||
} |
||||
|
||||
if(password!==''){ |
||||
data['password'] = password |
||||
} |
||||
|
||||
closeDialog('edit', data); |
||||
} |
||||
setId(0) |
||||
setName('') |
||||
setEmail('') |
||||
setBirthDate(moment(moment().format('YYYY-MM-DD'))) |
||||
setBirthPlace('') |
||||
setPhoneNumber('') |
||||
setGender('Laki-laki') |
||||
setAddress('') |
||||
setUsername('') |
||||
setPassword('') |
||||
setIdRole(3) |
||||
setUserId(0) |
||||
} |
||||
|
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
setName('') |
||||
setEmail('') |
||||
setBirthDate(moment(moment().format('YYYY-MM-DD'))) |
||||
setBirthPlace('') |
||||
setPhoneNumber('') |
||||
setGender('Laki-laki') |
||||
setAddress('') |
||||
setUsername('') |
||||
setPassword('') |
||||
setIdRole(null) |
||||
setUserId(0) |
||||
} |
||||
|
||||
const handleDatePicker = (date, dateString) => { |
||||
setBirthDate(date) |
||||
} |
||||
|
||||
const setupOption = () => { |
||||
return( |
||||
<> |
||||
{dataRole.map((val, index)=> { |
||||
return( |
||||
<Option key={index} value={val.id}>{val.name}</Option> |
||||
) |
||||
})} |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const onChangeRole = (val) => { |
||||
setIdRole(val) |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return( |
||||
<Form> |
||||
<Row> |
||||
<Col> |
||||
<FormGroup> |
||||
<Label className="capitalize">Nama</Label> |
||||
<Input type="text" value={name} onChange={(e)=> setName(e.target.value)} placeholder={`Nama..`}/> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>Tempat Lahir</Label> |
||||
<Input type="text" value={birth_place} onChange={(e)=> setBirthPlace(e.target.value) } placeholder={`Tempat lahir..`} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>Tanggal Lahir</Label> |
||||
<DatePicker style={{width:"100%"}} value={birth_date} onChange={handleDatePicker} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Jenis Kelamin</Label> |
||||
<Input type="select" value={gender} onChange={(e)=> setGender(e.target.value)} placeholder={`Jenis Kelamin..`}> |
||||
<option value="Laki-laki">Laki-laki</option> |
||||
<option value="Perempuan">Perempuan</option> |
||||
</Input> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Alamat</Label> |
||||
<Input type="textarea" value={address} onChange={(e)=> setAddress(e.target.value)} placeholder={`Alamat..`} /> |
||||
</FormGroup> |
||||
</Col> |
||||
<Col> |
||||
<FormGroup> |
||||
<Label>Username</Label> |
||||
<Input type="text" value={username} onChange={(e)=> setUsername(e.target.value)} placeholder="username.." /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>Email</Label> |
||||
<Input type="text" value={email} onChange={(e)=> setEmail(e.target.value)} placeholder="email.." /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>Nomor Hp</Label> |
||||
<Input type="text" value={phone_number} onChange={(e)=> setPhoneNumber(e.target.value)} placeholder={`Nomor Hp..`} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label>Password</Label> |
||||
<Input type="password" value={password} onChange={(e)=> setPassword(e.target.value)} placeholder="password.." /> |
||||
</FormGroup> |
||||
</Col> |
||||
</Row> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<Modal size="lg" isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={closeDialog}>{typeDialog=="Save" ? `Tambah` : "Edit"} User Waspang</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>{typeDialog}</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogForm; |
@ -1,156 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react' |
||||
import { Modal, ModalHeader, ModalBody, ModalFooter, Row, Col } from 'reactstrap'; |
||||
import { Button, Form, FormGroup, Label, Input } from 'reactstrap'; |
||||
import { Select, DatePicker } from 'antd'; |
||||
import moment from 'moment'; |
||||
import 'antd/dist/antd.css'; |
||||
const proyekId = localStorage.getItem('proyek_id'); |
||||
const { Option } = Select; |
||||
const DialogProyek = ({ openDialog, closeDialog, toggleDialog, dataWaspangProyek, dataProyek, waspangId }) => { |
||||
const [id, setId] = useState(0) |
||||
const [proyek_id, setProyekId] = useState(null) |
||||
const [user_id, setUserId] = useState(null) |
||||
const [userIdAdd, setUserIdAdd] = useState(0) |
||||
const [startDate, setStartDate] = useState(moment(moment())) |
||||
const [endDate, setEndDate] = useState(moment(moment())) |
||||
const [type, setType] = useState("add") |
||||
const [disableSelectProyek, setDisableSelectProyek] = useState(false) |
||||
const [role_id, setRoleId] = useState(localStorage.getItem('role_id')) |
||||
|
||||
useEffect(() => { |
||||
if (waspangId) { |
||||
setUserIdAdd(waspangId) |
||||
} |
||||
}, [waspangId]) |
||||
|
||||
useEffect(() => { |
||||
let data = dataWaspangProyek || [] |
||||
console.log("waspang id", waspangId) |
||||
console.log("role_id", role_id) |
||||
if (data.length > 0) { |
||||
let dataObj = data[0] |
||||
setType("edit") |
||||
setProyekId(dataObj.proyek_id) |
||||
if (dataObj.mulai) { |
||||
setStartDate(moment(moment(dataObj.mulai))) |
||||
} else { |
||||
setStartDate(moment(moment())) |
||||
} |
||||
|
||||
if (dataObj.mulai) { |
||||
setEndDate(moment(moment(dataObj.akhir))) |
||||
} else { |
||||
setEndDate(moment(moment())) |
||||
} |
||||
|
||||
|
||||
setUserId(dataObj.user_id) |
||||
setId(dataObj.id) |
||||
} else { |
||||
setProyekId(null) |
||||
setStartDate(moment(moment())) |
||||
setEndDate(moment(moment())) |
||||
setType("add") |
||||
} |
||||
|
||||
if (parseInt(role_id) === 2) { |
||||
setProyekId(parseInt(proyekId)) |
||||
setDisableSelectProyek(true) |
||||
} |
||||
}, [dataWaspangProyek, openDialog]) |
||||
|
||||
useEffect(() => { |
||||
if (parseInt(role_id) === 2) { |
||||
setProyekId(parseInt(proyekId)) |
||||
setDisableSelectProyek(true) |
||||
} |
||||
}, [role_id]) |
||||
const handleCancel = () => { |
||||
closeDialog('cancel', 'none') |
||||
setId(0) |
||||
setProyekId(null) |
||||
} |
||||
|
||||
const onChangeParent = (value) => { |
||||
setProyekId(value) |
||||
} |
||||
|
||||
const setupOption = () => { |
||||
return ( |
||||
<> |
||||
{dataProyek.map((val, index) => { |
||||
return ( |
||||
<Option key={index} value={val.id}>{val.nama}</Option> |
||||
) |
||||
})} |
||||
</> |
||||
) |
||||
} |
||||
|
||||
const handleStartDate = (date, string) => { |
||||
setStartDate(date) |
||||
} |
||||
|
||||
const handleEndDate = (date, string) => { |
||||
setEndDate(date) |
||||
} |
||||
|
||||
const handleSave = () => { |
||||
let data = { |
||||
type, |
||||
mulai: startDate, |
||||
akhir: endDate, |
||||
proyek_id, |
||||
user_id |
||||
} |
||||
|
||||
if (type === "add") { |
||||
data['user_id'] = userIdAdd |
||||
} |
||||
|
||||
if (type === "edit") { |
||||
data['id'] = id |
||||
} |
||||
|
||||
closeDialog("save", data) |
||||
} |
||||
|
||||
const renderForm = () => { |
||||
return ( |
||||
<Form> |
||||
<FormGroup> |
||||
<Label className="capitalize">Proyek</Label> |
||||
{/* <Input type="text" value={alias} onChange={(e)=> setAlias(e.target.value)} placeholder={`Icon..`} /> */} |
||||
<Select showSearch value={proyek_id} onChange={onChangeParent} placeholder="Select Proyek .." style={{ width: '100%' }} disabled={disableSelectProyek}> |
||||
{setupOption()} |
||||
</Select> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Tanggal Mulai</Label> |
||||
<DatePicker style={{ width: "100%" }} value={startDate} onChange={handleStartDate} allowClear={false} /> |
||||
</FormGroup> |
||||
<FormGroup> |
||||
<Label className="capitalize">Tanggal</Label> |
||||
<DatePicker style={{ width: "100%" }} value={endDate} onChange={handleEndDate} allowClear={false} /> |
||||
</FormGroup> |
||||
</Form> |
||||
) |
||||
} |
||||
|
||||
|
||||
return ( |
||||
<Modal isOpen={openDialog} toggle={toggleDialog}> |
||||
<ModalHeader className="capitalize" toggle={() => closeDialog("none", "none")}>Save User Proyek</ModalHeader> |
||||
<ModalBody> |
||||
{renderForm()} |
||||
</ModalBody> |
||||
<ModalFooter> |
||||
<Button color="primary" onClick={() => handleSave()}>Save</Button>{' '} |
||||
<Button className="capitalize" color="secondary" onClick={() => handleCancel()}>Batal</Button> |
||||
</ModalFooter> |
||||
</Modal> |
||||
) |
||||
|
||||
} |
||||
|
||||
export default DialogProyek; |
@ -1,686 +0,0 @@
|
||||
import React, { useState, useEffect } from 'react'; |
||||
import { Card, CardBody, CardHeader, Col, Row, Table, Input } from 'reactstrap'; |
||||
import { Button } from 'reactstrap'; |
||||
import axios from 'axios'; |
||||
import * as XLSX from 'xlsx'; |
||||
import SweetAlert from 'react-bootstrap-sweetalert'; |
||||
import DialogForm from './DialogForm'; |
||||
import { NotificationContainer, NotificationManager } from 'react-notifications'; |
||||
import { Pagination, Tooltip } from 'antd'; |
||||
import {
|
||||
USER_ADD, |
||||
USER_SEARCH, |
||||
USER_EDIT, |
||||
USER_DELETE,
|
||||
ROLE_SEARCH, |
||||
USERROLE_ADD, |
||||
USERROLE_EDIT, |
||||
USERROLE_DELETE, |
||||
USERROLE_SEARCH, |
||||
USERPROYEK_SEARCH, |
||||
PROYEK_SEARCH, |
||||
USERPROYEK_EDIT, |
||||
USERPROYEK_ADD |
||||
} from '../../../const/ApiConst.js';import moment from 'moment'; |
||||
import DialogProyek from './DialogProyek'; |
||||
const token = window.localStorage.getItem('token'); |
||||
const config = { |
||||
headers:
|
||||
{
|
||||
Authorization : `Bearer ${token}`, |
||||
"Content-type" : `application/json` |
||||
} |
||||
}; |
||||
const column =
|
||||
[ |
||||
{ name: "Nama" }, |
||||
{ name: "Tempat Lahir" }, |
||||
{ name: "Tanggal Lahir" }, |
||||
{ name: "Nomor Telepon" }, |
||||
{ name: "Email" }, |
||||
{ name: "Proyek"} |
||||
] |
||||
|
||||
|
||||
const IndexUser = ({params}) => { |
||||
const [dataTable, setDatatable] = useState([]) |
||||
const [search, setSearch] = useState('') |
||||
const [currentPage, setCurrentPage] = useState(1) |
||||
const [totalPage, setTotalPage] = useState(0) |
||||
const [openDialog, setOpenDialog] = useState(false) |
||||
const [typeDialog, setTypeDialog] = useState('Save') |
||||
const [idDelete, setIdDelete] = useState(0) |
||||
const [dataProyek, setDataProyek] = useState([]) |
||||
const [alertDelete, setAlertDelete] = useState(false) |
||||
const [dataEdit, setDataEdit] = useState([]) |
||||
const [rowsPerPage, setRowsPerPage] = useState(10) |
||||
const [clickOpenModal, setClickOpenModal] = useState(false) |
||||
const [allDataUserProyek, setAllDataUserProyek] = useState([]) |
||||
const [dataRole, setDataRole] = useState([]) |
||||
const [dataExport, setDataExport] = useState([]) |
||||
const [openDialogProyek, setOpenDialogProyek] = useState(false) |
||||
const [dataWaspangProyek, setDataWaspangProyek] = useState([]) |
||||
const [waspangId, setWaspangId] = useState([]) |
||||
const pageName = params.name; |
||||
useEffect(()=> { |
||||
getAllDataRole(); |
||||
getAllDataProyek(); |
||||
getAllDataUserProyek(); |
||||
},[]) |
||||
|
||||
useEffect(()=> { |
||||
getDataUser(); |
||||
},[search,rowsPerPage,currentPage]) |
||||
|
||||
useEffect(()=> { |
||||
const cekData = dataExport || [] |
||||
if(cekData.length > 0){ |
||||
exportExcel() |
||||
} |
||||
},[dataExport]) |
||||
|
||||
const handleSearch = e => { |
||||
const value = e.target.value |
||||
setSearch(value); |
||||
setCurrentPage(1) |
||||
}; |
||||
|
||||
const getAllDataRole = async () => { |
||||
|
||||
const payload = { |
||||
"paging": {"start": 0, "length": -1}, |
||||
"columns": [ |
||||
{"name": "name", "logic_operator": "ilike", "value": "", "operator": "AND"} |
||||
], |
||||
"joins": [], |
||||
"orders": {"columns": ["id"], "ascending": false} |
||||
} |
||||
|
||||
|
||||
|
||||
const result = await axios |
||||
.post(ROLE_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
|
||||
if(result && result.data && result.data.code == 200){ |
||||
setDataRole(result.data.data); |
||||
}else{ |
||||
} |
||||
} |
||||
|
||||
const getAllDataProyek = async () => { |
||||
|
||||
const payload = { |
||||
"paging": {"start": 0, "length": -1}, |
||||
"columns": [ |
||||
{"name": "nama", "logic_operator": "ilike", "value": "", "operator": "AND"} |
||||
], |
||||
"joins": [], |
||||
"orders": {"columns": ["id"], "ascending": false} |
||||
} |
||||
|
||||
|
||||
|
||||
const result = await axios |
||||
.post(PROYEK_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code == 200){ |
||||
setDataProyek(result.data.data); |
||||
}else{ |
||||
|
||||
} |
||||
} |
||||
|
||||
const getAllDataUserProyek = async () => { |
||||
const formData = { |
||||
"paging": {"start": 0, "length": -1}, |
||||
"columns": [ |
||||
], |
||||
"joins": [ |
||||
{ |
||||
"name":"m_proyek", |
||||
"column_join":"proyek_id", |
||||
"column_results":[ |
||||
"nama", |
||||
] |
||||
} |
||||
], |
||||
"orders": {"columns": ["id"], "ascending": false} |
||||
} |
||||
const result = await axios.post(USERPROYEK_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code===200){ |
||||
setAllDataUserProyek(result.data.data) |
||||
}else{ |
||||
|
||||
} |
||||
} |
||||
|
||||
const getDataUser = async () => { |
||||
|
||||
let start = 0; |
||||
|
||||
if (currentPage !== 1 && currentPage > 1) { |
||||
start = (currentPage * rowsPerPage) - rowsPerPage |
||||
} |
||||
|
||||
const payload = { |
||||
"paging":{ |
||||
"start":start, |
||||
"length":rowsPerPage |
||||
}, |
||||
"filter_columns":[ |
||||
{ |
||||
"name":"name", |
||||
"value":"", |
||||
"table_name":"m_users" |
||||
} |
||||
], |
||||
"columns":[ |
||||
{ |
||||
"name":"name", |
||||
"logic_operator":"like", |
||||
"value":search, |
||||
"operator":"AND", |
||||
"table_name":"m_users" |
||||
}, |
||||
{ |
||||
"name":"id", |
||||
"logic_operator":"=", |
||||
"value":'3', |
||||
"operator":"AND", |
||||
"table_name":"m_roles" |
||||
} |
||||
], |
||||
"joins":[ |
||||
{ |
||||
"name":"m_users", |
||||
"column_join":"user_id", |
||||
"column_results":[ |
||||
"username", |
||||
"name", |
||||
"email", |
||||
"gender", |
||||
"phone_number", |
||||
"address", |
||||
"birth_place", |
||||
"birth_date" |
||||
] |
||||
}, |
||||
{ |
||||
"name":"m_roles", |
||||
"column_join":"role_id", |
||||
"column_results":[ |
||||
"name" |
||||
] |
||||
} |
||||
], |
||||
"orders":{ |
||||
"columns":[ |
||||
"id" |
||||
], |
||||
"ascending":false |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
const result = await axios |
||||
.post(USERROLE_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
|
||||
|
||||
if(result && result.data && result.data.code == 200){ |
||||
setDatatable(result.data.data); |
||||
setTotalPage(result.data.totalRecord); |
||||
}else{ |
||||
NotificationManager.error('Gagal Mengambil Data!!', 'Failed'); |
||||
} |
||||
} |
||||
|
||||
const handleOpenDialog = async (type) => { |
||||
await setTypeDialog(type) |
||||
setOpenDialog(true) |
||||
} |
||||
|
||||
const handleCloseDialog = (type, data) => { |
||||
if (type === "save") { |
||||
saveUser(data); |
||||
} else if (type === "edit") { |
||||
editUser(data); |
||||
} |
||||
setDataEdit([]) |
||||
setOpenDialog(false) |
||||
} |
||||
|
||||
const toggleAddDialog = () => { |
||||
setOpenDialog(!openDialog) |
||||
} |
||||
|
||||
const onConfirmDelete = async () => { |
||||
let url = USER_DELETE(idDelete); |
||||
|
||||
const result = await axios.delete(url,config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
getDataUser() |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.success(`Data user berhasil dihapus!`, 'Success!!'); |
||||
} else { |
||||
setIdDelete(0) |
||||
setAlertDelete(false) |
||||
NotificationManager.error(`Data user gagal dihapus!}`, 'Failed!!'); |
||||
} |
||||
} |
||||
|
||||
const userRoleDelete = async (id) => { |
||||
let url = USERROLE_DELETE(id); |
||||
|
||||
const result = await axios.delete(url,config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if (result && result.data && result.data.code === 200) { |
||||
|
||||
} else { |
||||
|
||||
} |
||||
} |
||||
|
||||
const saveUser = async (data) => {
|
||||
const formData = data |
||||
|
||||
const result = await axios.post(USER_ADD, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code===200){ |
||||
let dataRes = result.data.data |
||||
addUserRole(dataRes.id, data.role_id) |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, 'Failed!!'); |
||||
}
|
||||
|
||||
} |
||||
|
||||
const editUser = async (data) => { |
||||
|
||||
let url = USER_EDIT(data.user_id) |
||||
|
||||
const formData = data |
||||
|
||||
const result = await axios.put(url, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code===200){ |
||||
editUserRole(data) |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const addUserRole = async (user_id, role_id) => { |
||||
const formData = { |
||||
user_id, |
||||
role_id |
||||
} |
||||
const result = await axios.post(USERROLE_ADD, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code===200){ |
||||
getDataUser(); |
||||
NotificationManager.success(`Data user berhasil ditambahkan`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const editUserRole = async (data) => { |
||||
let url = USERROLE_EDIT(data.id) |
||||
|
||||
const formData = { |
||||
user_id:data.user_id, |
||||
role_id:data.role_id |
||||
} |
||||
|
||||
const result = await axios.put(url, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code===200){ |
||||
getDataUser(); |
||||
NotificationManager.success(`Data user berhasil di edit`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
|
||||
const handleEdit = async (data) => { |
||||
await setDataEdit(data) |
||||
handleOpenDialog('Edit'); |
||||
} |
||||
|
||||
const handleDelete = async (id) => { |
||||
await setAlertDelete(true) |
||||
await setIdDelete(id) |
||||
} |
||||
|
||||
const onShowSizeChange = (current, pageSize) => { |
||||
setRowsPerPage(pageSize) |
||||
} |
||||
|
||||
const onPagination = (current, pageSize) => { |
||||
setCurrentPage(current) |
||||
} |
||||
|
||||
const handleExportExcel = async () => { |
||||
|
||||
const payload = { |
||||
"paging":{ |
||||
"start":0, |
||||
"length":-1 |
||||
}, |
||||
"filter_columns":[ |
||||
{ |
||||
"name":"name", |
||||
"value":"", |
||||
"table_name":"m_users" |
||||
} |
||||
], |
||||
"columns":[ |
||||
{ |
||||
"name":"name", |
||||
"logic_operator":"like", |
||||
"value":search, |
||||
"operator":"AND", |
||||
"table_name":"m_users" |
||||
} |
||||
], |
||||
"joins":[ |
||||
{ |
||||
"name":"m_users", |
||||
"column_join":"user_id", |
||||
"column_results":[ |
||||
"username", |
||||
"name", |
||||
"email", |
||||
"gender", |
||||
"phone_number", |
||||
"address", |
||||
"birth_place", |
||||
"birth_date" |
||||
] |
||||
}, |
||||
{ |
||||
"name":"m_roles", |
||||
"column_join":"role_id", |
||||
"column_results":[ |
||||
"name" |
||||
] |
||||
} |
||||
], |
||||
"orders":{ |
||||
"columns":[ |
||||
"id" |
||||
], |
||||
"ascending":false |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
const result = await axios |
||||
.post(USERROLE_SEARCH, payload, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code == 200){ |
||||
let resData = result.data.data; |
||||
const excelData = []; |
||||
resData.map((n, index) => { |
||||
let dataRow = { |
||||
"Name" :n.join.m_users_name ? n.join.m_users_name : "-", |
||||
"Email" :n.join.m_users_email ? n.join.m_users_email : "-", |
||||
"Username" :n.join.m_users_username ? n.join.m_users_username : "-", |
||||
"Phone Number":n.join.m_users_phone_number ? n.join.m_users_phone_number : "-", |
||||
"Address":n.join.m_users_address ? n.join.m_users_address : "-", |
||||
"Birth Date":n.join.m_users_birth_date ? moment(n.join.m_users_birth_date).format("YYYY-MM-DD") : "-", |
||||
"Birth Place":n.join.m_users_birth_place ? n.join.m_users_birth_place : "-", |
||||
"Gender":n.join.m_users_gender ? n.join.m_users_gender : "-" |
||||
} |
||||
excelData.push(dataRow) |
||||
}) |
||||
await setDataExport(excelData); |
||||
}else{ |
||||
NotificationManager.error('Gagal Export Data!!', 'Failed'); |
||||
}
|
||||
} |
||||
|
||||
|
||||
const exportExcel = () => { |
||||
const dataExcel = dataExport || []; |
||||
const fileName = `Data ${pageName}.xlsx`; |
||||
const ws = XLSX.utils.json_to_sheet(dataExcel); |
||||
const wb = XLSX.utils.book_new(); |
||||
XLSX.utils.book_append_sheet(wb, ws, `Data ${pageName}`); |
||||
|
||||
XLSX.writeFile(wb, fileName); |
||||
} |
||||
|
||||
const cancelDelete = () => { |
||||
setAlertDelete(false) |
||||
setIdDelete(0) |
||||
} |
||||
|
||||
const renderRoleProyek = (role_name, user_id) => { |
||||
const userProyek = allDataUserProyek || [] |
||||
let index = userProyek.findIndex(x => parseInt(x.user_id) === parseInt(user_id)); |
||||
if(index>=0){ |
||||
return allDataUserProyek[index].join.m_proyek_nama |
||||
}else{ |
||||
return role_name; |
||||
} |
||||
} |
||||
|
||||
const handleWaspangProyek = async (data) => { |
||||
await setWaspangId(data.user_id) |
||||
getDataWaspangProyek(data.user_id); |
||||
} |
||||
|
||||
const getDataWaspangProyek = async (id) => { |
||||
const formData = { |
||||
"paging": {"start": 0, "length": -1}, |
||||
"columns": [ |
||||
{"name": "user_id", "logic_operator": "=", "value": id.toString(), "operator": "AND"} |
||||
], |
||||
"joins": [], |
||||
"orders": {"columns": ["id"], "ascending": false} |
||||
} |
||||
const result = await axios.post(USERPROYEK_SEARCH, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code===200){ |
||||
let dataRes = result.data.data |
||||
if(dataRes.length > 0){ |
||||
await setDataWaspangProyek(result.data.data) |
||||
setOpenDialogProyek(true) |
||||
}else { |
||||
await setDataWaspangProyek([]) |
||||
setOpenDialogProyek(true) |
||||
} |
||||
|
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const closeProyekDialog = (type, data) => { |
||||
if(type==="save"){ |
||||
if(data.type==="add"){ |
||||
saveWaspangProyek(data) |
||||
}else{ |
||||
editWaspangProyek(data) |
||||
} |
||||
} |
||||
setOpenDialogProyek(false) |
||||
} |
||||
|
||||
const saveWaspangProyek = async (data) => { |
||||
const formData = data |
||||
|
||||
const result = await axios.post(USERPROYEK_ADD, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code===200){ |
||||
NotificationManager.success(`Data user proyek berhasil ditambahkan`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const editWaspangProyek = async (data) => { |
||||
|
||||
let url = USERPROYEK_EDIT(data.id) |
||||
|
||||
const formData = data |
||||
|
||||
const result = await axios.put(url, formData, config) |
||||
.then(res => res) |
||||
.catch((error) => error.response); |
||||
|
||||
if(result && result.data && result.data.code===200){ |
||||
NotificationManager.success(`Data user proyek berhasil diedit`, 'Success!!'); |
||||
} else { |
||||
NotificationManager.error(`${result.data.message}`, `Failed!!`); |
||||
} |
||||
} |
||||
|
||||
const toggleProyekDialog = () => { |
||||
setOpenDialogProyek(!openDialogProyek) |
||||
} |
||||
|
||||
return ( |
||||
<div> |
||||
<NotificationContainer /> |
||||
<SweetAlert |
||||
show={alertDelete} |
||||
warning |
||||
showCancel |
||||
confirmBtnText="Delete" |
||||
confirmBtnBsStyle="danger" |
||||
title={`Apakah kamu yakin?`} |
||||
onConfirm={onConfirmDelete} |
||||
onCancel={() => cancelDelete()} |
||||
focusCancelBtn |
||||
> |
||||
Data user waspang akan terhapus!! |
||||
</SweetAlert> |
||||
<DialogForm |
||||
openDialog={openDialog} |
||||
closeDialog={handleCloseDialog} |
||||
toggleDialog={() => toggleAddDialog} |
||||
typeDialog={typeDialog} |
||||
dataEdit={dataEdit} |
||||
clickOpenModal={clickOpenModal} |
||||
dataRole={dataRole} |
||||
/> |
||||
<DialogProyek |
||||
openDialog={openDialogProyek} |
||||
closeDialog={closeProyekDialog} |
||||
dataProyek={dataProyek} |
||||
dataWaspangProyek={dataWaspangProyek} |
||||
toggleDialog={toggleProyekDialog} |
||||
waspangId={waspangId} |
||||
/> |
||||
<Card> |
||||
<CardHeader style={{ display: "flex", justifyContent: "space-between" }}> |
||||
<h4>{pageName}</h4> |
||||
<Row> |
||||
<Col> |
||||
<Input onChange={handleSearch} value={search} type="text" name="search" id="search" placeholder={`Cari nama`} /> |
||||
</Col> |
||||
<Col> |
||||
<Tooltip title="Tambah User Waspang"> |
||||
<Button id="TooltipTambah" color="success" onClick={() => handleOpenDialog('Save')}><i className="fa fa-plus"></i></Button> |
||||
</Tooltip> |
||||
<Tooltip title="Export Excel"> |
||||
<Button style={{marginLeft:"5px"}} id="TooltipExport" color="primary" onClick={()=> handleExportExcel()}><i className="fa fa-print"></i></Button> |
||||
</Tooltip> |
||||
</Col> |
||||
</Row> |
||||
</CardHeader> |
||||
<CardBody> |
||||
<Table responsive striped hover> |
||||
<thead> |
||||
<tr> |
||||
<th className="capitalize">Aksi</th> |
||||
{column.map((i, index) => { |
||||
return ( |
||||
<th key={index} scope="row">{i.name}</th> |
||||
) |
||||
})} |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{dataTable.length<=0 ?
|
||||
<tr> |
||||
<td colSpan="7" align="center">No Data Available</td> |
||||
</tr> : null} |
||||
{dataTable.map((n, index) => { |
||||
return ( |
||||
<tr key={index}> |
||||
<td> |
||||
<Tooltip title="Delete"> |
||||
<i id="TooltipDelete" className="fa fa-trash" style={{ color: 'red', marginRight: '10px', cursor: "pointer" }} onClick={() => handleDelete(n.user_id)}></i> |
||||
</Tooltip> |
||||
<Tooltip title="Edit"> |
||||
<i id="TooltipEdit" className="fa fa-pencil" style={{ color: 'green', cursor: "pointer",marginRight: '10px' }} onClick={() => handleEdit(n)}></i> |
||||
</Tooltip> |
||||
<Tooltip title={`Proyek`}> |
||||
<i onClick={() => handleWaspangProyek(n)} style={{color:"black", cursor: "pointer"}} className="cil-task"></i> |
||||
</Tooltip> |
||||
</td> |
||||
<td>{n.join ? n.join.m_users_name : "-"}</td> |
||||
<td>{n.join ? n.join.m_users_birth_place || "-" : "-"}</td> |
||||
<td>{n.join.m_users_birth_date ? moment(n.join.m_users_birth_date).format("YYYY-MM-DD") : "-"}</td> |
||||
<td>{n.join ? n.join.m_users_phone_number : "-"}</td> |
||||
<td>{n.join ? n.join.m_users_email : "-"}</td> |
||||
{/* <td>{n.join ? n.join.m_roles_name : "-"}</td> */} |
||||
<td>{n.join ? n.role_id===3 ? renderRoleProyek(n.join.m_roles_name, n.user_id) : n.join.m_roles_name : "-"}</td> |
||||
</tr> |
||||
) |
||||
})} |
||||
</tbody> |
||||
</Table> |
||||
<Pagination |
||||
showSizeChanger |
||||
onShowSizeChange={onShowSizeChange} |
||||
onChange={onPagination} |
||||
defaultCurrent={currentPage} |
||||
pageSize={rowsPerPage} |
||||
total={totalPage} |
||||
pageSizeOptions={["10", "15", "20", "25", "30", "35", "40"]} |
||||
/> |
||||
</CardBody> |
||||
</Card> |
||||
</div> |
||||
) |
||||
} |
||||
|
||||
export default IndexUser; |