diff --git a/data/certbot/conf/accounts/acme-v02.api.letsencrypt.org/directory/ea267890aea95a1f17dc1366beaae60b/meta.json b/data/certbot/conf/accounts/acme-v02.api.letsencrypt.org/directory/ea267890aea95a1f17dc1366beaae60b/meta.json new file mode 100644 index 0000000000000000000000000000000000000000..00d68ba8210520b0596cd7921ec125ea499eb56a --- /dev/null +++ b/data/certbot/conf/accounts/acme-v02.api.letsencrypt.org/directory/ea267890aea95a1f17dc1366beaae60b/meta.json @@ -0,0 +1 @@ +{"creation_dt": "2024-05-12T17:14:21Z", "creation_host": "e861166e59fc"} \ No newline at end of file diff --git a/data/certbot/conf/accounts/acme-v02.api.letsencrypt.org/directory/ea267890aea95a1f17dc1366beaae60b/private_key.json b/data/certbot/conf/accounts/acme-v02.api.letsencrypt.org/directory/ea267890aea95a1f17dc1366beaae60b/private_key.json new file mode 100644 index 0000000000000000000000000000000000000000..058041ae37bff3379500e149d1d23b2716875205 --- /dev/null +++ b/data/certbot/conf/accounts/acme-v02.api.letsencrypt.org/directory/ea267890aea95a1f17dc1366beaae60b/private_key.json @@ -0,0 +1 @@ +{"n": "wkcQy64niwy18vWV-o5fs3mz15FsVyKJquNJ63ZiE_fUVLaBmh5TlLGH6LcLYOMdxX7pWuwJMfD-oTlmjTGhkUv-4dufj0YNwLzfUCxdGjwmOkCUuREhyquM1OQFVwVmO3Zjq0uvFbDPKMXtNUqkDzZq30K6D1NpsTwxUlp_-BD-wV7MrVsqfSPFUAc7n8wdquNfIDf5lsWH23Co-CLQ941PCuEtVQ6B8WHuQMhafLkjpUNE-pNyE27XGKF5wiJSfsWKDPc41KPelS0JaIUSR5Ot5qDlqhn2e-qeztEG8AtcPIW_tMlVsYyQK6EVCepezOqJGNCdN89ZVRDGow2Lh3igOgoXp3okKceaZKmzlsRpE5YdsX2PShROntVyD9Lni6TqfoSWNMRRA96I9z2DN9qYBFDWwtr1H1vVmUPplkl-Oxe_-TqBVzoztQh0Ir2gAIVG8RGqH73YkuNjzpVznCuGUk9xDWsxp2AOU3c06PGgDbqZt3DELz82IfsvjRX9Mdl6g-DBwyVS5CwjERh8ON8xIk02x5nEPXBfpHFYQPyqp-GzxV6BE8h6B5fEK3LvXAVfUEWPDB5lujc_bvHd5AgWzO7uNBZZvqBjwAqKJrrl16HG6GLlkH42vr-CKvYuWTpDc_xUXaLbUJf2ldA5SCU1vpGrcfbD1QaNchr4CTU", "e": "AQAB", "d": "FNFmAgK-HK8BVZuYtVSe-gMckQj1lxC4Ynt15v60hnc-us_Oa3lnHhPiqxPnlZDra8esXHXWi7zLTEjJAxrtDpNvfeb5iMd09HueDQqen2UP-PCv_x962NYxLSQ8qOqHM0VTFilHWwerQISVD-ouUlhTyMDEYfK07K0Ki_dD_I0K_3rtFoEiYxkmLOvZfnIc67xEQUDo7zho1SGUDvg2yZAhhtpCRU8HVZpXhtGcAKlwzGYSSizqmHJ-0hYw5JX7nmIEklxw1o2zbZYkip1X1sZYaCeYSfX7l6O4iL5ABBDzkqNdEOj81HMU2oKprST-1kPQ6mZ7B7P3BUqFk-CrsWnly5R-L9AKUoXxyAvv2VTo7h3WRg470pY6HmvSddyLVl6BDGCi5vw-wcRNy4hEEi2OZDcKOr6Sv6WmI8I39joJDBKwM23mu3AlwNn2MVggCplwT_k7tgLkgn_5IEsNpdO0zpeKpso2gUcv04Ezg_0BWhlfV4TYNs_4E65YLepMpIvvqVe85w1nRiQ57TghZgc7GDQCRwf0KKNZMFsO7l28UswURUmCsvEaigqjiUe13VD9rU_XMwc4ob80OPctCgZhzS9mfYFjQvxe7JfOrcOeV-DYaNrBtelVGEqfDezy8SjqJ4IcXyMx_Jr-wuAYFo4VCWQ42S6B5wipPOdegrE", "p": "9iSQDnxOQIqpyzK0v_tFjKLUb8Q3HHl0IHPa7L-ESKTg7E_GYJfW0tYuijwrzjkfeSDYnEtHhjff_ulC6N51CVR4Js5_Yio76efjZoGSraSSt8UWhg2E6bNXQmzMTFq_47sFoKRG9_1dugWVvhnm26keYC-eWkJ4DKzX0tZQwsrsN8PD97G2KhETt6OQ7I05AH_g3a2_tWXpplJSROaUG-kvTQVJU6nx9IsIdBmUmhnXCWGYKN_5hU2sUi9tET8fgE5zm5TqX5xd1FVfyhza765J-WojkyyyvqREKaDZvJQRaTNh_AVNp-0OgMjSizZXtRNaZzpmmsWiExnhZaqISw", "q": "yg7I3Eoq-DKCvyb4dym2xg35TSuZa0W62o3yTdwjRWSJBQgrOSmv-F3jjlmI90AwIzsg0HOynRsFmze4YL2KdIljDdpcN4a9KLBL7pVEck6jQyt7B50Fa7Mbe8vKMHsnwzPDmvj4CzElnpsjExuxoFdmI_k0sECljBs2lDUEDDzceqDUvCrgOtgdtLO_FoykeG-o_vlXno2lguz2Dxzn3ApPTQYeBl6HIHr10Bs1eJRmjRBMpAdhM1QYG5LYMlk4LoCf2wQNG8K2A6OCE_r4NR9RaupwBuRXx9KT3sMdK2DmIHV-FoaF9YsQSKH04046bqR55QzFS4ymuw9ud-_Efw", "dp": "YInmlkfaySWZgsDYc5Oxq38RouRqWRipmzDVZJWY5IUGUqjXPXtQHlEy37TJ2ZA979waGPLNkq7Hg8spGvxlGsuudEn5XB8EcLEqV0HqrYAmqzz5oIoc3ywfxUW2uxu8tyzbAC5uR0VwRU17dZvjF7Q03bTPfscjHpWL8H1uH3hHPXfinHtu3wDjotrcNGsPOErvfwJudk8KXNlcuvlUjb3fd23jXJUC-M6u-houVmJcHKnSa_Wsf8P_GhzPwjvntwMOBK9bXTSO-ICjmTnIBMlu6gve-BJH6M20jj8wJu5MBd7JR3ctBffMAGbDbSZbMAHvKx2UsI9jCerUpHNGEQ", "dq": "TQwCL23goK-yB222xMmVNkRR0clUQQFf1MLXqDTPBkDltpN819k7jntOsBMYFR_WuzhqtNHJQ_rv0lYW6lycFP_mU3v2Of4Y1xESgzFL3kJ6IrzLtwV68axkSHpW6NGtQdPVPJy_CJV_ANGrODgRLVDmU8VNAABGn_wofa8RkhELCX-WXwICaq3J9gOsU87hUENTr5YogP8GI7xzvyOIjfEod_hjLo6Q_COm4-ncI9SCnjue3dUqjUX9w1XlNp2qvKCzU_JhhTpj6VNJ4JCMYMVGaHxop1ge2MVFOWYxEz9pwOrMX46AOjcCyI9pL9u-kD4LdPm_qaVCVoX126oDxQ", "qi": "tbsWkxhkHXa0-nApZHGe78vai6X2qv89FMmRVYmKw4dHGm9obsUq2pGuIRfpASpvgil7SQcl5kNH58YxjQ0uH934Ysf2Xz8hzyryY7xWO8zjcYdcl4LkaNq01yCT2ARP-NduIdyHXO3pC2QHnCZSUEDOlmAQDX3Eczrod8i6uN0FEIA_VFcb-ynl9_HxLZUhMaDy_2OhRzr1UYm_5i5wCuSTT26bIarHuI5xV8J4t3efcP-LBfQM8MjqCcl9itGPrnhFoj_TlqXlkAFg9ELr5Wia58hZ5C22u7ADkk9kdoODyrdpJa_mwaDfR7VzJLlLwcZ8LC-0fzwJ4zPX3Yn5vQ", "kty": "RSA"} \ No newline at end of file diff --git a/data/certbot/conf/accounts/acme-v02.api.letsencrypt.org/directory/ea267890aea95a1f17dc1366beaae60b/regr.json b/data/certbot/conf/accounts/acme-v02.api.letsencrypt.org/directory/ea267890aea95a1f17dc1366beaae60b/regr.json new file mode 100644 index 0000000000000000000000000000000000000000..a656bbd08c5ff7ad9a0c2f6f35b1f7bab4238706 --- /dev/null +++ b/data/certbot/conf/accounts/acme-v02.api.letsencrypt.org/directory/ea267890aea95a1f17dc1366beaae60b/regr.json @@ -0,0 +1 @@ +{"body": {}, "uri": "https://acme-v02.api.letsencrypt.org/acme/acct/1722574517"} \ No newline at end of file diff --git a/data/certbot/conf/options-ssl-nginx.conf b/data/certbot/conf/options-ssl-nginx.conf new file mode 100644 index 0000000000000000000000000000000000000000..f2aadba3dec1e6e7602cc56590fe9f15294bbcd1 --- /dev/null +++ b/data/certbot/conf/options-ssl-nginx.conf @@ -0,0 +1,14 @@ +# This file contains important security parameters. If you modify this file +# manually, Certbot will be unable to automatically provide future security +# updates. Instead, Certbot will print and log an error message with a path to +# the up-to-date file that you will need to refer to when manually updating +# this file. Contents are based on https://ssl-config.mozilla.org + +ssl_session_cache shared:le_nginx_SSL:10m; +ssl_session_timeout 1440m; +ssl_session_tickets off; + +ssl_protocols TLSv1.2 TLSv1.3; +ssl_prefer_server_ciphers off; + +ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"; diff --git a/data/certbot/conf/ssl-dhparams.pem b/data/certbot/conf/ssl-dhparams.pem new file mode 100644 index 0000000000000000000000000000000000000000..9b182b7201fd94b6d896f863418517808bbbe7f9 --- /dev/null +++ b/data/certbot/conf/ssl-dhparams.pem @@ -0,0 +1,8 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz ++8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a +87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7 +YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi +7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD +ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg== +-----END DH PARAMETERS----- diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000000000000000000000000000000000000..4d1ded0118d91ed44f2dc7c7bb680e7327975fa0 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,27 @@ +version: '3.8' + +services: + goservice: + image: graduit-be + env_file: .env + ports: + - "8080:8080" + + nginx: + build: ./nginx + ports: + - "80:80" + - "443:443" + depends_on: + - goservice + volumes: + - ./data/certbot/conf:/etc/letsencrypt + - ./data/certbot/www:/var/www/certbot + command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" + + certbot: + image: certbot/certbot + volumes: + - ./data/certbot/conf:/etc/letsencrypt + - ./data/certbot/www:/var/www/certbot + entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index e4d8efbada9c8fb11ab4fda0d6550af6e4b95107..3760b0c8d2a89a496a5228a15e3a8fde78465ebd 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -1,19 +1,5 @@ version: "3.8" services: - graduit_server: - build: . - ports: - - 8080:8080 - hostname: graduit_server - env_file: .env - volumes: - - ./:/usr/app - - /usr/app/db-data - restart: always - depends_on: - - graduit_db - - s2_db - s2_db: image: postgres:alpine ports: diff --git a/init-letsencrypt.sh b/init-letsencrypt.sh new file mode 100755 index 0000000000000000000000000000000000000000..6f0c741f9e8425af42f3d30418843e3ec5a70fa8 --- /dev/null +++ b/init-letsencrypt.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +if ! [ -x "$(command -v docker-compose)" ]; then + echo 'Error: docker-compose is not installed.' >&2 + exit 1 +fi + +domains=(s1api.domainbuattesting.my.id) +rsa_key_size=4096 +data_path="./data/certbot" +email="" # Adding a valid address is strongly recommended +staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits + +if [ -d "$data_path" ]; then + read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision + if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then + exit + fi +fi + + +if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then + echo "### Downloading recommended TLS parameters ..." + mkdir -p "$data_path/conf" + curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf" + curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem" + echo +fi + +echo "### Creating dummy certificate for $domains ..." +path="/etc/letsencrypt/live/$domains" +mkdir -p "$data_path/conf/live/$domains" +docker-compose -f docker-compose.prod.yml run --rm --entrypoint "\ + openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\ + -keyout '$path/privkey.pem' \ + -out '$path/fullchain.pem' \ + -subj '/CN=localhost'" certbot +echo + + +echo "### Starting nginx ..." +docker-compose -f docker-compose.prod.yml up --force-recreate -d nginx +echo + +echo "### Deleting dummy certificate for $domains ..." +docker-compose -f docker-compose.prod.yml run --rm --entrypoint "\ + rm -Rf /etc/letsencrypt/live/$domains && \ + rm -Rf /etc/letsencrypt/archive/$domains && \ + rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot +echo + + +echo "### Requesting Let's Encrypt certificate for $domains ..." +#Join $domains to -d args +domain_args="" +for domain in "${domains[@]}"; do + domain_args="$domain_args -d $domain" +done + +# Select appropriate email arg +case "$email" in + "") email_arg="--register-unsafely-without-email" ;; + *) email_arg="--email $email" ;; +esac + +# Enable staging mode if needed +if [ $staging != "0" ]; then staging_arg="--staging"; fi + +docker-compose -f docker-compose.prod.yml run --rm --entrypoint "\ + certbot certonly --webroot -w /var/www/certbot \ + $staging_arg \ + $email_arg \ + $domain_args \ + --rsa-key-size $rsa_key_size \ + --agree-tos \ + --force-renewal" certbot +echo + +echo "### Reloading nginx ..." +docker-compose -f docker-compose.prod.yml exec nginx nginx -s reload diff --git a/nginx/Dockerfile b/nginx/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..1a23bd593167e01a92d31bb29e20c9d0d612b67b --- /dev/null +++ b/nginx/Dockerfile @@ -0,0 +1,7 @@ +#nginx/Dockerfile +FROM nginx:latest +EXPOSE 80 +EXPOSE 443 +COPY nginx.conf /etc/nginx/nginx.conf +# Start Nginx process +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/nginx/nginx.conf b/nginx/nginx.conf new file mode 100644 index 0000000000000000000000000000000000000000..5599432a74834b941ac5fd2fda51bb504c1da2f1 --- /dev/null +++ b/nginx/nginx.conf @@ -0,0 +1,47 @@ +"nginx.conf" + +events { + worker_connections 1024; +} +http { + server_tokens off; + sendfile on; + include /etc/nginx/mime.types; + include /etc/letsencrypt/options-ssl-nginx.conf; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + +server { + listen 80; + server_name s1api.domainbuattesting.my.id finance-api.web.id; + + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl; + server_name s1api.domainbuattesting.my.id finance-api.web.id; + + ssl_certificate /etc/letsencrypt/live/s1api.domainbuattesting.my.id/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/s1api.domainbuattesting.my.id/privkey.pem; + + location /api/ { + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $http_host; + proxy_pass http://goservice:8080/api/; + } + + + location /swagger/ { + proxy_set_header X-Forwarded-For $remote_addr; + proxy_set_header Host $http_host; + proxy_pass http://goservice:8080$request_uri; + } + + } +} \ No newline at end of file diff --git a/src/handler/handler.go b/src/handler/handler.go index d9f5c953353ca9d8806914d9b8b1341f08017a6e..19ada8be1289f6ff9d5ad714031abb6a903bb784 100644 --- a/src/handler/handler.go +++ b/src/handler/handler.go @@ -14,6 +14,8 @@ import ( dashboardMahasiswaTransport "gitlab.informatika.org/k-01-11/graduit-be/src/module/dashboard_mahasiswa/transport" dashboardTimTugasConfig "gitlab.informatika.org/k-01-11/graduit-be/src/module/dashboard_tim_tugas/config" dashboardTimTugasTransport "gitlab.informatika.org/k-01-11/graduit-be/src/module/dashboard_tim_tugas/transport" + dashboardTimTAConfig "gitlab.informatika.org/k-01-11/graduit-be/src/module/dashboard_tim_ta/config" + dashboardTimTATransport "gitlab.informatika.org/k-01-11/graduit-be/src/module/dashboard_tim_ta/transport" pendaftaranConfig "gitlab.informatika.org/k-01-11/graduit-be/src/module/pendaftaran/config" pendaftaranTransport "gitlab.informatika.org/k-01-11/graduit-be/src/module/pendaftaran/transport" pendaftaranSidSemConfig "gitlab.informatika.org/k-01-11/graduit-be/src/module/pendaftaran_sidsem/config" @@ -49,6 +51,8 @@ type Service struct { TIMTASchedulingHandler *schedulingTransport.TIMTASchedulingHandler MahasiswaPendaftaranSidSemHandler *pendaftaranSidSemTransport.MahasiswaPendaftaranSidSemHandler TIMTAPendaftaranSidSemHandler *pendaftaranSidSemTransport.TIMTAPendaftaranSidSemHandler + TIMTADashboardTimHandler *dashboardTimTATransport.TIMTADashboardTimHandler + } func MakeHandler() *Service { @@ -118,6 +122,11 @@ func MakeHandler() *Service { DBRead: dbRead, }) + TIMTADashboardHandler := dashboardTimTATransport.NewTIMTADashboardTimHandler(dashboardTimTAConfig.DashboardTimTransportConfig{ + DBWrite: dbWrite, + DBRead: dbRead, + }) + TIMTASchedulingHandlerHandler := schedulingTransport.NewTIMTASchedulingHandler(schedulingConfig.SchedulingTransportConfig{ DBWrite: dbWrite, DBRead: dbRead, @@ -150,5 +159,6 @@ func MakeHandler() *Service { MahasiswaPendaftaranSidSemHandler: MahasiswaPendaftaranSidSemHandler, TIMTAPendaftaranSidSemHandler: TIMTAPendaftaranSidSemHandler, AdminRuanganHandler: AdminRuanganHandler, + TIMTADashboardTimHandler: TIMTADashboardHandler, } } diff --git a/src/handler/server.go b/src/handler/server.go index 0353fb9be7c539da2c75dc3d44b44c5e3bbc5be4..bbefc56b5425682207fe15c3bfb79f4301894352 100644 --- a/src/handler/server.go +++ b/src/handler/server.go @@ -63,6 +63,7 @@ func (s *Service) InitializeRoutes() *echo.Echo { TIMTAGroup.Use(middleware.Validator("S1_TIM_TA")) s.TIMTASchedulingHandler.MountTIMTA(TIMTAGroup) s.TIMTAPendaftaranSidSemHandler.MountTIMTA(TIMTAGroup) + s.TIMTADashboardTimHandler.MountTIMTA(TIMTAGroup) return e } diff --git a/src/module/dashboard_tim_ta/entity/dashboard_tim_ta.go b/src/module/dashboard_tim_ta/entity/dashboard_tim_ta.go index 1fe62afd879a141e6e04d9011fda4c9130548368..c38f71ae3fb147624d3b178541cb4603d163bb8d 100644 --- a/src/module/dashboard_tim_ta/entity/dashboard_tim_ta.go +++ b/src/module/dashboard_tim_ta/entity/dashboard_tim_ta.go @@ -12,3 +12,12 @@ type DataPendaftaran struct { DosenPembimbing string `json:"dosbing"` Status string `json:"status"` } + +type StatusMahasiswa struct { + Id string `json:"id"` + NIM string `json:"nim"` + Nama string `json:"nama"` + PengajuanTopik bool + SeminarProposal bool + Sidang bool +} diff --git a/src/module/dashboard_tim_ta/internal/repository/dashboard_tim_ta.go b/src/module/dashboard_tim_ta/internal/repository/dashboard_tim_ta.go index dd0e75df33a1053aa756ea9230f65182bfbdaeac..a17c999b0cefddc5becde43020c43c75f30d9ed3 100644 --- a/src/module/dashboard_tim_ta/internal/repository/dashboard_tim_ta.go +++ b/src/module/dashboard_tim_ta/internal/repository/dashboard_tim_ta.go @@ -70,3 +70,69 @@ func (repo *DashboardTimRepo) GetDataDashboard(offset, size int) (output []entit return dataMahasiswa, nil } + +func (repo *DashboardTimRepo) GetStatusDashboard(offset, size int) (output []entity.StatusMahasiswa, err error) { + var statusMahasiswa []entity.StatusMahasiswa + var mahasiswa []models.Pengguna + + // Find all users that have role S1_MAHASISWA + result := repo.DBRead.Where("roles @> ?", "{S1_MAHASISWA}").Limit(size).Offset(offset).Find(&mahasiswa) + if result.Error != nil { + return nil, result.Error + } + + for _, mhs := range mahasiswa { + var proposal models.PendaftaranTA + var sidsem models.PendaftaranSidSem + var taStatus, seminarStatus, sidangStatus bool + + // Check status for TA + taResult := repo.DBRead.Where("id_mahasiswa = ?", mhs.ID).First(&proposal) + if taResult.Error != nil { + taStatus = false + } else if proposal.Status != "APPROVED" { + taStatus = false + } else { + taStatus = true + } + + // Check status for Seminar Proposal + seminarResult := repo.DBRead.Where("pendaftaran_ta_id = ? AND tipe = ?", proposal.ID, "Seminar Proposal").First(&sidsem) + if seminarResult.Error != nil { + seminarStatus = false + } else if !sidsem.Ditolak { + seminarStatus = false + } else if sidsem.Ditolak { + seminarStatus = true + } else { + seminarStatus = false + } + + // Check status for Sidang Proposal + sidangResult := repo.DBRead.Where("pendaftaran_ta_id = ? AND tipe = ?", mhs.ID, "Sidang Proposal").First(&sidsem) + if sidangResult.Error != nil { + sidangStatus = false + } else if !sidsem.Ditolak { + sidangStatus = false + } else if sidsem.Ditolak { + sidangStatus = true + } else { + sidangStatus = false + } + + // Create StatusMahasiswa entity + data := entity.StatusMahasiswa{ + Id: mhs.ID, + NIM: mhs.NIM, + Nama: mhs.Nama, + PengajuanTopik: taStatus, + SeminarProposal: seminarStatus, + Sidang: sidangStatus, + } + + // Append to output + statusMahasiswa = append(statusMahasiswa, data) + } + + return statusMahasiswa, nil +} diff --git a/src/module/dashboard_tim_ta/internal/usecase/dashboard_tim_ta.go b/src/module/dashboard_tim_ta/internal/usecase/dashboard_tim_ta.go index d83a54a19b9670f4ec96ee93f47b0af69cd01d07..92c0e1aa7acaa03269646400f8fd6a52259dd1e3 100644 --- a/src/module/dashboard_tim_ta/internal/usecase/dashboard_tim_ta.go +++ b/src/module/dashboard_tim_ta/internal/usecase/dashboard_tim_ta.go @@ -4,6 +4,7 @@ import "gitlab.informatika.org/k-01-11/graduit-be/src/module/dashboard_tim_ta/en type DashboardTimUseCase interface { GetDataMahasiswa(offset, size int) (output []entity.DataPendaftaran, err error) + GetStatusMahasiswa(offset, size int) (output []entity.StatusMahasiswa, err error) } type DashboardTimUc struct { @@ -25,3 +26,13 @@ func (uc *DashboardTimUc) GetDataMahasiswa(offset, size int) (output []entity.Da return listMahasiswa, nil } + +func (uc *DashboardTimUc) GetStatusMahasiswa(offset, size int) (output []entity.StatusMahasiswa, err error) { + listMahasiswa, err := uc.dashboardTimRepo.GetStatusDashboard(offset, size) + + if err != nil { + return listMahasiswa, err + } + + return listMahasiswa, nil +} diff --git a/src/module/dashboard_tim_ta/internal/usecase/repository.go b/src/module/dashboard_tim_ta/internal/usecase/repository.go index 9114e4d92a09b8402175e7aa77de7a570fd29fb5..559e2203aed7c45b9af35c107381c25b1829f98e 100644 --- a/src/module/dashboard_tim_ta/internal/usecase/repository.go +++ b/src/module/dashboard_tim_ta/internal/usecase/repository.go @@ -4,4 +4,5 @@ import "gitlab.informatika.org/k-01-11/graduit-be/src/module/dashboard_tim_ta/en type DashboardTimRepository interface { GetDataDashboard(offset, size int) (output []entity.DataPendaftaran, err error) + GetStatusDashboard(offset, size int) (output []entity.StatusMahasiswa, err error) } diff --git a/src/module/dashboard_tim_ta/transport/admin_handler.go b/src/module/dashboard_tim_ta/transport/timta_handler.go similarity index 63% rename from src/module/dashboard_tim_ta/transport/admin_handler.go rename to src/module/dashboard_tim_ta/transport/timta_handler.go index 1d5f73545c5b24299ebb3b6a95d5b67f811e0e40..cf6983ae87e31e48717eaeac696367c244147673 100644 --- a/src/module/dashboard_tim_ta/transport/admin_handler.go +++ b/src/module/dashboard_tim_ta/transport/timta_handler.go @@ -11,21 +11,22 @@ import ( "gitlab.informatika.org/k-01-11/graduit-be/src/utils" ) -type AdminDashboardTimHandler struct { +type TIMTADashboardTimHandler struct { dashboardTimUseCase usecase.DashboardTimUseCase } -func NewAdminDashboardTimHandler(cfg config.DashboardTimTransportConfig) *AdminDashboardTimHandler { +func NewTIMTADashboardTimHandler(cfg config.DashboardTimTransportConfig) *TIMTADashboardTimHandler { dashboardTimRepository := repository.NewDashboardTimRepository(cfg.DBWrite, cfg.DBRead) dashboardTimUsecase := usecase.NewDashboardTimUsecase(dashboardTimRepository) - return &AdminDashboardTimHandler{ + return &TIMTADashboardTimHandler{ dashboardTimUseCase: dashboardTimUsecase, } } -func (t *AdminDashboardTimHandler) MountAdmin(group *echo.Group) { +func (t *TIMTADashboardTimHandler) MountTIMTA(group *echo.Group) { group.GET("/dashboard-tim", t.GetDataMahasiswa) + group.GET("/dashboard-status", t.GetStatusMahasiswa) } // GetDataMahasiswa retrieves a list of mahasiswa that has already done pendaftaran @@ -39,7 +40,7 @@ func (t *AdminDashboardTimHandler) MountAdmin(group *echo.Group) { // @Param offset query string false "Offset" // @Success 200 {object} []entity.DataPendaftaran "List mahasiswa successfully retrieved" // @Router /dashboard-tim [get] -func (t *AdminDashboardTimHandler) GetDataMahasiswa(c echo.Context) error { +func (t *TIMTADashboardTimHandler) GetDataMahasiswa(c echo.Context) error { sizeStr := c.QueryParam("limit") offsetStr := c.QueryParam("offset") @@ -63,3 +64,28 @@ func (t *AdminDashboardTimHandler) GetDataMahasiswa(c echo.Context) error { return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "List mahasiswa successfully retreived", listMahasiswa)) } + +func (t *TIMTADashboardTimHandler) GetStatusMahasiswa(c echo.Context) error { + sizeStr := c.QueryParam("limit") + offsetStr := c.QueryParam("offset") + + size, err := strconv.Atoi(sizeStr) + if err != nil { + // Handle error, maybe return an error response + size = 10 + } + + offset, err := strconv.Atoi(offsetStr) + if err != nil { + // Handle error, maybe return an error response + offset = 0 + } + + listMahasiswa, err := t.dashboardTimUseCase.GetStatusMahasiswa(offset, size) + if err != nil { + return c.JSON(http.StatusBadRequest, utils.ResponseDetailOutput(false, http.StatusBadRequest, err.Error(), nil)) + } + + return c.JSON(http.StatusOK, utils.ResponseDetailOutput(true, http.StatusOK, "List Status mahasiswa successfully retreived", listMahasiswa)) + +} \ No newline at end of file