create: new folder
BIN
2024___Conference___Irrigation_Openstreetmap___Zaed.pdf
Normal file
32
4507.dat
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
9c245911-d56f-44b0-b76c-1cd9b861abed 6654472586912.jpeg jpeg 607967 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/6654472586912.jpeg 127.0.0.1 t 2024-05-27 15:41:10 2024-05-27 15:41:10
|
||||||
|
9c245a87-f989-4a71-a1d6-37d28d9c0453 6654481b08400.jpeg jpeg 607967 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/6654481b08400.jpeg 127.0.0.1 t 2024-05-27 15:45:16 2024-05-27 15:45:16
|
||||||
|
9c245a89-4839-4e50-9058-71a6470fe343 6654481c2a97a.jpeg jpeg 251421 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/6654481c2a97a.jpeg 127.0.0.1 t 2024-05-27 15:45:17 2024-05-27 15:45:17
|
||||||
|
9c245a8a-31df-494f-a0ea-ccb9d61c5274 6654481d06320.jpeg jpeg 41463 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/6654481d06320.jpeg 127.0.0.1 t 2024-05-27 15:45:17 2024-05-27 15:45:17
|
||||||
|
9c383860-f637-4dd4-8869-e7a75774332d 66614d28c0cc2.jpeg jpeg 607967 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/66614d28c0cc2.jpeg 127.0.0.1 t 2024-06-06 12:46:19 2024-06-06 12:46:19
|
||||||
|
9c3843c8-96d8-4e12-b4f7-687870729448 666154a488e04.jpeg jpeg 41463 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666154a488e04.jpeg 127.0.0.1 t 2024-06-06 13:18:13 2024-06-06 13:18:13
|
||||||
|
9c39e96a-3807-47c2-9b32-48964ff7db2c 666268f624a2d.jpeg jpeg 251421 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666268f624a2d.jpeg 127.0.0.1 t 2024-06-07 08:57:11 2024-06-07 08:57:11
|
||||||
|
9c3bfed9-b016-4ef6-b099-320ebc3da70c 6663c68c65734.jpg jpg 0 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/6663c68c65734.jpg 127.0.0.1 t 2024-06-08 09:48:47 2024-06-08 09:48:47
|
||||||
|
9c3c040c-1e44-4967-9b28-c26fbed03a5e 6663c9f5bfad1.jpg jpg 251421 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/6663c9f5bfad1.jpg 127.0.0.1 t 2024-06-08 10:03:18 2024-06-08 10:03:18
|
||||||
|
9c3c058d-69d5-4623-b4d3-47823d6bed27 6663caf2314b0.png png 452394 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/6663caf2314b0.png 127.0.0.1 t 2024-06-08 10:07:31 2024-06-08 10:07:31
|
||||||
|
9c3c0766-7256-4d77-b8c1-6cf9fa12b965 6663cc2893786.jpeg jpeg 41463 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/6663cc2893786.jpeg 127.0.0.1 t 2024-06-08 10:12:41 2024-06-08 10:12:41
|
||||||
|
9c488123-9cce-4d8d-9fb1-bacad502358a 666bf93231b1c.jpeg jpeg 607967 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666bf93231b1c.jpeg 182.4.135.233 t 2024-06-14 15:03:01 2024-06-14 15:03:01
|
||||||
|
9c488b4d-88b5-48ea-acd1-ce3950bc4cb8 666bffde88ad5.jpeg jpeg 198761 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666bffde88ad5.jpeg 182.4.135.233 t 2024-06-14 15:31:26 2024-06-14 15:31:26
|
||||||
|
9c48da33-e807-4664-85ee-61ce23c79877 666c33934710f.jpeg jpeg 318460 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666c33934710f.jpeg 114.5.222.195 t 2024-06-14 19:12:04 2024-06-14 19:12:04
|
||||||
|
9c4a4978-3f59-4207-befe-9cd776c8f382 666d24449e935.jpeg jpeg 94716 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666d24449e935.jpeg 114.5.110.254 t 2024-06-15 12:19:01 2024-06-15 12:19:01
|
||||||
|
9c4a5033-44e7-45e4-baca-25a0d417c6d7 666d28adcde40.jpeg jpeg 94716 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666d28adcde40.jpeg 114.5.110.254 t 2024-06-15 12:37:50 2024-06-15 12:37:50
|
||||||
|
9c4a5660-f9f6-4426-8fa5-c4f8e4e572e9 666d2cba3dfb7.jpeg jpeg 263098 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666d2cba3dfb7.jpeg 114.5.110.254 t 2024-06-15 12:55:07 2024-06-15 12:55:07
|
||||||
|
9c4a584e-a9a7-4ba1-9023-7ea1ccf0e8d3 666d2dfc8b430.jpeg jpeg 398191 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666d2dfc8b430.jpeg 114.5.110.254 t 2024-06-15 13:00:30 2024-06-15 13:00:30
|
||||||
|
9c4a59de-402e-4edf-ab0e-4e05d98c173d 666d2f02e0b0c.jpeg jpeg 318460 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666d2f02e0b0c.jpeg 114.5.110.254 t 2024-06-15 13:04:52 2024-06-15 13:04:52
|
||||||
|
9c4a5b8c-39f2-457d-9897-8b9ce9ba369c 666d301dae00b.jpeg jpeg 27348 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666d301dae00b.jpeg 114.5.110.254 t 2024-06-15 13:09:34 2024-06-15 13:09:34
|
||||||
|
9c4a5eb1-c037-4c7f-a1c8-64948d945680 666d322ddcd48.jpeg jpeg 27348 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666d322ddcd48.jpeg 114.5.222.144 t 2024-06-15 13:18:22 2024-06-15 13:18:22
|
||||||
|
9c4a60ad-a3f5-4ae4-9fed-37d3bab001d8 666d337ab9a67.jpeg jpeg 94716 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666d337ab9a67.jpeg 114.5.222.144 t 2024-06-15 13:23:55 2024-06-15 13:23:55
|
||||||
|
9c4a704e-cb81-4c2e-bc0a-e0b7c126ff8d 666d3db8a03ca.jpeg jpeg 19241 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666d3db8a03ca.jpeg 103.189.201.114 t 2024-06-15 14:07:37 2024-06-15 14:07:37
|
||||||
|
9c4ccf39-7c43-42fe-a767-dc11ac57f6e5 666ecb74ab14a.jpeg jpeg 696964 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666ecb74ab14a.jpeg 103.213.128.201 t 2024-06-16 18:24:40 2024-06-16 18:24:40
|
||||||
|
9c4ccf41-9ed0-4e3e-be24-8ff2a06dd695 666ecb798cb85.jpeg jpeg 696964 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666ecb798cb85.jpeg 103.213.128.201 t 2024-06-16 18:24:46 2024-06-16 18:24:46
|
||||||
|
9c8a50e7-75e3-4c26-8ecf-feba76062b82 66971a8c380ba.jpeg jpeg 607967 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/66971a8c380ba.jpeg 114.5.222.205 t 2024-07-17 08:12:47 2024-07-17 08:12:47
|
||||||
|
9c8a54af-f5e5-41ce-9186-76dcecd799c3 66971d0762d50.jpeg jpeg 607967 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/66971d0762d50.jpeg 114.5.222.205 t 2024-07-17 08:23:22 2024-07-17 08:23:22
|
||||||
|
9c8a54d5-7eb9-44c8-aa84-287e0c023b97 66971d1faafa2.jpeg jpeg 607967 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/66971d1faafa2.jpeg 114.5.222.205 t 2024-07-17 08:23:46 2024-07-17 08:23:46
|
||||||
|
9c8a54f0-c4db-4c91-a0bd-0284742d23f8 66971d343a4d1.jpeg jpeg 41463 image https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/66971d343a4d1.jpeg 114.5.222.205 t 2024-07-17 08:24:04 2024-07-17 08:24:04
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
6
4509.dat
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
35790101 357901 Junrejo 2024-02-02 23:03:28.578088 \N
|
||||||
|
35790102 357901 Bumiaji 2024-02-02 23:03:28.578088 \N
|
||||||
|
35790103 357901 Batu 2024-02-02 23:03:28.578088 \N
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
16
4524.dat
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
1 2014_10_12_100000_create_password_reset_tokens_table 1
|
||||||
|
2 2019_08_19_000000_create_failed_jobs_table 1
|
||||||
|
3 2019_12_14_000001_create_personal_access_tokens_table 1
|
||||||
|
4 2024_01_19_060639_user_roles 1
|
||||||
|
5 2024_01_19_060640_create_users_table 1
|
||||||
|
6 2024_01_19_061919_status 1
|
||||||
|
7 2024_01_19_062325_city 1
|
||||||
|
8 2024_01_19_062455_districts 1
|
||||||
|
9 2024_01_19_062930_sub_districts 1
|
||||||
|
10 2024_01_19_063439_irrigations 1
|
||||||
|
11 2024_01_19_064559_segments 1
|
||||||
|
12 2024_01_19_065233_report_list 1
|
||||||
|
13 2024_01_19_071531_dss_analytic_data 1
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
38
4534.dat
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
2cbe5013-9fb9-436c-9326-07f7b0d016cb 748c90a1-25ba-4fc1-a9f9-63879cf4fe90 c78b942c-2fd8-4876-b6d6-07933d7326be ticket_IFN6CVEBLPM8T33I3sgJAStv7zNLeqL8lMOGpqkS9mcrtBSzpoitRgGmS3PlVxblV92vdZxxepov1YP9ssUnZxa5LJ6gnqbgHlZ0 \N \N \N
|
||||||
|
7ab28f87-380d-484d-ad24-1060828f0131 748c90a1-25ba-4fc1-a9f9-63879cf4fe90 c78b942c-2fd8-4876-b6d6-07933d7326be ticket_RHLKzn0J1RRxShr2WKLYXoRNqUZlM4TFBMHYcOhDSz1vh1vxv5MxJC2o5GNsOykXS24UGKNb8FLNN4xpbfgsLE5bK8C9J1uW1fzT \N \N \N
|
||||||
|
a7b46667-861f-40f1-9c8b-90bc24f80cb0 748c90a1-25ba-4fc1-a9f9-63879cf4fe90 c78b942c-2fd8-4876-b6d6-07933d7326be ticket_eBBDXMas8DSsOoHWKZhgYE5eZYjIyVtCOFVDbxyGxYimVKJN9TVrJfIdaCBrkuipeny9y1YjighQgTzcv27OL9aig1ZxCME8q2QG \N 2024-02-14 13:25:42 2024-02-14 13:25:42
|
||||||
|
8a865321-03f7-4d66-b234-a7947fededc0 748c90a1-25ba-4fc1-a9f9-63879cf4fe90 c78b942c-2fd8-4876-b6d6-07933d7326be ticket_3lDZpdLtAYDbc6c5sPGxh9QSIT4NYwXI6svZg0pPlQrzAd6LTyT1C02T1z0uPlqa1yvNtdEqeTsuLl7cZNWtpZBwEuWolLgzqRaG \N 2024-02-14 13:34:06 2024-02-14 13:34:06
|
||||||
|
ccf7db7b-62ae-4c43-8051-a605a2b408ca 748c90a1-25ba-4fc1-a9f9-63879cf4fe90 c78b942c-2fd8-4876-b6d6-07933d7326be ticket_e0AmUjlV4tRclTk0rWZIPIRom6xcoYGtnkq9PNqciTvvhjVerl7KyGQ99CdKTQVAYqFVKmBA2mLn2GiNwZvhUaIb9a4n0D1Xs5TS \N 2024-02-14 13:54:14 2024-02-14 13:54:14
|
||||||
|
b24f5079-0007-472c-93fe-938f3ec2fa8f 748c90a1-25ba-4fc1-a9f9-63879cf4fe90 c78b942c-2fd8-4876-b6d6-07933d7326be 2402QLKAz \N 2024-02-15 13:12:17 2024-02-15 13:12:17
|
||||||
|
3801c872-3ba3-4804-bd68-5f508a41ea99 748c90a1-25ba-4fc1-a9f9-63879cf4fe90 c78b942c-2fd8-4876-b6d6-07933d7326be 240226815 \N 2024-02-15 13:20:53 2024-02-15 13:20:53
|
||||||
|
7ddc0739-9b83-40d8-b9b8-92d0646af352 7dcdfaaf-a5c9-4efe-8ae2-bb3976323e16 c78b942c-2fd8-4876-b6d6-07933d7326be 240284286 \N 2024-02-15 14:48:22 2024-02-15 14:48:22
|
||||||
|
65998e18-99c9-4cb1-9755-6499024dbf04 7dcdfaaf-a5c9-4efe-8ae2-bb3976323e16 c78b942c-2fd8-4876-b6d6-07933d7326be 240262543 \N 2024-02-15 14:49:34 2024-02-15 14:49:34
|
||||||
|
9c245876-1072-40c4-b97e-73d978c1395e 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240525682 \N 2024-05-27 15:39:28 2024-05-27 15:39:28
|
||||||
|
9c245a86-3ac6-409a-9215-f02cb618d4f4 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240510750 \N 2024-05-27 15:45:15 2024-05-27 15:45:15
|
||||||
|
9c3837c3-0667-4eab-83ca-5bf61200c282 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240656917 \N 2024-06-06 12:44:36 2024-06-06 12:44:36
|
||||||
|
9c38385c-58eb-4339-ae15-f18d8bfa651d 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240652328 \N 2024-06-06 12:46:16 2024-06-06 12:46:16
|
||||||
|
9c39e968-8e6b-46af-bbee-49b5ccd88f5c 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240617867 \N 2024-06-07 08:57:10 2024-06-07 08:57:10
|
||||||
|
9c487a74-95ba-4c4e-96e8-3c3d144a9f94 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240618543 \N 2024-06-14 14:44:20 2024-06-14 14:44:20
|
||||||
|
9c487cb3-2a4d-457b-9af6-86ceeec251e1 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240664210 \N 2024-06-14 14:50:36 2024-06-14 14:50:36
|
||||||
|
9c487fa8-111f-4a85-bfb1-45d4fed362d2 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240613260 \N 2024-06-14 14:58:52 2024-06-14 14:58:52
|
||||||
|
9c48808c-090a-4638-ac8b-4e706d9fe7e1 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240694867 \N 2024-06-14 15:01:22 2024-06-14 15:01:22
|
||||||
|
9c48811e-3873-44cb-ad9d-776bb51cc5ff 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240667300 \N 2024-06-14 15:02:58 2024-06-14 15:02:58
|
||||||
|
9c488b4c-f727-478b-9fcc-c6fd1c3d5493 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240682416 \N 2024-06-14 15:31:26 2024-06-14 15:31:26
|
||||||
|
9c4a4977-3e40-486e-8714-3f8cd90a9ea9 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240628826 \N 2024-06-15 12:19:00 2024-06-15 12:19:00
|
||||||
|
9c4a5032-417f-4578-acc2-7c40e0b3c59e 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240682728 \N 2024-06-15 12:37:49 2024-06-15 12:37:49
|
||||||
|
9c4a565f-b15f-4145-a11b-27c5b5162f6d 9c4a5526-dff4-437b-8bd3-d2febba30bbe c78b942c-2fd8-4876-b6d6-07933d7326be 240637288 \N 2024-06-15 12:55:06 2024-06-15 12:55:06
|
||||||
|
9c4a584b-8237-425b-828f-2e0cb7a20700 9c4a5526-dff4-437b-8bd3-d2febba30bbe c78b942c-2fd8-4876-b6d6-07933d7326be 240624225 \N 2024-06-15 13:00:28 2024-06-15 13:00:28
|
||||||
|
9c4a59db-d29d-4cd7-a82b-dd4e7a1ece8a 9c4a5526-dff4-437b-8bd3-d2febba30bbe c78b942c-2fd8-4876-b6d6-07933d7326be 240689079 \N 2024-06-15 13:04:50 2024-06-15 13:04:50
|
||||||
|
9c4a5b8b-5496-43ef-a06f-448169220753 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240667277 \N 2024-06-15 13:09:33 2024-06-15 13:09:33
|
||||||
|
9c4a5eb1-4997-4a83-9d20-39a7cc8887e8 9c4a5e6b-e4d6-4dde-9c08-3b9bf69261c2 c78b942c-2fd8-4876-b6d6-07933d7326be 240627739 \N 2024-06-15 13:18:21 2024-06-15 13:18:21
|
||||||
|
9c4a60ad-2f53-44cd-be84-6d999823fc7f 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240668758 \N 2024-06-15 13:23:54 2024-06-15 13:23:54
|
||||||
|
9c24590f-a6c6-46e1-bbd1-aa02be4faf2d 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f 1b8f9309-0626-4dbb-9959-dccd6f441677 240510767 \N 2024-05-27 15:41:09 2024-05-27 15:41:09
|
||||||
|
9c3843c7-9569-471c-a6c3-e455dc44d858 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f 1b8f9309-0626-4dbb-9959-dccd6f441677 240612217 \N 2024-06-06 13:18:12 2024-06-06 13:18:12
|
||||||
|
9c48da32-9d61-49de-8d19-38e6ca7cb498 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f 4307de48-c40c-4b52-ba94-9207103e5d36 240616566 \N 2024-06-14 19:12:03 2024-06-14 19:12:03
|
||||||
|
9c8a50e2-3704-4cb6-95b3-dce29680e0c3 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240791365 \N 2024-07-17 08:12:44 2024-07-17 08:12:44
|
||||||
|
9c8a54ab-6a2f-4e0f-91a8-41f288462537 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240743984 \N 2024-07-17 08:23:19 2024-07-17 08:23:19
|
||||||
|
9c8a54d0-7c7d-4bdf-b8c4-4f7b284897c6 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240779171 \N 2024-07-17 08:23:43 2024-07-17 08:23:43
|
||||||
|
9c8a54ef-d376-42e8-a677-ad3a2af03e6b 9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f c78b942c-2fd8-4876-b6d6-07933d7326be 240786569 \N 2024-07-17 08:24:04 2024-07-17 08:24:04
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
25
4535.dat
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
9c245911-f8f6-4d70-9d03-dbca2460499f 9c24590f-aac4-4910-977d-cf9671acaab9 9c245911-d56f-44b0-b76c-1cd9b861abed 2024-05-27 15:41:11 2024-05-27 15:41:11
|
||||||
|
9c245a87-fbfe-4ef9-bccf-169263049006 9c245a86-3e51-4f42-8829-f3a0de5378e8 9c245a87-f989-4a71-a1d6-37d28d9c0453 2024-05-27 15:45:16 2024-05-27 15:45:16
|
||||||
|
9c245a89-4923-4773-aee3-1a3f19339bdf 9c245a87-fd0f-43e7-9220-65a2ec7025fe 9c245a89-4839-4e50-9058-71a6470fe343 2024-05-27 15:45:17 2024-05-27 15:45:17
|
||||||
|
9c245a8a-32a9-4631-811d-91d04f2c3d45 9c245a89-4984-484d-a547-999e5c931b94 9c245a8a-31df-494f-a0ea-ccb9d61c5274 2024-05-27 15:45:17 2024-05-27 15:45:17
|
||||||
|
9c383860-fa51-4ca1-af90-ab8b6a2adda3 9c38385c-5c18-4203-8657-e6a75371a8f0 9c383860-f637-4dd4-8869-e7a75774332d 2024-06-06 12:46:19 2024-06-06 12:46:19
|
||||||
|
9c3843c8-97e5-4b02-9265-577742ed8aad 9c3843c7-9874-492f-9529-98ea06eaa365 9c3843c8-96d8-4e12-b4f7-687870729448 2024-06-06 13:18:13 2024-06-06 13:18:13
|
||||||
|
9c39e96a-3a2d-44da-be69-c345bbd2b726 9c39e968-9653-4880-871b-732bdf71a5ad 9c39e96a-3807-47c2-9b32-48964ff7db2c 2024-06-07 08:57:11 2024-06-07 08:57:11
|
||||||
|
9c488123-9df3-4f96-a7ce-e3fa6860802d 9c48811e-3991-4a94-a2c2-b693df7e55d9 9c488123-9cce-4d8d-9fb1-bacad502358a 2024-06-14 15:03:01 2024-06-14 15:03:01
|
||||||
|
9c488b4d-89d0-414c-b5c0-4265ca22ba0a 9c488b4c-f84a-470b-b709-c4df4cb89c9c 9c488b4d-88b5-48ea-acd1-ce3950bc4cb8 2024-06-14 15:31:26 2024-06-14 15:31:26
|
||||||
|
9c48da33-e922-4520-842b-051cdadea321 9c48da32-9e91-48e0-a405-675b4669cad2 9c48da33-e807-4664-85ee-61ce23c79877 2024-06-14 19:12:04 2024-06-14 19:12:04
|
||||||
|
9c4a4978-406e-4066-9ef8-f7c8f3ab4846 9c4a4977-3f4f-4c26-ba43-8560c375bf97 9c4a4978-3f59-4207-befe-9cd776c8f382 2024-06-15 12:19:01 2024-06-15 12:19:01
|
||||||
|
9c4a5033-45f4-44c7-93d0-c379733314f3 9c4a5032-42a0-4a05-94f4-cb1f065558c0 9c4a5033-44e7-45e4-baca-25a0d417c6d7 2024-06-15 12:37:50 2024-06-15 12:37:50
|
||||||
|
9c4a5660-fb0d-4145-9ebc-d677df6de642 9c4a565f-b283-48be-b55f-43b633f899fb 9c4a5660-f9f6-4426-8fa5-c4f8e4e572e9 2024-06-15 12:55:07 2024-06-15 12:55:07
|
||||||
|
9c4a584e-aacc-4809-bd23-637563e48073 9c4a584b-8355-4434-885a-9294504ba3e6 9c4a584e-a9a7-4ba1-9023-7ea1ccf0e8d3 2024-06-15 13:00:30 2024-06-15 13:00:30
|
||||||
|
9c4a59de-4151-4ef3-8652-bc92a00464d6 9c4a59db-d3c5-4c41-a609-82cea3cdbb19 9c4a59de-402e-4edf-ab0e-4e05d98c173d 2024-06-15 13:04:52 2024-06-15 13:04:52
|
||||||
|
9c4a5b8c-3b00-4b1c-ac33-b58d90494559 9c4a5b8b-55a5-4773-8202-a2c55ba18e55 9c4a5b8c-39f2-457d-9897-8b9ce9ba369c 2024-06-15 13:09:34 2024-06-15 13:09:34
|
||||||
|
9c4a5eb1-c140-492a-8811-9560e25d02ac 9c4a5eb1-4a99-44e9-b1b2-7eee73e2c18f 9c4a5eb1-c037-4c7f-a1c8-64948d945680 2024-06-15 13:18:22 2024-06-15 13:18:22
|
||||||
|
9c4a60ad-a503-4ae2-ae25-9aa04f7dcaba 9c4a60ad-306f-4c0b-9beb-6344a1d8fd80 9c4a60ad-a3f5-4ae4-9fed-37d3bab001d8 2024-06-15 13:23:55 2024-06-15 13:23:55
|
||||||
|
9c8a50e7-7702-4861-a26b-7bf547439dd9 9c8a50e2-3811-4a99-bed2-eef381a3e33d 9c8a50e7-75e3-4c26-8ecf-feba76062b82 2024-07-17 08:12:47 2024-07-17 08:12:47
|
||||||
|
9c8a54af-f701-42bc-99c3-4a040a3c2576 9c8a54ab-6b66-473d-8321-5e3fd91a249b 9c8a54af-f5e5-41ce-9186-76dcecd799c3 2024-07-17 08:23:22 2024-07-17 08:23:22
|
||||||
|
9c8a54d5-7fd3-4e29-9427-a45a8e4e443e 9c8a54d0-7daf-4310-97cb-59aa187865ed 9c8a54d5-7eb9-44c8-aa84-287e0c023b97 2024-07-17 08:23:46 2024-07-17 08:23:46
|
||||||
|
9c8a54f0-c5f1-4b06-9fdc-e49bc45a0123 9c8a54ef-d4d2-405f-8375-3770fc212fc4 9c8a54f0-c4db-4c91-a0bd-0284742d23f8 2024-07-17 08:24:04 2024-07-17 08:24:04
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
29
4536.dat
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
9c24590f-aac4-4910-977d-cf9671acaab9 9c24590f-a6c6-46e1-bbd1-aa02be4faf2d f180297a-770e-4169-9d19-d1e5b9903daa Berat \N \N \N Ambrol 2024-05-27 15:41:09 2024-05-27 15:41:09
|
||||||
|
9c245a86-3e51-4f42-8829-f3a0de5378e8 9c245a86-3ac6-409a-9215-f02cb618d4f4 51a7b55c-417c-4531-912d-87c7f5d544c8 Berat \N \N \N Iki ambrol mas 2024-05-27 15:45:15 2024-05-27 15:45:15
|
||||||
|
9c245a87-fd0f-43e7-9220-65a2ec7025fe 9c245a86-3ac6-409a-9215-f02cb618d4f4 2e651a70-331c-4c58-b0dd-21d6b32bb52e Sedang \N \N \N Semenane kok patah-patah mas 2024-05-27 15:45:16 2024-05-27 15:45:16
|
||||||
|
9c245a89-4984-484d-a547-999e5c931b94 9c245a86-3ac6-409a-9215-f02cb618d4f4 eb60350a-6177-456b-9a5b-73e367d94f32 Ringan \N \N \N Semenane protol ringan! 2024-05-27 15:45:17 2024-05-27 15:45:17
|
||||||
|
9c38385c-5c18-4203-8657-e6a75371a8f0 9c38385c-58eb-4339-ae15-f18d8bfa651d d5aec113-b425-45c2-aeb4-0ff98da60a9f Berat \N \N \N Ambrol mas bro 2024-06-06 12:46:16 2024-06-06 12:46:16
|
||||||
|
9c3843c7-9874-492f-9529-98ea06eaa365 9c3843c7-9569-471c-a6c3-e455dc44d858 ec895365-0a52-4c13-a2d0-bc22825d5206 Sedang \N \N \N Semenan e protol mas bro 2024-06-06 13:18:12 2024-06-06 13:18:12
|
||||||
|
9c39e968-9653-4880-871b-732bdf71a5ad 9c39e968-8e6b-46af-bbee-49b5ccd88f5c 7be6324e-f9ad-425a-b2d0-5b189002d5a0 Sedang \N \N \N Semenan e patah ndek daerah selecta 2024-06-07 08:57:10 2024-06-07 08:57:10
|
||||||
|
9c487a74-978f-4370-8939-cfcff28fcd01 9c487a74-95ba-4c4e-96e8-3c3d144a9f94 fe19ff6c-3be2-45e4-8252-baab5a68ce6a Sedang \N \N \N Semenan rusak 2024-06-14 14:44:20 2024-06-14 14:44:20
|
||||||
|
9c487cb3-2b6d-4c1f-9112-6e17033226b2 9c487cb3-2a4d-457b-9af6-86ceeec251e1 258237d5-b774-457e-966f-5c5cbebb7f2e Berat \N \N \N ambrol 2024-06-14 14:50:36 2024-06-14 14:50:36
|
||||||
|
9c487fa8-1242-41d5-b3ce-a9c85f8444cc 9c487fa8-111f-4a85-bfb1-45d4fed362d2 500e33f5-a90d-4bbf-999a-36f85b2b38f0 Berat \N \N \N ambrol 2024-06-14 14:58:52 2024-06-14 14:58:52
|
||||||
|
9c48808c-0a2e-416b-aa6c-ddeaec758789 9c48808c-090a-4638-ac8b-4e706d9fe7e1 6b218079-5937-412d-a252-58ce9a96951e Berat \N \N \N ambrol 2024-06-14 15:01:22 2024-06-14 15:01:22
|
||||||
|
9c48811e-3991-4a94-a2c2-b693df7e55d9 9c48811e-3873-44cb-ad9d-776bb51cc5ff 500e33f5-a90d-4bbf-999a-36f85b2b38f0 Berat \N \N \N ambrol 2024-06-14 15:02:58 2024-06-14 15:02:58
|
||||||
|
9c488b4c-f84a-470b-b709-c4df4cb89c9c 9c488b4c-f727-478b-9fcc-c6fd1c3d5493 eefbdcdc-b941-4f81-8d00-5cf736c83abd Ringan \N \N \N Ringan 2024-06-14 15:31:26 2024-06-14 15:31:26
|
||||||
|
9c48da32-9e91-48e0-a405-675b4669cad2 9c48da32-9d61-49de-8d19-38e6ca7cb498 62131b74-83ee-4034-8e70-a7eb61a38ffe Ringan \N \N \N ringan 2024-06-14 19:12:03 2024-06-14 19:12:03
|
||||||
|
9c4a4977-3f4f-4c26-ba43-8560c375bf97 9c4a4977-3e40-486e-8714-3f8cd90a9ea9 f2265ab4-eae5-48f5-a20a-374fceade32f Ringan \N \N \N ringan 2024-06-15 12:19:00 2024-06-15 12:19:00
|
||||||
|
9c4a5032-42a0-4a05-94f4-cb1f065558c0 9c4a5032-417f-4578-acc2-7c40e0b3c59e eefbdcdc-b941-4f81-8d00-5cf736c83abd Sedang \N \N \N semenan ada yang rusak 2024-06-15 12:37:49 2024-06-15 12:37:49
|
||||||
|
9c4a565f-b283-48be-b55f-43b633f899fb 9c4a565f-b15f-4145-a11b-27c5b5162f6d ef66260e-d3fc-4139-a015-d7eb7380df28 Sedang \N \N \N Seharusnya ditanami bambu untuk menguatkan Pipa pipa irigasi 2024-06-15 12:55:06 2024-06-15 12:55:06
|
||||||
|
9c4a584b-8355-4434-885a-9294504ba3e6 9c4a584b-8237-425b-828f-2e0cb7a20700 1980a0f2-b321-497c-b51e-3c608314022e Ringan \N \N \N Rusak dikit di semenan 2024-06-15 13:00:28 2024-06-15 13:00:28
|
||||||
|
9c4a59db-d3c5-4c41-a609-82cea3cdbb19 9c4a59db-d29d-4cd7-a82b-dd4e7a1ece8a 1980a0f2-b321-497c-b51e-3c608314022e Ringan \N \N \N longsor dikit 2024-06-15 13:04:50 2024-06-15 13:04:50
|
||||||
|
9c4a5b8b-55a5-4773-8202-a2c55ba18e55 9c4a5b8b-5496-43ef-a06f-448169220753 fb795f4c-32fd-401d-b224-45178c5ca0bd Ringan \N \N \N kurang kuat 2024-06-15 13:09:33 2024-06-15 13:09:33
|
||||||
|
9c4a5eb1-4a99-44e9-b1b2-7eee73e2c18f 9c4a5eb1-4997-4a83-9d20-39a7cc8887e8 fb795f4c-32fd-401d-b224-45178c5ca0bd Sedang \N \N \N sedang 2024-06-15 13:18:21 2024-06-15 13:18:21
|
||||||
|
9c4a60ad-306f-4c0b-9beb-6344a1d8fd80 9c4a60ad-2f53-44cd-be84-6d999823fc7f 1980a0f2-b321-497c-b51e-3c608314022e Ringan \N \N \N longsor dikit 2024-06-15 13:23:54 2024-06-15 13:23:54
|
||||||
|
9c8a50e2-3811-4a99-bed2-eef381a3e33d 9c8a50e2-3704-4cb6-95b3-dce29680e0c3 d3cb354c-1d6c-4f74-b712-cb27a04356d2 Berat \N \N \N Ambrol maze 2024-07-17 08:12:44 2024-07-17 08:12:44
|
||||||
|
9c8a54ab-6b66-473d-8321-5e3fd91a249b 9c8a54ab-6a2f-4e0f-91a8-41f288462537 c7d934ca-2295-467b-ab03-21125a7dbc36 Berat \N \N \N Semenan russak adan ambrol 2024-07-17 08:23:19 2024-07-17 08:23:19
|
||||||
|
9c8a54d0-7daf-4310-97cb-59aa187865ed 9c8a54d0-7c7d-4bdf-b8c4-4f7b284897c6 3fafcdb3-e2a6-46f3-9cac-d0652e331a55 Berat \N \N \N Semenan ambrol 2024-07-17 08:23:43 2024-07-17 08:23:43
|
||||||
|
9c8a54ef-d4d2-405f-8375-3770fc212fc4 9c8a54ef-d376-42e8-a677-ad3a2af03e6b f2f13cbd-7ba7-4daa-a158-6de324826d5c Sedang \N \N \N Semanan protol 2024-07-17 08:24:04 2024-07-17 08:24:04
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
6
4537.dat
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
1b8f9309-0626-4dbb-9959-dccd6f441677 Ditindak Lanjuti 2024-06-06 13:26:12 \N
|
||||||
|
4307de48-c40c-4b52-ba94-9207103e5d36 Selesai 2024-06-06 13:27:12 \N
|
||||||
|
c78b942c-2fd8-4876-b6d6-07933d7326be Dalam Proses 2024-02-23 11:05:12 \N
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
6
4539.dat
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
732afb4c-faf0-4a21-bb51-ce9d9275b844 Admin ADM 2024-02-06 23:04:14 \N
|
||||||
|
844c6707-c758-46ab-aaaf-513c814ff7af TestBro TEST for testing 2024-02-13 00:22:44 2024-02-13 00:22:44
|
||||||
|
1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa User USR for civilian and PUPR employee 2024-02-15 14:41:53 2024-02-15 14:41:53
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
19
4540.dat
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
748c90a1-25ba-4fc1-a9f9-63879cf4fe90 732afb4c-faf0-4a21-bb51-ce9d9275b844 Slebew test@gmail.com $2y$12$PxLzU0XQousGkhcekjx0wuDLlVO9TSqpS.JYA1gl2uXv/Ic0/O4dm Maulana Rosandy faefeaf 2024-02-07 15:22:20 2024-02-07 15:38:13 \N \N
|
||||||
|
0f716f90-27b7-477c-b9ac-90b670527c61 844c6707-c758-46ab-aaaf-513c814ff7af Hello test1@gmail.com $2y$12$Kz37uXysccFCXqSW.cY5ZuzNo4J1JhQgZUzM7lPup9l/jniN46IF. Maulana p 2024-02-14 23:57:05 2024-02-15 10:07:30 \N \N
|
||||||
|
7dcdfaaf-a5c9-4efe-8ae2-bb3976323e16 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa zaed zaed@gmail.com $2y$12$600S6Mvp3KV1m7OFYKfrdest3vjL1fOVEw7c38CdRB4woidTUr46K Zaed Abdullah https://images.unsplash.com/photo-1575936123452-b67c3203c357?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8aW1hZ2V8ZW58MHx8MHx8fDA%3D 2024-02-15 14:46:14 2024-02-15 14:46:14 \N \N
|
||||||
|
9c364baa-8a25-4987-ab6b-7c6f0907d523 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa rudy rudy@gmail.com $2y$12$xM7ZIn186Ch9RXIXPUR3WO8beQHplmSAgNYpnc5a9YQOzsMJ2PL1q Rudy \N 2024-06-05 13:48:36 2024-06-05 13:48:36 \N \N
|
||||||
|
9c368299-f71e-498b-b881-4e446e7fb771 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa zaedabdullah z4ed.thalib123@gmail.com $2y$12$EEVUyrv4UGaL/WUGXGvBkOIDMGc6QDUGjlSl1fhqTGCcg.syK2yti Zaed Abdullah \N 2024-06-05 16:22:12 2024-06-06 09:48:00 \N \N
|
||||||
|
9c3a5bb7-0e51-4f89-8678-6ffb6fb0748e 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa zen zen@gmail.com $2y$12$qyLaoKe5WLKPn0hB/6Igcu1PvKLgYtfLwGFc3ZuRTbVPfSk3xqPuC Darwadi Zen \N 2024-06-07 14:16:47 2024-06-07 14:34:45 \N \N
|
||||||
|
9c482ec1-620d-4daf-a0eb-8f3bf3577bbe 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa anis anis@gmail.com $2y$12$fihpi6ncOajvgSPemr/xveWKB.SgNfb3uenI1BaZLbU4E8G51pb4m Anis \N 2024-06-14 11:12:40 2024-06-14 11:12:40 \N \N
|
||||||
|
9c4861a3-ae86-4611-a616-bd897fd23b72 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa Anita anitamunawaroh7@gmail.com $2y$12$B7xfXmS454VVYhXwWQuo6esKzKinHoqY5KhoAw4bOn8BeSex9qimO Anita \N 2024-06-14 13:34:56 2024-06-14 13:34:56 \N \N
|
||||||
|
9c487498-89aa-4bc1-98ad-b147f8213966 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa syuaib syuaib@gmail.com $2y$12$XEihF.UGuM2u2vtvXR4e/OSQhkeESnxJfwMSpl2pXHVG31CCUKE2. Syuaib pribadi \N 2024-06-14 14:27:57 2024-06-14 14:38:16 \N \N
|
||||||
|
9c488478-42d5-4f6c-b069-d86903e7a6bc 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa Yovie yovieony19@gmail.com $2y$12$mOa1CXs9y2azDBJ/fPPCeeBlXXAahI8n07orS2WDnOBTrLGibMySa Yovie ony saputra \N 2024-06-14 15:12:20 2024-06-14 15:12:20 \N \N
|
||||||
|
9c48912c-af75-416a-9089-977ca252e743 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa anas12 anasmakara@gmail.com $2y$12$LCCOy.AfeNtYNglTdI9E3uKi2HereFJ3SA9KsUneg0dxlGbupnJ5u Anas Ramadhani \N 2024-06-14 15:47:52 2024-06-14 15:47:52 \N \N
|
||||||
|
9c4a4156-03c0-4b65-9e42-9b756d443502 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa Kafi kafi@gmail.com $2y$12$eNAgBie6jmh08fz5Sujgq./XdGsImQqIb/c6pdiJRoUjSd1n7p79C Kafi \N 2024-06-15 11:56:16 2024-06-15 11:56:16 \N \N
|
||||||
|
9c4a5526-dff4-437b-8bd3-d2febba30bbe 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa munadi munadi3612@gmail.com $2y$12$NNRSHp2yGAivE9VoyFBhhefHBZDmcJfD7skDCIqN12FgbNjVm.mT. Munadi \N 2024-06-15 12:51:41 2024-06-15 12:51:41 \N \N
|
||||||
|
9c4a5e6b-e4d6-4dde-9c08-3b9bf69261c2 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa galang galang4123@gmail.com $2y$12$0gbsSy.w/WjLZWcLAmGdGuTjKR7fnW70QYvfH4XJZhl6CWt5o/nj6 Galang \N 2024-06-15 13:17:36 2024-06-15 13:17:36 \N \N
|
||||||
|
9c465894-9a17-4cc2-b6cf-fe5d9139ea1e 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa H Nh $2y$12$AF9HN49w4y89zSEsVIzo6eVkRPps7MDAC.IgKNKU6QyWkd5wQvM/q halo https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/666ecb798cb85.jpeg 2024-06-13 13:17:57 2024-06-16 18:24:46 \N \N
|
||||||
|
9c223f86-a3bc-4e6a-a58d-65a5b8d0c46f 1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa ana ana@gmail.com $2y$12$8ieo8mpu33LAiD/oUuhg0uHQLJXtJxTJzqLngiI2kXlkIpxVgjguq Ana Bellaa https://storage.googleapis.com/irrigation-upload-dump.appspot.com/image/6663cc2893786.jpeg 2024-05-26 14:38:06 2024-07-16 20:33:07 \N \N
|
||||||
|
\.
|
||||||
|
|
||||||
|
|
||||||
BIN
Demo_Aplikasi.mkv
Normal file
21
IrrigationReport/.eslintrc.cjs
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: { browser: true, es2020: true },
|
||||||
|
extends: [
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
'plugin:react/jsx-runtime',
|
||||||
|
'plugin:react-hooks/recommended',
|
||||||
|
],
|
||||||
|
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
||||||
|
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
|
||||||
|
settings: { react: { version: '18.2' } },
|
||||||
|
plugins: ['react-refresh'],
|
||||||
|
rules: {
|
||||||
|
'react-refresh/only-export-components': [
|
||||||
|
'warn',
|
||||||
|
{ allowConstantExport: true },
|
||||||
|
],
|
||||||
|
'react/prop-types': 'off',
|
||||||
|
},
|
||||||
|
}
|
||||||
25
IrrigationReport/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
src/main.jsx
|
||||||
1
IrrigationReport/README.md
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
# PelaporanIrigasi
|
||||||
13
IrrigationReport/index.html
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>IrrigationReport</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.jsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
4485
IrrigationReport/package-lock.json
generated
Normal file
33
IrrigationReport/package.json
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"name": "irrigationreport",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
|
||||||
|
"preview": "vite preview"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bootstrap": "^5.3.2",
|
||||||
|
"bootstrap-icons": "^1.11.3",
|
||||||
|
"leaflet": "^1.9.4",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-cookie": "^7.0.2",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-leaflet": "^4.2.1",
|
||||||
|
"react-router-dom": "^6.22.3",
|
||||||
|
"react-toastify": "^10.0.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/react": "^18.2.37",
|
||||||
|
"@types/react-dom": "^18.2.15",
|
||||||
|
"@vitejs/plugin-react": "^4.2.0",
|
||||||
|
"eslint": "^8.53.0",
|
||||||
|
"eslint-plugin-react": "^7.33.2",
|
||||||
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.4",
|
||||||
|
"vite": "^5.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
IrrigationReport/public/img/map-icon-purple.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
IrrigationReport/public/img/map-icon.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
IrrigationReport/public/img/maps-icon-purple.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
IrrigationReport/public/img/maps-icon.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
IrrigationReport/public/img/pencil-icon.png
Normal file
|
After Width: | Height: | Size: 552 B |
BIN
IrrigationReport/public/img/profile-icon-purple.png
Normal file
|
After Width: | Height: | Size: 115 KiB |
BIN
IrrigationReport/public/img/profile-icon.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
IrrigationReport/public/img/report/sumber_dandang.jpeg
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
IrrigationReport/public/img/riwayat-icon-purple.png
Normal file
|
After Width: | Height: | Size: 6.5 KiB |
BIN
IrrigationReport/public/img/riwayat-icon.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
1
IrrigationReport/public/vite.svg
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
19
IrrigationReport/src/App.css
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
html, body, #root, .page{
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leaflet-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
50
IrrigationReport/src/App.jsx
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
import './App.css'
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
import 'leaflet/dist/leaflet.css'
|
||||||
|
import {
|
||||||
|
BrowserRouter as Router,
|
||||||
|
Routes,
|
||||||
|
Route,
|
||||||
|
} from "react-router-dom";
|
||||||
|
|
||||||
|
import Home from './pages/Home';
|
||||||
|
import Login from './pages/Login';
|
||||||
|
import Register from './pages/Register';
|
||||||
|
import ForgotPassword from './pages/ForgotPassword';
|
||||||
|
import ChangePassword from './pages/ChangePassword';
|
||||||
|
import Laporkan from './pages/Laporkan';
|
||||||
|
import Riwayat from './pages/Riwayat';
|
||||||
|
import Laporan from './pages/Laporan';
|
||||||
|
import Profil from './pages/Profil';
|
||||||
|
import DetailRiwayat from './pages/DetailRiwayat';
|
||||||
|
import EditProfil from './pages/EditProfil';
|
||||||
|
import { CookiesProvider } from 'react-cookie'
|
||||||
|
import Protected from './components/Protected';
|
||||||
|
import { ToastContainer } from 'react-toastify';
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
return (
|
||||||
|
<CookiesProvider>
|
||||||
|
<Router>
|
||||||
|
<ToastContainer autoClose={4000} theme="colored"/>
|
||||||
|
<Routes>
|
||||||
|
<Route path="/login" element={<Login />} />
|
||||||
|
<Route path="/register" element={<Register />} />
|
||||||
|
<Route path="/lupa-password" element={<ForgotPassword />} />
|
||||||
|
<Route path="/ganti-password/:token" element={<ChangePassword />} />
|
||||||
|
<Route element={<Protected/>}>
|
||||||
|
<Route path="/" element={<Home/>} />
|
||||||
|
<Route path="/laporkan" element={<Laporkan/>} />
|
||||||
|
<Route path="/riwayat" element={<Riwayat />} />
|
||||||
|
<Route path="/detail-laporan/:id/:segment" element={<DetailRiwayat />} />
|
||||||
|
<Route path="/laporan" element={<Laporan />} />
|
||||||
|
<Route path="/profil" element={<Profil />} />
|
||||||
|
<Route path="/edit-profil" element={<EditProfil />} />
|
||||||
|
</Route>
|
||||||
|
</Routes>
|
||||||
|
</Router>
|
||||||
|
</CookiesProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App
|
||||||
34
IrrigationReport/src/components/BottomBar.jsx
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { Link } from "react-router-dom"
|
||||||
|
|
||||||
|
export default function BottomBar({activeIcon}) {
|
||||||
|
return(
|
||||||
|
<nav className="navbar navbar-expand navbar-light bg-light">
|
||||||
|
<ul className="navbar-nav nav-justified w-100">
|
||||||
|
<li className="nav-item">
|
||||||
|
<Link to={"/laporkan"} className="nav-link text-center">
|
||||||
|
<img src={activeIcon === "laporkan" ? "/img/map-icon-purple.png" : "/img/map-icon.png"} width={'35vh'}/>
|
||||||
|
<span className="small d-block"><b>Laporkan</b></span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li className="nav-item">
|
||||||
|
<Link to={"/riwayat"} className="nav-link text-center">
|
||||||
|
<img src={activeIcon === "riwayat" ? "/img/riwayat-icon-purple.png" : "/img/riwayat-icon.png"} width={'35vh'} />
|
||||||
|
<span className="small d-block"><b>Riwayat</b></span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li className="nav-item">
|
||||||
|
<Link to={"/laporan"} className="nav-link text-center">
|
||||||
|
<img src={activeIcon === "laporan" ? "/img/maps-icon-purple.png" : "/img/maps-icon.png"} width={'35vh'} />
|
||||||
|
<span className="small d-block"><b>Laporan</b></span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li className="nav-item">
|
||||||
|
<Link to={"/profil"} className="nav-link text-center">
|
||||||
|
<img src={activeIcon === "profil" ? "/img/profile-icon-purple.png" : "/img/profile-icon.png"} width={'35vh'} />
|
||||||
|
<span className="small d-block"><b>Profil</b></span>
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
)
|
||||||
|
}
|
||||||
77
IrrigationReport/src/components/ChangePasswordForm.jsx
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
|
const FORM_ENDPOINT = "https://laporirigasi.my.id/api/reset-password";
|
||||||
|
|
||||||
|
const ChangePasswordForm = () => {
|
||||||
|
const { token } = useParams();
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
const [status, setStatus] = useState('');
|
||||||
|
const [message, setMessage] = useState('');
|
||||||
|
const email = searchParams.get("email");
|
||||||
|
|
||||||
|
let navigate = useNavigate();
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setStatus('loading');
|
||||||
|
setMessage('');
|
||||||
|
|
||||||
|
const finalFormEndpoint = e.target.action;
|
||||||
|
const data = Array.from(e.target.elements)
|
||||||
|
.filter((input) => input.name)
|
||||||
|
.reduce((obj, input) => Object.assign(obj, { [input.name]: input.value }), {});
|
||||||
|
|
||||||
|
fetch(finalFormEndpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(response.statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
setStatus('success');
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setMessage(err.toString());
|
||||||
|
setStatus('error');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (status === "success") {
|
||||||
|
toast.success("Password anda berhasil diganti");
|
||||||
|
navigate("/login");
|
||||||
|
}
|
||||||
|
else if (status === "error") {
|
||||||
|
toast.error("Terjadi kesalahan");
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
}, [status, navigate, message]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
action={FORM_ENDPOINT}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
method="POST"
|
||||||
|
encType="application/x-www-form-urlencoded"
|
||||||
|
>
|
||||||
|
<input type="hidden" name="token" value={token}/>
|
||||||
|
<input type="hidden" name="email" value={email}/>
|
||||||
|
<input type="password" name="password" className="form-input" id="email" placeholder="Password Baru"/>
|
||||||
|
<input type="password" name="password_confirmation" className="form-input" id="email" placeholder="Ulangi Password Baru"/>
|
||||||
|
<button className="forgot-button" type="submit">Kirimkan</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ChangePasswordForm;
|
||||||
108
IrrigationReport/src/components/EditProfilForm.jsx
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Cookies } from "react-cookie";
|
||||||
|
|
||||||
|
const FORM_ENDPOINT = "https://laporirigasi.my.id/api/profile";
|
||||||
|
|
||||||
|
const EditProfilForm = () => {
|
||||||
|
const [status, setStatus] = useState('');
|
||||||
|
const [message, setMessage] = useState('');
|
||||||
|
// Input State for default values
|
||||||
|
const [fullname, setFullName] = useState("");
|
||||||
|
const [img, setImg] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const cookies = new Cookies();
|
||||||
|
fetch(`https://laporirigasi.my.id/api/profile`, {
|
||||||
|
headers: {Authorization: 'Bearer '+cookies.get('user_session')}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
setFullName(data.fullname);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
let navigate = useNavigate();
|
||||||
|
|
||||||
|
const handleImgChange = (e) => {
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(image) {
|
||||||
|
setImg(image.target.result);
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(e.target.files[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setStatus('loading');
|
||||||
|
setMessage('');
|
||||||
|
|
||||||
|
const finalFormEndpoint = e.target.action;
|
||||||
|
const data = Array.from(e.target.elements)
|
||||||
|
.filter((input) => input.name)
|
||||||
|
.reduce((obj, input) => Object.assign(obj, { [input.name]: input.value }), {});
|
||||||
|
|
||||||
|
const cookies = new Cookies();
|
||||||
|
fetch(finalFormEndpoint, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': 'Bearer '+cookies.get('user_session')
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(response.statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
setStatus('success');
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setMessage(err.toString());
|
||||||
|
setStatus('error');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (status === "success") {
|
||||||
|
navigate("/profil");
|
||||||
|
}
|
||||||
|
}, [status, navigate]);
|
||||||
|
|
||||||
|
if (status === "error") {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>Something bad happened!</div>
|
||||||
|
<div>{message}</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
className="e-p-form"
|
||||||
|
action={FORM_ENDPOINT}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
method="PUT"
|
||||||
|
encType="multipart/form-data"
|
||||||
|
>
|
||||||
|
<div className="profile-container">
|
||||||
|
<h4>Foto Profil:</h4>
|
||||||
|
<input type="file" name="photo-profile" accept="image/*" onChange={handleImgChange}></input>
|
||||||
|
<input type="hidden" name="image" value={img}></input>
|
||||||
|
</div>
|
||||||
|
<input type="text" name="fullname" className="e-p-form-input" id="register-fullname" value={fullname} onChange={e => setFullName(e.target.value)}/>
|
||||||
|
<div className="e-div-btn">
|
||||||
|
<button className="e-button">Simpan Data</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default EditProfilForm;
|
||||||
67
IrrigationReport/src/components/ForgotPasswordForm.jsx
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
|
const FORM_ENDPOINT = "https://laporirigasi.my.id/api/forgot-password";
|
||||||
|
|
||||||
|
const ForgotPasswordForm = () => {
|
||||||
|
const [status, setStatus] = useState('');
|
||||||
|
const [message, setMessage] = useState('');
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setStatus('loading');
|
||||||
|
setMessage('');
|
||||||
|
|
||||||
|
const finalFormEndpoint = e.target.action;
|
||||||
|
const data = Array.from(e.target.elements)
|
||||||
|
.filter((input) => input.name)
|
||||||
|
.reduce((obj, input) => Object.assign(obj, { [input.name]: input.value }), {});
|
||||||
|
|
||||||
|
fetch(finalFormEndpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(response.statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
setStatus('success');
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setMessage(err.toString());
|
||||||
|
setStatus('error');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (status === "success") {
|
||||||
|
toast.success("Cek email anda untuk petunjuk ganti password")
|
||||||
|
}
|
||||||
|
else if (status === "error") {
|
||||||
|
toast.error("Terjadi kesalahan");
|
||||||
|
console.log(message);
|
||||||
|
}
|
||||||
|
}, [status, message]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
action={FORM_ENDPOINT}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
method="POST"
|
||||||
|
encType="application/x-www-form-urlencoded"
|
||||||
|
>
|
||||||
|
<input type="text" name="email" className="form-input" id="email" placeholder="email"/>
|
||||||
|
<button className="forgot-button" type="submit">Kirimkan</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ForgotPasswordForm;
|
||||||
9
IrrigationReport/src/components/LoadingPopUp.jsx
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import './loading.css';
|
||||||
|
|
||||||
|
export default function LoadingPopUp() {
|
||||||
|
return (
|
||||||
|
<div className="spinner-container">
|
||||||
|
<div className="loading-spinner"></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
14
IrrigationReport/src/components/LocateUser.jsx
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { useMap } from "react-leaflet";
|
||||||
|
|
||||||
|
export default function LocateUser({changeCoordinate}) {
|
||||||
|
const map = useMap();
|
||||||
|
map.attributionControl.setPrefix('');
|
||||||
|
map.locate({setView: true});
|
||||||
|
|
||||||
|
map.on('locationfound', function(e) {
|
||||||
|
const latitude = e.latitude;
|
||||||
|
const longitude = e.longitude;
|
||||||
|
changeCoordinate(latitude, longitude);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
79
IrrigationReport/src/components/LoginForm.jsx
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Cookies } from "react-cookie";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
|
const FORM_ENDPOINT = "https://laporirigasi.my.id/api/auth/login";
|
||||||
|
|
||||||
|
const LoginForm = ({changeIsLoading}) => {
|
||||||
|
const [status, setStatus] = useState('');
|
||||||
|
const cookies = new Cookies();
|
||||||
|
|
||||||
|
let navigate = useNavigate();
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
changeIsLoading(true);
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
setStatus('loading');
|
||||||
|
|
||||||
|
const finalFormEndpoint = e.target.action;
|
||||||
|
const data = Array.from(e.target.elements)
|
||||||
|
.filter((input) => input.name)
|
||||||
|
.reduce((obj, input) => Object.assign(obj, { [input.name]: input.value }), {});
|
||||||
|
|
||||||
|
fetch(finalFormEndpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(response.statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
cookies.set('user_session', data.data.jwtToken, { path: '/' })
|
||||||
|
setStatus('success');
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log("err = "+err);
|
||||||
|
toast.error("Terdapat email atau password yang salah");
|
||||||
|
setStatus('error');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (status === "success") {
|
||||||
|
changeIsLoading(false);
|
||||||
|
navigate("/laporkan");
|
||||||
|
} else if(status === "error") {
|
||||||
|
changeIsLoading(false);
|
||||||
|
toast.error()
|
||||||
|
}
|
||||||
|
}, [status, navigate]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
action={FORM_ENDPOINT}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
method="POST"
|
||||||
|
encType="multipart/form-data"
|
||||||
|
>
|
||||||
|
<input type="text" name="email" className="form-input" id="email" placeholder="email" required/>
|
||||||
|
<input type="password" name="password" className="form-input" id="password" placeholder="password" required/>
|
||||||
|
<div id="forgot-pwd">
|
||||||
|
<a href="/lupa-password">Lupa password?</a><br />
|
||||||
|
</div>
|
||||||
|
<button className="login-button" type="submit">Login</button><br />
|
||||||
|
<a href="/register" id="register-link">Belum punya akun? Klik untuk daftar</a>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoginForm;
|
||||||
39
IrrigationReport/src/components/Protected.jsx
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { Cookies } from "react-cookie";
|
||||||
|
import { Navigate, Outlet } from "react-router-dom";
|
||||||
|
import { toast } from "react-toastify";
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
import LoadingPopUp from "./LoadingPopUp";
|
||||||
|
|
||||||
|
export default function Protected() {
|
||||||
|
const [statusCode, setStatusCode] = useState("");
|
||||||
|
useEffect(() => {
|
||||||
|
const cookies = new Cookies();
|
||||||
|
fetch(`https://laporirigasi.my.id/api/check-valid-cookie`, {
|
||||||
|
headers: {Authorization: 'Bearer '+cookies.get('user_session')}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
setStatusCode(res.status);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
useEffect(()=>{
|
||||||
|
if(statusCode===403){
|
||||||
|
toast.error("Harap Login terlebih dahulu");
|
||||||
|
}
|
||||||
|
}, [statusCode])
|
||||||
|
if(statusCode===403){
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Navigate to="/login" />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
} else if(statusCode===200){
|
||||||
|
return <Outlet/>;
|
||||||
|
} else if(statusCode===500){
|
||||||
|
return <h1>500 Internal Server Error</h1>
|
||||||
|
} else if(statusCode===""){
|
||||||
|
return <LoadingPopUp/>
|
||||||
|
}else{
|
||||||
|
return <h1>Terdapat error dengan status code: {statusCode}</h1>
|
||||||
|
}
|
||||||
|
}
|
||||||
78
IrrigationReport/src/components/RegisterForm.jsx
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
|
||||||
|
const FORM_ENDPOINT = "https://laporirigasi.my.id/api/auth/register";
|
||||||
|
|
||||||
|
const RegisterForm = () => {
|
||||||
|
const [status, setStatus] = useState('');
|
||||||
|
const [message, setMessage] = useState('');
|
||||||
|
|
||||||
|
let navigate = useNavigate();
|
||||||
|
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
setStatus('loading');
|
||||||
|
setMessage('');
|
||||||
|
|
||||||
|
const finalFormEndpoint = e.target.action;
|
||||||
|
const data = Array.from(e.target.elements)
|
||||||
|
.filter((input) => input.name)
|
||||||
|
.reduce((obj, input) => Object.assign(obj, { [input.name]: input.value }), {});
|
||||||
|
|
||||||
|
fetch(finalFormEndpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(response.statusText);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
setStatus('success');
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
setMessage(err.toString());
|
||||||
|
setStatus('error');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (status === "success") {
|
||||||
|
navigate("/login");
|
||||||
|
}
|
||||||
|
}, [status, navigate]);
|
||||||
|
|
||||||
|
if (status === "error") {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div>Something bad happened!</div>
|
||||||
|
<div>{message}</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
action={FORM_ENDPOINT}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
method="POST"
|
||||||
|
encType="multipart/form-data"
|
||||||
|
>
|
||||||
|
<input type="text" name="username" className="r-form-input" id="register-username" placeholder="Username" required /><br></br>
|
||||||
|
<input type="text" name="email" className="r-form-input" id="register-email" placeholder="Email" required /><br></br>
|
||||||
|
<input type="password" name="password" className="r-form-input" id="register-password" placeholder="Password" required /><br></br>
|
||||||
|
<input type="text" name="fullname" className="r-form-input" id="register-fullname" placeholder="Nama Lengkap" required /><br></br>
|
||||||
|
<input type="hidden" name="urole_id" value={"1d3c9d35-3d02-4b42-ad44-b75ca8c4e4fa"}/><br></br>
|
||||||
|
<button className="register-button">Register</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RegisterForm;
|
||||||
52
IrrigationReport/src/components/ReportForm1.jsx
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import useForm from "./UseForm";
|
||||||
|
|
||||||
|
const FORM_ENDPOINT = "https://laporirigasi.my.id/api/report";
|
||||||
|
|
||||||
|
const ReportForm1 = ({count, segmentId1, level1, image1, changeCount, changeImage1, changeLevel1, changeNote1}) => {
|
||||||
|
const { handleSubmit } = useForm({
|
||||||
|
changeCount
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleImage(e) {
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(image) {
|
||||||
|
changeImage1(image.target.result);
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(e.target.files[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<form
|
||||||
|
action={FORM_ENDPOINT}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
method="POST"
|
||||||
|
encType="multipart/form-data"
|
||||||
|
>
|
||||||
|
<h3 className="h-info">Informasi Laporan 1</h3>
|
||||||
|
<h6 className="h-irrigation-photo">Foto Irigasi yang Rusak</h6>
|
||||||
|
<input type="hidden" name="segment_id1" value={segmentId1}></input>
|
||||||
|
<input type="file" className="r-img" accept="image/*" title="Pilih file" onChange={(e)=>handleImage(e)} required></input>
|
||||||
|
<input type="hidden" name="image1" value={image1}></input>
|
||||||
|
<h6 className="h-irrigation-dmg">Tingkat Kerusakan Irigasi</h6>
|
||||||
|
<input type="radio" name="level1" value="Ringan" onChange={e => changeLevel1(e.target.value)} required></input>
|
||||||
|
<label htmlFor="html" id="dmg-radio">ringan</label>
|
||||||
|
<input type="radio" name="level1" value="Sedang" onChange={e => changeLevel1(e.target.value)} required></input>
|
||||||
|
<label htmlFor="css" id="dmg-radio">sedang</label>
|
||||||
|
<input type="radio" name="level1" value="Berat" onChange={e => changeLevel1(e.target.value)} required></input>
|
||||||
|
<label htmlFor="parah" id="dmg-radio">berat</label>
|
||||||
|
<input type="hidden" name="level1" value={level1}></input>
|
||||||
|
<h6 className="h-ad-info">Keterangan Tambahan</h6>
|
||||||
|
<textarea className="ad-info" name="note1" rows="5" onChange={e => changeNote1(e.target.value)}></textarea>
|
||||||
|
<div className="div-submit-report">
|
||||||
|
<button className="submit-report" type="submit">Kumpulkan Laporan</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div className="div-report-other">
|
||||||
|
<button className="report-other" onClick={() => {changeCount(count+1);}}>Laporkan lainnya</button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReportForm1;
|
||||||
52
IrrigationReport/src/components/ReportForm2.jsx
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
import useForm from "./UseForm";
|
||||||
|
|
||||||
|
const FORM_ENDPOINT = "https://laporirigasi.my.id/api/report";
|
||||||
|
|
||||||
|
const ReportForm2 = ({segmentId, count, changeCount, segmentId1, level1, note1, image1, level2, image2, changeImage2, changeLevel2, changeNote2}) => {
|
||||||
|
const { handleSubmit } = useForm({
|
||||||
|
changeCount
|
||||||
|
});
|
||||||
|
function handleImage(e) {
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(image) {
|
||||||
|
changeImage2(image.target.result);
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(e.target.files[0]);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
action={FORM_ENDPOINT}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
method="POST"
|
||||||
|
encType="multipart/form-data"
|
||||||
|
>
|
||||||
|
<h3 className="h-info">Informasi Laporan 2</h3>
|
||||||
|
<h6 className="h-irrigation-photo">Foto Irigasi yang Rusak</h6>
|
||||||
|
<input type="hidden" name="segment_id1" value={segmentId1}></input>
|
||||||
|
<input type="hidden" name="level1" value={level1}></input>
|
||||||
|
<input type="hidden" name="note1" value={note1}></input>
|
||||||
|
<input type="hidden" name="image1" value={image1}></input>
|
||||||
|
<input type="hidden" name="segment_id2" value={segmentId}></input>
|
||||||
|
<input type="file" className="r-img" accept="image/*" onChange={(e)=>handleImage(e)} required></input>
|
||||||
|
<input type="hidden" name="image2" value={image2}></input>
|
||||||
|
<h6 className="h-irrigation-dmg">Tingkat Kerusakan Irigasi</h6>
|
||||||
|
<input type="radio" name="level2" value="Ringan" onChange={e => changeLevel2(e.target.value)} required></input>
|
||||||
|
<label htmlFor="html" id="dmg-radio">ringan</label>
|
||||||
|
<input type="radio" name="level2" value="Sedang" onChange={e => changeLevel2(e.target.value)} required></input>
|
||||||
|
<label htmlFor="css" id="dmg-radio">sedang</label>
|
||||||
|
<input type="radio" name="level2" value="Berat" onChange={e => changeLevel2(e.target.value)} required></input>
|
||||||
|
<label htmlFor="parah" id="dmg-radio">berat</label>
|
||||||
|
<input type="hidden" name="level2" value={level2}></input>
|
||||||
|
<h6 className="h-ad-info">Keterangan Tambahan</h6>
|
||||||
|
<textarea className="ad-info" name="note2" rows="5" onChange={e => changeNote2(e.target.value)}></textarea>
|
||||||
|
<div className="div-submit-report">
|
||||||
|
<button className="submit-report" type="submit">Kumpulkan Laporan</button>
|
||||||
|
</div>
|
||||||
|
<div className="div-report-other">
|
||||||
|
<button className="report-other" onClick={() => {changeCount(count+1);}}>Laporkan lainnya</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReportForm2;
|
||||||
56
IrrigationReport/src/components/ReportForm3.jsx
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
import useForm from "./UseForm";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
const FORM_ENDPOINT = "https://laporirigasi.my.id/api/report";
|
||||||
|
|
||||||
|
const ReportForm3 = ({segmentId, changeCount, segmentId1, image1, level1, note1, segmentId2, image2, level2, note2, image3, changeImage3}) => {
|
||||||
|
const { handleSubmit } = useForm({
|
||||||
|
changeCount
|
||||||
|
});
|
||||||
|
function handleImage(e) {
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(image) {
|
||||||
|
changeImage3(image.target.result);
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(e.target.files[0]);
|
||||||
|
}
|
||||||
|
const [level3, setLevel3] = useState("");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form
|
||||||
|
action={FORM_ENDPOINT}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
method="POST"
|
||||||
|
encType="multipart/form-data"
|
||||||
|
>
|
||||||
|
<h3 className="h-info">Informasi Laporan 3</h3>
|
||||||
|
<h6 className="h-irrigation-photo">Foto Irigasi yang Rusak</h6>
|
||||||
|
<input type="hidden" name="segment_id1" value={segmentId1}></input>
|
||||||
|
<input type="hidden" name="image1" value={image1}></input>
|
||||||
|
<input type="hidden" name="level1" value={level1}></input>
|
||||||
|
<input type="hidden" name="note1" value={note1}></input>
|
||||||
|
<input type="hidden" name="segment_id2" value={segmentId2}></input>
|
||||||
|
<input type="hidden" name="image2" value={image2}></input>
|
||||||
|
<input type="hidden" name="level2" value={level2}></input>
|
||||||
|
<input type="hidden" name="note2" value={note2}></input>
|
||||||
|
<input type="hidden" name="segment_id3" value={segmentId}></input>
|
||||||
|
<input type="file" className="r-img" accept="image/*" onChange={(e)=>handleImage(e)} required></input>
|
||||||
|
<input type="hidden" name="image3" value={image3}></input>
|
||||||
|
<h6 className="h-irrigation-dmg">Tingkat Kerusakan Irigasi</h6>
|
||||||
|
<input type="radio" name="level3" value="Ringan" onChange={e => setLevel3(e.target.value)} required></input>
|
||||||
|
<label htmlFor="html" id="dmg-radio">ringan</label>
|
||||||
|
<input type="radio" name="level3" value="Sedang" onChange={e => setLevel3(e.target.value)} required></input>
|
||||||
|
<label htmlFor="css" id="dmg-radio">sedang</label>
|
||||||
|
<input type="radio" name="level3" value="Berat" onChange={e => setLevel3(e.target.value)} required></input>
|
||||||
|
<label htmlFor="parah" id="dmg-radio">berat</label>
|
||||||
|
<input type="hidden" name="level3" value={level3}></input>
|
||||||
|
<h6 className="h-ad-info">Keterangan Tambahan</h6>
|
||||||
|
<textarea className="ad-info" name="note3" rows="5"></textarea>
|
||||||
|
<div className="div-submit-report">
|
||||||
|
<button className="submit-report" type="submit">Kumpulkan Laporan</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReportForm3;
|
||||||
24
IrrigationReport/src/components/ReportForms.jsx
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import ReportForm1 from "./ReportForm1";
|
||||||
|
import ReportForm2 from "./ReportForm2";
|
||||||
|
import ReportForm3 from "./ReportForm3";
|
||||||
|
|
||||||
|
export default function ReportForms({segmentId, count, changeCount, segmentId1, image1, level1, note1, changeSegmentId1, changeImage1, changeLevel1, changeNote1, segmentId2, image2, level2, note2, changeSegmentId2, changeImage2, changeLevel2, changeNote2, image3, changeImage3}) {
|
||||||
|
useEffect(() => {
|
||||||
|
if (count === 1) {
|
||||||
|
changeSegmentId1(segmentId);
|
||||||
|
} else if(count === 2) {
|
||||||
|
changeSegmentId2(segmentId);
|
||||||
|
}
|
||||||
|
}, [segmentId, count, changeSegmentId1, changeSegmentId2]);
|
||||||
|
if(count===1) {
|
||||||
|
// console.log("segmentId1 = "+segmentId1);
|
||||||
|
return <ReportForm1 segmentId1={segmentId1} changeImage1={changeImage1} changeLevel1={changeLevel1} changeNote1={changeNote1} count={count} changeCount={changeCount} level1={level1} image1={image1}/>
|
||||||
|
} else if(count===2) {
|
||||||
|
console.log("segmentId2 = "+segmentId2);
|
||||||
|
return <ReportForm2 segmentId={segmentId} count={count} changeCount={changeCount} segmentId1={segmentId1} image1={image1} level1={level1} note1={note1} level2={level2} image2={image2} changeImage2={changeImage2} changeLevel2={changeLevel2} changeNote2={changeNote2}/>
|
||||||
|
} else if(count===3) {
|
||||||
|
console.log("segmentId3 = "+segmentId);
|
||||||
|
return <ReportForm3 segmentId={segmentId} changeCount={changeCount} segmentId1={segmentId1} image1={image1} level1={level1} note1={note1} segmentId2={segmentId2} image2={image2} level2={level2} note2={note2} image3={image3} changeImage3={changeImage3}/>
|
||||||
|
}
|
||||||
|
}
|
||||||
9
IrrigationReport/src/components/TopNavBar.jsx
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
export default function TopNavBar() {
|
||||||
|
return(
|
||||||
|
<nav className="navbar navbar-light" style={{backgroundColor: '#B57EFB'}}>
|
||||||
|
<div className="container">
|
||||||
|
<h2 style={{color: 'white'}}>IrrigationReport</h2>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
)
|
||||||
|
}
|
||||||
43
IrrigationReport/src/components/UseForm.jsx
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
import { Cookies } from "react-cookie";
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
|
function useForm({ changeCount }) {
|
||||||
|
const handleSubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const id = toast.loading("Mohon tunggu sebentar...", {
|
||||||
|
position: "top-center"
|
||||||
|
});
|
||||||
|
|
||||||
|
const finalFormEndpoint = e.target.action;
|
||||||
|
const data = Array.from(e.target.elements)
|
||||||
|
.filter((input) => input.name)
|
||||||
|
.reduce((obj, input) => Object.assign(obj, { [input.name]: input.value }), {});
|
||||||
|
const cookies = new Cookies();
|
||||||
|
fetch(finalFormEndpoint, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Authorization: 'Bearer '+cookies.get('user_session')
|
||||||
|
},
|
||||||
|
body: JSON.stringify(data),
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(response.statusText);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
toast.update(id, { render: "Data Laporanmu Berhasil Terkirim", type: "success", isLoading: false, autoClose: 4000 });
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
toast.update(id, { render: "Data Laporanmu Gagal Terkirim", type: "error", isLoading: false, autoClose: 4000 });
|
||||||
|
console.log(err.toString());
|
||||||
|
});
|
||||||
|
changeCount(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
return { handleSubmit };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default useForm;
|
||||||
29
IrrigationReport/src/components/loading.css
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
.loading-spinner {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border: 8px solid #FFF;
|
||||||
|
border-bottom-color: #B57EFB;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: rotation 1s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes rotation {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.spinner-container {
|
||||||
|
display: grid;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
z-index: 2000;
|
||||||
|
position: fixed;
|
||||||
|
}
|
||||||
11
IrrigationReport/src/pages/ChangePassword.jsx
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import ChangePasswordForm from "../components/ChangePasswordForm";
|
||||||
|
|
||||||
|
export default function ChangePassword() {
|
||||||
|
return(
|
||||||
|
<div className="login-content">
|
||||||
|
<h1 className="forgot-header">Ganti Password</h1>
|
||||||
|
<p className="forgot-hint">Harap masukkan password anda yang baru</p>
|
||||||
|
<ChangePasswordForm/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
32
IrrigationReport/src/pages/DetailRiwayat.css
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
.report_detail {
|
||||||
|
width: 60%;
|
||||||
|
height: 7%;
|
||||||
|
margin: auto;
|
||||||
|
margin-top: 3.5%;
|
||||||
|
margin-bottom: 6%;
|
||||||
|
padding-top: 3.5%;
|
||||||
|
padding-bottom: 2%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
-moz-box-shadow: 0 0 3px #a4a3a3;
|
||||||
|
-webkit-box-shadow: 0 0 3px #a4a3a3;
|
||||||
|
box-shadow: 0 0 10px #a4a3a3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-data{
|
||||||
|
margin-left: 4%;
|
||||||
|
margin-right: 4%;
|
||||||
|
margin-bottom: 4%;
|
||||||
|
padding: 2%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
-moz-box-shadow: 0 0 3px #a4a3a3;
|
||||||
|
-webkit-box-shadow: 0 0 3px #a4a3a3;
|
||||||
|
box-shadow: 0 0 10px #a4a3a3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-point-link {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
107
IrrigationReport/src/pages/DetailRiwayat.jsx
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
import TopNavBar from "../components/TopNavBar";
|
||||||
|
import BottomBar from "../components/BottomBar";
|
||||||
|
import "./DetailRiwayat.css";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Cookies } from "react-cookie";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import LoadingPopUp from "../components/LoadingPopUp";
|
||||||
|
|
||||||
|
export default function DetailRiwayat() {
|
||||||
|
const [riwayat, setRiwayat] = useState([]);
|
||||||
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
let { id } = useParams();
|
||||||
|
let { segment } = useParams();
|
||||||
|
segment = parseInt(segment);
|
||||||
|
useEffect(() => {
|
||||||
|
const cookies = new Cookies();
|
||||||
|
fetch(`https://laporirigasi.my.id/api/report/${id}`, {
|
||||||
|
headers: {Authorization: 'Bearer '+cookies.get('user_session')}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
setRiwayat(data);
|
||||||
|
setIsLoading(false);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err.toString());
|
||||||
|
});
|
||||||
|
}, [id]);
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="page">
|
||||||
|
<TopNavBar/>
|
||||||
|
<div className="content">
|
||||||
|
<nav className="navbar">
|
||||||
|
<form className="container-fluid justify-content-around">
|
||||||
|
{riwayat.length===2?
|
||||||
|
<>
|
||||||
|
<Link to={`/detail-laporan/${id}/0`} className={"btn btn-outline-success me-2"+(segment===0?" active":"")} type="button">Lokasi 1</Link>
|
||||||
|
<Link to={`/detail-laporan/${id}/1`} className={"btn btn-outline-success me-2"+(segment===1?" active":"")} type="button">Lokasi 2</Link>
|
||||||
|
</>
|
||||||
|
:<></>}
|
||||||
|
{riwayat.length===3?
|
||||||
|
<>
|
||||||
|
<Link to={`/detail-laporan/${id}/0`} className={"btn btn-outline-success me-2"+(segment===0?" active":"")} type="button">Lokasi 1</Link>
|
||||||
|
<Link to={`/detail-laporan/${id}/1`} className={"btn btn-outline-success me-2"+(segment===1?" active":"")} type="button">Lokasi 2</Link>
|
||||||
|
<Link to={`/detail-laporan/${id}/2`} className={"btn btn-outline-success me-2"+(segment===2?" active":"")} type="button">Lokasi 3</Link>
|
||||||
|
</>
|
||||||
|
:<></>}
|
||||||
|
</form>
|
||||||
|
</nav>
|
||||||
|
{riwayat.length>0?
|
||||||
|
<>
|
||||||
|
<div className="report_detail">
|
||||||
|
<h1>Detail Laporan</h1>
|
||||||
|
</div>
|
||||||
|
<div className="report-data">
|
||||||
|
<h4>Nama Irigasi:</h4>
|
||||||
|
<h4>{riwayat[segment].irrigation}</h4>
|
||||||
|
</div>
|
||||||
|
<div className="report-data">
|
||||||
|
<h4>Saluran:</h4>
|
||||||
|
<h4>{riwayat[segment].canal}</h4>
|
||||||
|
</div>
|
||||||
|
<div className="report-data">
|
||||||
|
<h4>Status:</h4>
|
||||||
|
<h4>{riwayat[segment].status}</h4>
|
||||||
|
</div>
|
||||||
|
<div className="report-data">
|
||||||
|
<h4>Tingkat Kerusakan:</h4>
|
||||||
|
<h4>{riwayat[segment].level}</h4>
|
||||||
|
</div>
|
||||||
|
<div className="report-data">
|
||||||
|
<h4>Keterangan:</h4>
|
||||||
|
<h4>{riwayat[segment].note}</h4>
|
||||||
|
</div>
|
||||||
|
<div className="report-data">
|
||||||
|
<h4>Foto: </h4>
|
||||||
|
<img src={riwayat[segment].image} width="60%" alt="Foto Irigasi yang Rusak" />
|
||||||
|
</div>
|
||||||
|
<div className="report-data">
|
||||||
|
<h4>Tanggal dan Waktu Lapor: </h4>
|
||||||
|
<h4>{riwayat[segment].created_at}</h4>
|
||||||
|
</div>
|
||||||
|
{riwayat[segment].done_at?
|
||||||
|
<div className="report-data">
|
||||||
|
<h4>Tanggal Selesai: </h4>
|
||||||
|
<h4>{riwayat[segment].done_at}</h4>
|
||||||
|
</div>:<></>}
|
||||||
|
<div className="report-data">
|
||||||
|
<h4>Titik Tengah Lokasi: </h4>
|
||||||
|
<a className="center-point-link" href={`https://www.google.com/maps/place/${JSON.parse(riwayat[segment].center_point_json)[1]},${JSON.parse(riwayat[segment].center_point_json)[0]}?entry=ttu`}>Lihat di Google Maps</a>
|
||||||
|
</div>
|
||||||
|
</>:<></>}
|
||||||
|
</div>
|
||||||
|
{ isLoading ?
|
||||||
|
<>
|
||||||
|
<LoadingPopUp/>
|
||||||
|
</>
|
||||||
|
:<></>
|
||||||
|
}
|
||||||
|
<BottomBar activeIcon={"riwayat"}/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
46
IrrigationReport/src/pages/EditProfil.css
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
.e-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.e-i-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.e-header {
|
||||||
|
padding-top: 7%;
|
||||||
|
padding-bottom: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.e-p-form{
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 15%;
|
||||||
|
padding-left: 5%;
|
||||||
|
padding-right: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.e-p-form-input {
|
||||||
|
width: 100%;
|
||||||
|
height: 3rem;
|
||||||
|
border: 5px solid #E7E7E7;
|
||||||
|
border-radius: 17px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 4.7%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.e-div-btn {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.e-button {
|
||||||
|
background-color: #64A2FF;
|
||||||
|
color: white;
|
||||||
|
width: 40%;
|
||||||
|
height: 2.5rem;
|
||||||
|
border-radius: 20px;
|
||||||
|
border: 0px;
|
||||||
|
margin-bottom: 0.8rem;
|
||||||
|
}
|
||||||
19
IrrigationReport/src/pages/EditProfil.jsx
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
import TopNavBar from "../components/TopNavBar";
|
||||||
|
import BottomBar from "../components/BottomBar";
|
||||||
|
import "./EditProfil.css";
|
||||||
|
import EditProfilForm from "../components/EditProfilForm";
|
||||||
|
|
||||||
|
export default function EditProfil(){
|
||||||
|
return(
|
||||||
|
<div className="page">
|
||||||
|
<TopNavBar />
|
||||||
|
<div className="e-content">
|
||||||
|
<div className="e-i-content">
|
||||||
|
<h1 className="e-header">Ubah Data Diri</h1>
|
||||||
|
<EditProfilForm />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<BottomBar activeIcon={"profil"} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
17
IrrigationReport/src/pages/ForgotPassword.css
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
.forgot-header {
|
||||||
|
margin-bottom: 7%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot-hint {
|
||||||
|
margin-bottom: 15%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot-button {
|
||||||
|
background-color: #B57EFB;
|
||||||
|
color: white;
|
||||||
|
width: 32%;
|
||||||
|
height: 2.8rem;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 0px;
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
12
IrrigationReport/src/pages/ForgotPassword.jsx
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
import ForgotPasswordForm from "../components/ForgotPasswordForm";
|
||||||
|
import "./ForgotPassword.css";
|
||||||
|
|
||||||
|
export default function ForgotPassword() {
|
||||||
|
return(
|
||||||
|
<div className="login-content">
|
||||||
|
<h1 className="forgot-header">Lupa Password</h1>
|
||||||
|
<p className="forgot-hint">Harap masukkan email address anda untuk mendapatkan link untuk ganti password</p>
|
||||||
|
<ForgotPasswordForm/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
9
IrrigationReport/src/pages/Home.jsx
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
|
export default function Home() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
useEffect(()=>{
|
||||||
|
navigate("/laporkan");
|
||||||
|
}, [navigate]);
|
||||||
|
}
|
||||||
123
IrrigationReport/src/pages/Laporan.jsx
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
import {MapContainer, TileLayer, useMap} from 'react-leaflet';
|
||||||
|
import L from 'leaflet';
|
||||||
|
import TopNavBar from "../components/TopNavBar";
|
||||||
|
import BottomBar from "../components/BottomBar";
|
||||||
|
import LocateUser from '../components/LocateUser';
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { Cookies } from 'react-cookie';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
|
||||||
|
export default function Laporan(){
|
||||||
|
const [latitude, setLatitude] = useState("");
|
||||||
|
const [longitude, setLongitude] = useState("");
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [isPopUpActive, setPopUpActive] = useState(false);
|
||||||
|
const [segments, setSegments] = useState([]);
|
||||||
|
const [segment, setSegment] = useState();
|
||||||
|
|
||||||
|
function showPopUp() {
|
||||||
|
setPopUpActive(true);
|
||||||
|
}
|
||||||
|
function hidePopUp() {
|
||||||
|
setPopUpActive(false);
|
||||||
|
}
|
||||||
|
function changeSegments(data) {
|
||||||
|
setSegments(data);
|
||||||
|
changeIsLoading(false);
|
||||||
|
}
|
||||||
|
function changeSegment(data) {
|
||||||
|
setSegment(data);
|
||||||
|
}
|
||||||
|
function changeCoordinate(latitude, longitude) {
|
||||||
|
setLatitude(latitude);
|
||||||
|
setLongitude(longitude);
|
||||||
|
}
|
||||||
|
function changeIsLoading(value) {
|
||||||
|
if(isLoading!=value){
|
||||||
|
setIsLoading(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(
|
||||||
|
<div className="page">
|
||||||
|
<TopNavBar />
|
||||||
|
<div className="leaflet-container">
|
||||||
|
<MapContainer
|
||||||
|
center={[-7.87074500384173, 112.52647830035404]}
|
||||||
|
minZoom={19}
|
||||||
|
maxZoom={22}
|
||||||
|
scrollWheelZoom={true}>
|
||||||
|
<TileLayer
|
||||||
|
url="http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}"
|
||||||
|
maxZoom={22}
|
||||||
|
subdomains={['mt0','mt1','mt2','mt3']}
|
||||||
|
/>
|
||||||
|
<LocateUser changeCoordinate={changeCoordinate}/>
|
||||||
|
<Segments segments={segments} latitude={latitude} longitude={longitude} showPopUp={showPopUp} changeSegments={changeSegments} changeSegment={changeSegment} changeIsLoading={changeIsLoading}/>
|
||||||
|
</MapContainer>
|
||||||
|
</div>
|
||||||
|
{isPopUpActive?<ShowPopUp segment={segment} hidePopUp={hidePopUp}/>:<></>}
|
||||||
|
<BottomBar activeIcon={"laporan"}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Segments({segments, showPopUp, latitude, longitude, changeIsLoading, changeSegments, changeSegment}) {
|
||||||
|
const map = useMap();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
changeIsLoading(true);
|
||||||
|
const cookies = new Cookies();
|
||||||
|
fetch('https://laporirigasi.my.id/api/segments-by-user-id?' + new URLSearchParams({
|
||||||
|
lat: `${latitude}`,
|
||||||
|
long: `${longitude}`,
|
||||||
|
}), {
|
||||||
|
headers: {Authorization: 'Bearer '+cookies.get('user_session')}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
changeSegments(data);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
changeIsLoading(false);
|
||||||
|
toast.error("Gagal mengambil data");
|
||||||
|
console.log(err.toString());
|
||||||
|
});
|
||||||
|
}, [latitude, longitude]);
|
||||||
|
|
||||||
|
segments.map((segment) => {
|
||||||
|
const geojson = JSON.parse(segment.geojson)
|
||||||
|
var pointA = new L.LatLng(geojson.coordinates[0][1], geojson.coordinates[0][0]);
|
||||||
|
var pointB = new L.LatLng(geojson.coordinates[1][1], geojson.coordinates[1][0]);
|
||||||
|
var pointList = [pointA, pointB];
|
||||||
|
|
||||||
|
var segmentLine = new L.Polyline(pointList, {
|
||||||
|
color: 'blue',
|
||||||
|
weight: 6,
|
||||||
|
opacity: 1,
|
||||||
|
smoothFactor: 1,
|
||||||
|
className: 'segment-line'
|
||||||
|
});
|
||||||
|
segmentLine.on("click", function() {
|
||||||
|
changeSegment(segment);
|
||||||
|
showPopUp();
|
||||||
|
})
|
||||||
|
segmentLine.addTo(map);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function ShowPopUp({segment, hidePopUp}) {
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<div className="popup-bg" onClick={() => hidePopUp()}>
|
||||||
|
</div>
|
||||||
|
<div className="popup">
|
||||||
|
<h3 className="h-info">Informasi Laporan</h3>
|
||||||
|
<h5>Nama Irigasi: {segment.irrigation}</h5>
|
||||||
|
<h5>Saluran: {segment.canal}</h5>
|
||||||
|
<h5>Status: {segment.status}</h5>
|
||||||
|
<h5>Tingkat Kerusakan: {segment.level}</h5>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
160
IrrigationReport/src/pages/Laporkan.css
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
.h-info {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.segment-line {
|
||||||
|
filter: drop-shadow(1px 1px 0 #00ff0d) drop-shadow(-1px -1px 0 #00ff0d) drop-shadow(1px -1px 0 #00ff0d) drop-shadow(-1px 1px 0 #00ff0d);
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-bg {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 2000;
|
||||||
|
background-color: rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 2000;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
height: 500px;
|
||||||
|
width: 280px;
|
||||||
|
padding-top: 20px;
|
||||||
|
padding-left: 22px;
|
||||||
|
padding-right: 22px;
|
||||||
|
padding-bottom: 25px;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-irrigation-photo {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-irrigation-dmg {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dmg-radio {
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-ad-info {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ad-info {
|
||||||
|
border: 6px solid #E7E7E7;
|
||||||
|
border-radius: 15px;
|
||||||
|
width: 234px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div-submit-report {
|
||||||
|
margin-top: 13.5px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-report {
|
||||||
|
background-color: #64A2FF;
|
||||||
|
color: white;
|
||||||
|
width: 190px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 20px;
|
||||||
|
border: 0px;
|
||||||
|
margin-bottom: 12.8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div-report-other {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-other {
|
||||||
|
background-color: #a9a9a9;
|
||||||
|
color: white;
|
||||||
|
width: 190px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 20px;
|
||||||
|
border: 0px;
|
||||||
|
margin-bottom: 25.6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 640px) and (min-height: 750px) {
|
||||||
|
.popup {
|
||||||
|
height: 700px;
|
||||||
|
width: 480px;
|
||||||
|
padding-top: 27px;
|
||||||
|
padding-left: 60px;
|
||||||
|
padding-right: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-info {
|
||||||
|
font-size: 33px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-irrigation-photo {
|
||||||
|
margin-top: 40px;
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.r-img {
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-irrigation-dmg {
|
||||||
|
margin-top: 25px;
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#dmg-radio {
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 4px;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.h-ad-info {
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ad-info {
|
||||||
|
border: 6px solid #E7E7E7;
|
||||||
|
border-radius: 15px;
|
||||||
|
width: 334px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div-submit-report {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-report {
|
||||||
|
width: 290px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 25px;
|
||||||
|
margin-top: 20px;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.div-report-other {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-other {
|
||||||
|
width: 290px;
|
||||||
|
height: 60px;
|
||||||
|
border-radius: 25px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
font-size: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
187
IrrigationReport/src/pages/Laporkan.jsx
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
import {MapContainer, TileLayer, useMap} from 'react-leaflet'
|
||||||
|
import L from 'leaflet';
|
||||||
|
import TopNavBar from "../components/TopNavBar";
|
||||||
|
import BottomBar from "../components/BottomBar";
|
||||||
|
import LocateUser from '../components/LocateUser';
|
||||||
|
import ReportForms from '../components/ReportForms';
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import { Cookies } from 'react-cookie';
|
||||||
|
import "./Laporkan.css";
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
|
// import LoadingPopUp from '../components/LoadingPopUp';
|
||||||
|
|
||||||
|
export default function Laporkan() {
|
||||||
|
const [isPopUpActive, setPopUpActive] = useState(false);
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [segmentId, setSegmentId] = useState("0");
|
||||||
|
const [latitude, setLatitude] = useState("");
|
||||||
|
const [longitude, setLongitude] = useState("");
|
||||||
|
const [count, setCount] = useState(1);
|
||||||
|
const [segmentId1, setSegmentId1] = useState("");
|
||||||
|
const [image1, setImage1] = useState("");
|
||||||
|
const [level1, setLevel1] = useState("");
|
||||||
|
const [note1, setNote1] = useState("");
|
||||||
|
const [segmentId2, setSegmentId2] = useState("");
|
||||||
|
const [image2, setImage2] = useState("");
|
||||||
|
const [level2, setLevel2] = useState("");
|
||||||
|
const [note2, setNote2] = useState("");
|
||||||
|
const [image3, setImage3] = useState("");
|
||||||
|
|
||||||
|
function changeCoordinate(lat, long) {
|
||||||
|
if(latitude===""){
|
||||||
|
setLatitude(lat);
|
||||||
|
setLongitude(long);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function inputSegmentId(id) {
|
||||||
|
setSegmentId(id);
|
||||||
|
}
|
||||||
|
function showPopUp() {
|
||||||
|
setPopUpActive(true);
|
||||||
|
}
|
||||||
|
function changeCount(num) {
|
||||||
|
setCount(num)
|
||||||
|
if(num===4){
|
||||||
|
setCount(1);
|
||||||
|
}
|
||||||
|
hidePopUp();
|
||||||
|
}
|
||||||
|
function changeSegmentId1(value) {
|
||||||
|
setSegmentId1(value);
|
||||||
|
}
|
||||||
|
function changeImage1(value) {
|
||||||
|
setImage1(value);
|
||||||
|
}
|
||||||
|
function changeLevel1(value) {
|
||||||
|
setLevel1(value);
|
||||||
|
}
|
||||||
|
function changeNote1(value) {
|
||||||
|
setNote1(value);
|
||||||
|
}
|
||||||
|
function changeSegmentId2(value) {
|
||||||
|
setSegmentId2(value);
|
||||||
|
}
|
||||||
|
function changeImage2(value) {
|
||||||
|
setImage2(value);
|
||||||
|
}
|
||||||
|
function changeLevel2(value) {
|
||||||
|
setLevel2(value);
|
||||||
|
}
|
||||||
|
function changeNote2(value) {
|
||||||
|
setNote2(value);
|
||||||
|
}
|
||||||
|
function changeImage3(value) {
|
||||||
|
setImage3(value);
|
||||||
|
}
|
||||||
|
function hidePopUp() {
|
||||||
|
setPopUpActive(false);
|
||||||
|
}
|
||||||
|
function changeIsLoading(value) {
|
||||||
|
if(isLoading!=value){
|
||||||
|
setIsLoading(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
useEffect(()=>{
|
||||||
|
toast.info("Klik garis pendek, letak irigasi yang rusak")
|
||||||
|
}, [])
|
||||||
|
return (
|
||||||
|
<div className="page">
|
||||||
|
<TopNavBar />
|
||||||
|
<div className="leaflet-container">
|
||||||
|
<MapContainer
|
||||||
|
center={[-7.902260521, 112.557507431]}
|
||||||
|
minZoom={19}
|
||||||
|
maxZoom={22}
|
||||||
|
zoom={19}
|
||||||
|
scrollWheelZoom={true}>
|
||||||
|
<TileLayer
|
||||||
|
url="http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}"
|
||||||
|
maxZoom={22}
|
||||||
|
subdomains={['mt0','mt1','mt2','mt3']}
|
||||||
|
/>
|
||||||
|
<LocateUser changeCoordinate={changeCoordinate}/>
|
||||||
|
<Segments showPopUp={showPopUp} inputSegmentId={inputSegmentId} latitude={latitude} longitude={longitude} changeIsLoading={changeIsLoading}/>
|
||||||
|
</MapContainer>
|
||||||
|
</div>
|
||||||
|
{ isPopUpActive ?
|
||||||
|
<>
|
||||||
|
<div className="popup-bg" onClick={() => hidePopUp()}>
|
||||||
|
</div>
|
||||||
|
<div className="popup">
|
||||||
|
<ReportForms
|
||||||
|
segmentId={segmentId} count={count} changeCount={changeCount}
|
||||||
|
segmentId1={segmentId1} image1={image1} level1={level1} note1={note1}
|
||||||
|
changeSegmentId1={changeSegmentId1} changeImage1={changeImage1} changeLevel1={changeLevel1} changeNote1={changeNote1}
|
||||||
|
segmentId2={segmentId2} image2={image2} level2={level2} note2={note2}
|
||||||
|
changeSegmentId2={changeSegmentId2} changeImage2={changeImage2} changeLevel2={changeLevel2} changeNote2={changeNote2}
|
||||||
|
image3={image3} changeImage3={changeImage3}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
: <></>
|
||||||
|
}
|
||||||
|
{ isLoading ?
|
||||||
|
<>
|
||||||
|
{/*<LoadingPopUp/>*/}
|
||||||
|
</>
|
||||||
|
:<></>
|
||||||
|
}
|
||||||
|
<BottomBar activeIcon={"laporkan"}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Segments({showPopUp, inputSegmentId, latitude, longitude, changeIsLoading}) {
|
||||||
|
const map = useMap();
|
||||||
|
const [segments, setSegments] = useState([]);
|
||||||
|
|
||||||
|
function changeSegments(data) {
|
||||||
|
setSegments(data);
|
||||||
|
changeIsLoading(false);
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
changeIsLoading(true);
|
||||||
|
const cookies = new Cookies();
|
||||||
|
fetch('https://laporirigasi.my.id/api/close-segments?' + new URLSearchParams({
|
||||||
|
lat: `${latitude}`,
|
||||||
|
long: `${longitude}`,
|
||||||
|
}), {
|
||||||
|
headers: {Authorization: 'Bearer '+cookies.get('user_session')}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
changeSegments(data);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
changeIsLoading(false);
|
||||||
|
toast.error("Gagal mengambil data");
|
||||||
|
console.log(err.toString());
|
||||||
|
});
|
||||||
|
}, [latitude, longitude]);
|
||||||
|
|
||||||
|
useEffect(()=>{
|
||||||
|
segments.map((segment) => {
|
||||||
|
const geojson = JSON.parse(segment.geojson)
|
||||||
|
var pointA = new L.LatLng(geojson.coordinates[0][1], geojson.coordinates[0][0]);
|
||||||
|
var pointB = new L.LatLng(geojson.coordinates[1][1], geojson.coordinates[1][0]);
|
||||||
|
var pointList = [pointA, pointB];
|
||||||
|
|
||||||
|
var segmentLine = new L.Polyline(pointList, {
|
||||||
|
color: 'blue',
|
||||||
|
weight: 6,
|
||||||
|
opacity: 1,
|
||||||
|
smoothFactor: 1,
|
||||||
|
className: 'segment-line'
|
||||||
|
});
|
||||||
|
segmentLine.on("click", function() {
|
||||||
|
inputSegmentId(segment.id);
|
||||||
|
showPopUp();
|
||||||
|
});
|
||||||
|
segmentLine.addTo(map);
|
||||||
|
})
|
||||||
|
map.setZoom(19);
|
||||||
|
}, [segments])
|
||||||
|
}
|
||||||
47
IrrigationReport/src/pages/Login.css
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
.login-content {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
text-align: center;
|
||||||
|
width: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-header{
|
||||||
|
margin-bottom: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input {
|
||||||
|
width: 100%;
|
||||||
|
height: 3rem;
|
||||||
|
border: 5px solid #E7E7E7;
|
||||||
|
border-radius: 17px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#email {
|
||||||
|
margin-bottom: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#forgot-pwd{
|
||||||
|
text-align: right;
|
||||||
|
margin-bottom: 1.6rem;
|
||||||
|
margin-right: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login-button {
|
||||||
|
background-color: #B57EFB;
|
||||||
|
color: white;
|
||||||
|
width: 32%;
|
||||||
|
height: 2.2rem;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 0px;
|
||||||
|
margin-bottom: 1.6rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 640px) {
|
||||||
|
.login-button {
|
||||||
|
height: 3rem;
|
||||||
|
font-size: 23px;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
IrrigationReport/src/pages/Login.jsx
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import './Login.css';
|
||||||
|
import LoginForm from '../components/LoginForm';
|
||||||
|
import LoadingPopUp from '../components/LoadingPopUp';
|
||||||
|
import { useState } from 'react';
|
||||||
|
|
||||||
|
export default function Login() {
|
||||||
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
function changeIsLoading(isLoad){
|
||||||
|
setIsLoading(isLoad);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
{isLoading?<LoadingPopUp/>:<></>}
|
||||||
|
<div className="login-content">
|
||||||
|
<h1 className="login-header">Login</h1>
|
||||||
|
<LoginForm changeIsLoading={changeIsLoading}/>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
59
IrrigationReport/src/pages/Profil.css
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
.photo-profile {
|
||||||
|
height: 37%;
|
||||||
|
width: auto;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pp-img {
|
||||||
|
height: 7rem;
|
||||||
|
width: 7rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-data {
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
margin-top: 3%;
|
||||||
|
margin-bottom: 2%;
|
||||||
|
width: 98%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pencil-button {
|
||||||
|
background-color: white;
|
||||||
|
padding: 0.3rem;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 3px solid #B1B1B1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout {
|
||||||
|
width: 98%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout-button{
|
||||||
|
background-color: white;
|
||||||
|
color: #FF5D5D;
|
||||||
|
padding-left: 25px;
|
||||||
|
padding-right: 25px;
|
||||||
|
padding-bottom: 7px;
|
||||||
|
padding-top: 7px;
|
||||||
|
border: 3px solid #FF5D5D;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-data {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-left: 3%;
|
||||||
|
padding-right: 3%;
|
||||||
|
border: 2.5px solid #949494;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-container {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 15%;
|
||||||
|
}
|
||||||
92
IrrigationReport/src/pages/Profil.jsx
Normal file
|
|
@ -0,0 +1,92 @@
|
||||||
|
import TopNavBar from "../components/TopNavBar";
|
||||||
|
import BottomBar from "../components/BottomBar";
|
||||||
|
import "./Profil.css";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Cookies } from "react-cookie";
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import LoadingPopUp from '../components/LoadingPopUp';
|
||||||
|
|
||||||
|
export default function Profil(){
|
||||||
|
const [profil, setProfil] = useState([]);
|
||||||
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
let navigate = useNavigate();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const cookies = new Cookies();
|
||||||
|
fetch(`https://laporirigasi.my.id/api/profile`, {
|
||||||
|
headers: {Authorization: 'Bearer '+cookies.get('user_session')}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
setProfil(data);
|
||||||
|
setIsLoading(false);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
function logout() {
|
||||||
|
setIsLoading(true);
|
||||||
|
const cookies = new Cookies();
|
||||||
|
fetch('https://laporirigasi.my.id/api/auth/logout', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Authorization: 'Bearer '+cookies.get('user_session')
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(response.statusText);
|
||||||
|
}
|
||||||
|
cookies.remove('user_session');
|
||||||
|
setIsLoading(false);
|
||||||
|
navigate("/login");
|
||||||
|
return null;
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
return err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function redirect() {
|
||||||
|
navigate("/edit-profil")
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="page">
|
||||||
|
<TopNavBar />
|
||||||
|
<div className="content">
|
||||||
|
<div className="photo-profile">
|
||||||
|
<img className="pp-img" src={profil.avatar} alt="Photo Profile" />
|
||||||
|
</div>
|
||||||
|
<div className="logout">
|
||||||
|
<button className="logout-button" onClick={logout}><b>Logout</b></button>
|
||||||
|
</div>
|
||||||
|
<div className="edit-data">
|
||||||
|
<button className="pencil-button" onClick={redirect}>
|
||||||
|
<img src="/img/pencil-icon.png" width="35rem" alt="" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="profile-data">
|
||||||
|
<h5>Nama Lengkap:</h5>
|
||||||
|
<h5>{profil.fullname}</h5>
|
||||||
|
</div>
|
||||||
|
<div className="profile-data">
|
||||||
|
<h5>Email:</h5>
|
||||||
|
<h5>{profil.email}</h5>
|
||||||
|
</div>
|
||||||
|
<div className="profile-data">
|
||||||
|
<h5>Username:</h5>
|
||||||
|
<h5>{profil.username}</h5>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{ isLoading ?
|
||||||
|
<>
|
||||||
|
<LoadingPopUp/>
|
||||||
|
</>
|
||||||
|
:<></>
|
||||||
|
}
|
||||||
|
<BottomBar activeIcon={"profil"} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
50
IrrigationReport/src/pages/Register.css
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
.register-button {
|
||||||
|
background-color: #B57EFB;
|
||||||
|
color: white;
|
||||||
|
width: 92.16px;
|
||||||
|
height: 2.7rem;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 0px;
|
||||||
|
margin-top: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.r-form-input {
|
||||||
|
width: 290px;
|
||||||
|
height: 48px;
|
||||||
|
border: 5px solid #E7E7E7;
|
||||||
|
border-radius: 17px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#register-username {
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (min-width: 640px) {
|
||||||
|
.register-title {
|
||||||
|
font-size: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.register-button {
|
||||||
|
width: 150px;
|
||||||
|
height: 60px;
|
||||||
|
margin-top: 36px;
|
||||||
|
font-size: 25px;
|
||||||
|
border-radius: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.r-form-input {
|
||||||
|
width: 430px;
|
||||||
|
height: 68px;
|
||||||
|
border-radius: 26px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
font-size: 22px;
|
||||||
|
padding-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#register-username {
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
11
IrrigationReport/src/pages/Register.jsx
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
import "./Register.css"
|
||||||
|
import RegisterForm from "../components/RegisterForm";
|
||||||
|
|
||||||
|
export default function Register() {
|
||||||
|
return(
|
||||||
|
<div className="login-content">
|
||||||
|
<h1 className="register-title">Register</h1>
|
||||||
|
<RegisterForm />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
45
IrrigationReport/src/pages/Riwayat.css
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
.riwayat-box {
|
||||||
|
padding: 10px;
|
||||||
|
border: 6px solid #E7E7E7;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 2px;
|
||||||
|
border-color: #B0B0B0;
|
||||||
|
margin: 20px;
|
||||||
|
display: flex;
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-form {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-bar {
|
||||||
|
outline: none;
|
||||||
|
border-width: 0px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-bar::placeholder {
|
||||||
|
color: #B0B0B0;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bi-search, .bi-funnel {
|
||||||
|
font-size: 1.5em;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.b-search {
|
||||||
|
background-color: white;
|
||||||
|
border-width: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
border-width: 3px;
|
||||||
|
}
|
||||||
157
IrrigationReport/src/pages/Riwayat.jsx
Normal file
|
|
@ -0,0 +1,157 @@
|
||||||
|
import TopNavBar from "../components/TopNavBar";
|
||||||
|
import BottomBar from "../components/BottomBar";
|
||||||
|
import "./Riwayat.css"
|
||||||
|
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { Cookies } from "react-cookie";
|
||||||
|
import LoadingPopUp from "../components/LoadingPopUp";
|
||||||
|
import 'bootstrap-icons/font/bootstrap-icons.css';
|
||||||
|
import 'bootstrap/dist/js/bootstrap.min.js';
|
||||||
|
|
||||||
|
export default function Riwayat(){
|
||||||
|
const [riwayats, setRiwayats] = useState([]);
|
||||||
|
const [isLoading, setIsLoading] = useState(true);
|
||||||
|
const [searchParams, setSearchParams] = useSearchParams();
|
||||||
|
|
||||||
|
const search = searchParams.get("search");
|
||||||
|
const filter = searchParams.get("filter");
|
||||||
|
|
||||||
|
function handleSubmit(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const data = Array.from(e.target.elements)
|
||||||
|
.filter((input) => input.name)
|
||||||
|
.reduce((obj, input) => Object.assign(obj, { [input.name]: input.value }), {});
|
||||||
|
|
||||||
|
changeParams("search", data.search);
|
||||||
|
}
|
||||||
|
function changeParams(param, value) {
|
||||||
|
if(search!=null && filter!=null && param==="search"){
|
||||||
|
setSearchParams({ filter: filter, search: value });
|
||||||
|
}else if(search!=null){
|
||||||
|
if(param==="search"){
|
||||||
|
setSearchParams({ search: value });
|
||||||
|
}else if(param==="filter"){
|
||||||
|
setSearchParams({ search: search, filter: value });
|
||||||
|
}
|
||||||
|
} else if(filter!=null){
|
||||||
|
if(param==="filter"){
|
||||||
|
setSearchParams({ filter: value });
|
||||||
|
}else if(param==="search"){
|
||||||
|
setSearchParams({ filter: filter, search: value });
|
||||||
|
}
|
||||||
|
} else if(param==="search"){
|
||||||
|
setSearchParams({ search: value });
|
||||||
|
} else if(param==="filter"){
|
||||||
|
setSearchParams({ filter: value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
const cookies = new Cookies();
|
||||||
|
if(search!=null&&filter!=null){
|
||||||
|
setIsLoading(true);
|
||||||
|
fetch('https://laporirigasi.my.id/api/user-reports?' + new URLSearchParams({
|
||||||
|
search: `${search}`,
|
||||||
|
filter: `${filter}`
|
||||||
|
}), {
|
||||||
|
headers: {Authorization: 'Bearer '+cookies.get('user_session')}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
setRiwayats(data);
|
||||||
|
setIsLoading(false);
|
||||||
|
});
|
||||||
|
} else if(filter!=null){
|
||||||
|
setIsLoading(true);
|
||||||
|
fetch('https://laporirigasi.my.id/api/user-reports?' + new URLSearchParams({
|
||||||
|
filter: `${filter}`
|
||||||
|
}), {
|
||||||
|
headers: {Authorization: 'Bearer '+cookies.get('user_session')}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
setRiwayats(data);
|
||||||
|
setIsLoading(false);
|
||||||
|
});
|
||||||
|
}else if(search===null) {
|
||||||
|
setIsLoading(true);
|
||||||
|
fetch('https://laporirigasi.my.id/api/user-reports', {
|
||||||
|
headers: {Authorization: 'Bearer '+cookies.get('user_session')}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
setRiwayats(data);
|
||||||
|
setIsLoading(false);
|
||||||
|
});
|
||||||
|
}else if(search!=null) {
|
||||||
|
fetch('https://laporirigasi.my.id/api/user-reports?' + new URLSearchParams({
|
||||||
|
search: `${search}`
|
||||||
|
}), {
|
||||||
|
headers: {Authorization: 'Bearer '+cookies.get('user_session')}
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
setRiwayats(data);
|
||||||
|
setIsLoading(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [search, filter]);
|
||||||
|
|
||||||
|
let navigate = useNavigate();
|
||||||
|
|
||||||
|
function toDetailPage(id) {
|
||||||
|
console.log("In toDetailPage function");
|
||||||
|
navigate("/detail-laporan/"+id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(
|
||||||
|
<div className="page">
|
||||||
|
<TopNavBar />
|
||||||
|
<div className="content">
|
||||||
|
<div className="search-container">
|
||||||
|
<form onSubmit={handleSubmit} method="get" className="search-form">
|
||||||
|
<input type="text" name="search" id="search-bar" placeholder="Cari riwayat"/>
|
||||||
|
<button className="b-search" type="submit">
|
||||||
|
<i className="bi bi-search"></i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<div className="btn-group">
|
||||||
|
<button type="button" className="b-search btn" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
<i className="bi bi-funnel"></i>
|
||||||
|
</button>
|
||||||
|
<ul className="dropdown-menu">
|
||||||
|
<li className="dropdown-item" style={{backgroundColor: "#B57EFB", color: "white"}} href="#">Filter Status:</li>
|
||||||
|
<li><a className="dropdown-item" onClick={()=>changeParams("filter", "Dalam Proses")}>Dalam Proses</a></li>
|
||||||
|
<li><a className="dropdown-item" onClick={()=>changeParams("filter", "Ditindak Lanjuti")}>Ditindak Lanjuti</a></li>
|
||||||
|
<li><a className="dropdown-item" onClick={()=>changeParams("filter", "Selesai")}>Selesai</a></li>
|
||||||
|
<li><a className="dropdown-item" onClick={()=>setSearchParams({})}>Hapus Filter</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{riwayats.map((riwayat) => (
|
||||||
|
<div className="riwayat-box" key={riwayat.id} onClick={() => toDetailPage(riwayat.id+"/0")}>
|
||||||
|
<h3>Nama Irigasi: {riwayat.irrigation}</h3>
|
||||||
|
<h3>Saluran: {riwayat.canal}</h3>
|
||||||
|
<h3>Status: {riwayat.status}</h3>
|
||||||
|
<h3>Tanggal Lapor: {riwayat.created_at.split(" ")[0]}</h3>
|
||||||
|
{riwayat.done_at?<h3>Tanggal Selesai: {riwayat.done_at}</h3>:<></>}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
{ isLoading ?
|
||||||
|
<>
|
||||||
|
<LoadingPopUp/>
|
||||||
|
</>
|
||||||
|
:<></>
|
||||||
|
}
|
||||||
|
<BottomBar activeIcon={"riwayat"} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
8
IrrigationReport/vercel.json
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"src": "/[^.]+",
|
||||||
|
"dest": "/"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
7
IrrigationReport/vite.config.js
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import react from '@vitejs/plugin-react'
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [react()],
|
||||||
|
})
|
||||||
BIN
Laporan Skripsi_Zaed Abdullah.docx
Normal file
BIN
Manual Program.docx
Normal file
BIN
Presentasi Skripsi_Zaed Abdullah.pptx
Normal file
18
irrigation-report-api/.editorconfig
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.{yml,yaml}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[docker-compose.yml]
|
||||||
|
indent_size = 4
|
||||||
59
irrigation-report-api/.env.example
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
APP_NAME=Laravel
|
||||||
|
APP_ENV=local
|
||||||
|
APP_KEY=
|
||||||
|
APP_DEBUG=true
|
||||||
|
APP_URL=http://localhost
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
LOG_DEPRECATIONS_CHANNEL=null
|
||||||
|
LOG_LEVEL=debug
|
||||||
|
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=127.0.0.1
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=laravel
|
||||||
|
DB_USERNAME=root
|
||||||
|
DB_PASSWORD=
|
||||||
|
|
||||||
|
BROADCAST_DRIVER=log
|
||||||
|
CACHE_DRIVER=file
|
||||||
|
FILESYSTEM_DISK=local
|
||||||
|
QUEUE_CONNECTION=sync
|
||||||
|
SESSION_DRIVER=file
|
||||||
|
SESSION_LIFETIME=120
|
||||||
|
|
||||||
|
MEMCACHED_HOST=127.0.0.1
|
||||||
|
|
||||||
|
REDIS_HOST=127.0.0.1
|
||||||
|
REDIS_PASSWORD=null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=mailpit
|
||||||
|
MAIL_PORT=1025
|
||||||
|
MAIL_USERNAME=null
|
||||||
|
MAIL_PASSWORD=null
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
MAIL_FROM_ADDRESS="hello@example.com"
|
||||||
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
|
AWS_ACCESS_KEY_ID=
|
||||||
|
AWS_SECRET_ACCESS_KEY=
|
||||||
|
AWS_DEFAULT_REGION=us-east-1
|
||||||
|
AWS_BUCKET=
|
||||||
|
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||||
|
|
||||||
|
PUSHER_APP_ID=
|
||||||
|
PUSHER_APP_KEY=
|
||||||
|
PUSHER_APP_SECRET=
|
||||||
|
PUSHER_HOST=
|
||||||
|
PUSHER_PORT=443
|
||||||
|
PUSHER_SCHEME=https
|
||||||
|
PUSHER_APP_CLUSTER=mt1
|
||||||
|
|
||||||
|
VITE_APP_NAME="${APP_NAME}"
|
||||||
|
VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||||
|
VITE_PUSHER_HOST="${PUSHER_HOST}"
|
||||||
|
VITE_PUSHER_PORT="${PUSHER_PORT}"
|
||||||
|
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
|
||||||
|
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
11
irrigation-report-api/.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
* text=auto eol=lf
|
||||||
|
|
||||||
|
*.blade.php diff=html
|
||||||
|
*.css diff=css
|
||||||
|
*.html diff=html
|
||||||
|
*.md diff=markdown
|
||||||
|
*.php diff=php
|
||||||
|
|
||||||
|
/.github export-ignore
|
||||||
|
CHANGELOG.md export-ignore
|
||||||
|
.styleci.yml export-ignore
|
||||||
20
irrigation-report-api/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
/.phpunit.cache
|
||||||
|
/node_modules
|
||||||
|
/public/build
|
||||||
|
/public/hot
|
||||||
|
/public/storage
|
||||||
|
/storage/*.key
|
||||||
|
/vendor
|
||||||
|
.env
|
||||||
|
.env.backup
|
||||||
|
.env.production
|
||||||
|
.phpunit.result.cache
|
||||||
|
Homestead.json
|
||||||
|
Homestead.yaml
|
||||||
|
auth.json
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
/.fleet
|
||||||
|
/.idea
|
||||||
|
/.vscode
|
||||||
|
/firebase_credential.json
|
||||||
66
irrigation-report-api/README.md
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
|
||||||
|
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
||||||
|
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
||||||
|
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## About Laravel
|
||||||
|
|
||||||
|
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
|
||||||
|
|
||||||
|
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
||||||
|
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
||||||
|
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
||||||
|
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
||||||
|
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
||||||
|
- [Robust background job processing](https://laravel.com/docs/queues).
|
||||||
|
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
||||||
|
|
||||||
|
Laravel is accessible, powerful, and provides tools required for large, robust applications.
|
||||||
|
|
||||||
|
## Learning Laravel
|
||||||
|
|
||||||
|
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
|
||||||
|
|
||||||
|
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
|
||||||
|
|
||||||
|
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 2000 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
|
||||||
|
|
||||||
|
## Laravel Sponsors
|
||||||
|
|
||||||
|
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com).
|
||||||
|
|
||||||
|
### Premium Partners
|
||||||
|
|
||||||
|
- **[Vehikl](https://vehikl.com/)**
|
||||||
|
- **[Tighten Co.](https://tighten.co)**
|
||||||
|
- **[WebReinvent](https://webreinvent.com/)**
|
||||||
|
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
||||||
|
- **[64 Robots](https://64robots.com)**
|
||||||
|
- **[Curotec](https://www.curotec.com/services/technologies/laravel/)**
|
||||||
|
- **[Cyber-Duck](https://cyber-duck.co.uk)**
|
||||||
|
- **[DevSquad](https://devsquad.com/hire-laravel-developers)**
|
||||||
|
- **[Jump24](https://jump24.co.uk)**
|
||||||
|
- **[Redberry](https://redberry.international/laravel/)**
|
||||||
|
- **[Active Logic](https://activelogic.com)**
|
||||||
|
- **[byte5](https://byte5.de)**
|
||||||
|
- **[OP.GG](https://op.gg)**
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
||||||
|
|
||||||
|
## Code of Conduct
|
||||||
|
|
||||||
|
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
||||||
|
|
||||||
|
## Security Vulnerabilities
|
||||||
|
|
||||||
|
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
class GenerateApiKey extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'generate-api-key';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Generated random API key';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$prefix = 'eikb';
|
||||||
|
$rand1 = substr(md5(uniqid()), 0, 8);
|
||||||
|
$rand2 = Str::random(8);
|
||||||
|
$rand3 = strval(mt_rand(1000, 9999));
|
||||||
|
$rand4 = str_shuffle(Str::random(4));
|
||||||
|
$rand5 = Str::random(10);
|
||||||
|
|
||||||
|
$apiKey = "$prefix-$rand1-$rand2-$rand3-$rand4-$rand5";
|
||||||
|
|
||||||
|
$this->info('API Key: ' . $apiKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
irrigation-report-api/app/Console/Kernel.php
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console;
|
||||||
|
|
||||||
|
use Illuminate\Console\Scheduling\Schedule;
|
||||||
|
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||||
|
|
||||||
|
class Kernel extends ConsoleKernel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Define the application's command schedule.
|
||||||
|
*/
|
||||||
|
protected function schedule(Schedule $schedule): void
|
||||||
|
{
|
||||||
|
// $schedule->command('inspire')->hourly();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the commands for the application.
|
||||||
|
*/
|
||||||
|
protected function commands(): void
|
||||||
|
{
|
||||||
|
$this->load(__DIR__.'/Commands');
|
||||||
|
|
||||||
|
require base_path('routes/console.php');
|
||||||
|
}
|
||||||
|
}
|
||||||
30
irrigation-report-api/app/Exceptions/Handler.php
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exceptions;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class Handler extends ExceptionHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The list of the inputs that are never flashed to the session on validation exceptions.
|
||||||
|
*
|
||||||
|
* @var array<int, string>
|
||||||
|
*/
|
||||||
|
protected $dontFlash = [
|
||||||
|
'current_password',
|
||||||
|
'password',
|
||||||
|
'password_confirmation',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the exception handling callbacks for the application.
|
||||||
|
*/
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
$this->reportable(function (Throwable $e) {
|
||||||
|
//
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||