|
library(shiny) |
|
library(shinyMobile) |
|
library(shinyalert) |
|
library(shinyWidgets) |
|
library(glue) |
|
library(dplyr) |
|
library(dbplyr) |
|
library(stringr) |
|
|
|
word_wrap <- function(x){ |
|
str_split(x, ",") |> |
|
unlist() |> |
|
str_trim("both") |> |
|
sapply(FUN = function(k){ |
|
if_else(is.na(k), "-", k) |
|
}) |> |
|
sapply(FUN = function(z){ |
|
if_else(nchar(z) > 90, |
|
paste(substring(z, 1, 30), substring(z, 31, 60), substring(z, 61, 90), substring(z, 91), sep = "<br>"), |
|
if_else(nchar(z) > 60, paste(substring(z, 1, 30), substring(z, 31, 60), substring(z, 61), sep = "<br>"), |
|
if_else(nchar(z) > 30, paste(substring(z, 1, 30), substring(z, 31), sep = "<br>"), |
|
z))) |
|
}) |> |
|
str_c(collapse = ",<br>") |> |
|
HTML() |
|
} |
|
|
|
ui <- f7Page( |
|
options = list(theme = "ios", dark = FALSE, skeletonOnLoad = TRUE), |
|
allowPWA = TRUE, |
|
f7TabLayout( |
|
navbar = f7Navbar(title = "SIMPASI"), |
|
f7Tabs(animated = T, |
|
id = "tabs", |
|
f7Tab(tabName = "input_menu", title = "Input Menu", active = TRUE, icon = f7Icon("book"), |
|
|
|
f7Card( |
|
h4(span(f7Icon("calendar"), "Tanggal"), style="margin:0px 0px 10px 0px;"), |
|
f7DatePicker("tgl", NULL), |
|
hr() |
|
), |
|
f7Card( |
|
h4(span(f7Icon("tray"), "Karbohidrat"), style="margin:0px 0px 10px 0px;"), |
|
f7TextArea("karbo", NULL, resize = TRUE), |
|
hr() |
|
), |
|
f7Card( |
|
h4(span(f7Icon("poultry_leg"), "Protein Hewani"), style="margin:0px 0px 10px 0px;"), |
|
f7TextArea("protein_hewani", NULL, resize = TRUE), |
|
hr() |
|
), |
|
f7Card( |
|
h4(span(f7Icon("tree"), "Protein Nabati"), style="margin:0px 0px 10px 0px;"), |
|
f7TextArea("protein_nabati", NULL, resize = TRUE), |
|
hr() |
|
), |
|
f7Card( |
|
h4(span(f7Icon("leaf_arrow_circlepath"), "Buah/Sayur"), style="margin:0px 0px 10px 0px;"), |
|
f7TextArea("buah_sayur", NULL, resize = TRUE), |
|
hr() |
|
), |
|
f7Card( |
|
h4(span(f7Icon("drop"), "Lemak Tambahan"), style="margin:0px 0px 10px 0px;"), |
|
f7TextArea("lemak_tambahan", NULL, resize = TRUE), |
|
hr() |
|
), |
|
f7Card( |
|
h4(span(f7Icon("circle_grid_hex"), "Camilan"), style="margin:0px 0px 10px 0px;"), |
|
f7TextArea("camilan", NULL, resize = TRUE), |
|
hr() |
|
), |
|
f7Card( |
|
h4(span(f7Icon("bandage"), "Gejala Alergi"), style="margin:0px 0px 10px 0px;"), |
|
f7TextArea("gejala", NULL, resize = TRUE), |
|
hr() |
|
), |
|
f7Card( |
|
h4(span(f7Icon("calendar_today"), "Tanggal Terjadi Gejala"), style="margin:0px 0px 10px 0px;"), |
|
f7DatePicker("tgl_gejala", NULL), |
|
hr() |
|
), |
|
|
|
f7Card( |
|
f7Button("save", "Simpan", size = "large"), |
|
br(), |
|
p("Copyright (C) 2024 aephidayatuloh", style = "text-align: center") |
|
) |
|
), |
|
f7Tab(tabName = "cari", title = "Cari Catatan", icon = f7Icon("doc_text_search"), |
|
|
|
f7Card( |
|
f7Select("komponen", "Cari berdasarkan:", width = "100%", |
|
choices = list("Tanggal" = "tanggal", |
|
"Karbohidrat" = "karbo", |
|
"Protein Hewani" = "protein_hewani", |
|
"Protein Nabati" = "protein_nabati", |
|
"Buah/Sayur" = "buah_sayur", |
|
"Lemak Tambahan" = "lemak_tambahan", |
|
"Camilan" = "camilan", |
|
"Gejala Alergi" = "gejala")) |
|
), |
|
conditionalPanel("input.komponen == 'tanggal'", |
|
f7Card( |
|
h4(span(f7Icon("calendar"), "Tanggal MPASI"), style="margin:0px 0px 10px 0px;"), |
|
f7DatePicker("cari_date", NULL, value = Sys.Date()), |
|
hr() |
|
), |
|
f7Card( |
|
f7Segment(container = "row", |
|
f7Button("prev", "< Prev", size = "large"), |
|
f7Button("nex", "Next >", size = "large") |
|
) |
|
), |
|
f7Card(uiOutput("out_cari_tgl")) |
|
|
|
), |
|
conditionalPanel("input.komponen != 'tanggal'", |
|
f7Card( |
|
p("Kata Kunci", style="text-align:center;"), |
|
f7Text("keyword", NULL, value = ""), |
|
hr(style="margin:5px 0px;") |
|
), |
|
uiOutput("out_cari_komponen") |
|
|
|
) |
|
|
|
|
|
), |
|
f7Tab(tabName = "update_gejala", title = "Update Gejala", icon = f7Icon("bubble_left_bubble_right"), |
|
|
|
f7Card( |
|
h4(span(f7Icon("calendar_today"), "Tanggal Terjadi Gejala"), style="margin:0px 0px 10px 0px;"), |
|
f7DatePicker("edit_tgl_gejala", NULL), |
|
hr() |
|
), |
|
f7Card( |
|
h4(span(f7Icon("bandage"), "Gejala Alergi"), style="margin:0px 0px 10px 0px;"), |
|
f7TextArea("edit_gejala", NULL, resize = TRUE), |
|
hr() |
|
), |
|
f7Card( |
|
h4(span(f7Icon("bandage"), "Tanggal Pemberian MPASI"), style="margin:0px 0px 10px 0px;"), |
|
f7DatePicker("edit_tanggal", NULL), |
|
hr() |
|
), |
|
f7Card( |
|
f7Button("edit_update", "Update", size = "large") |
|
) |
|
) |
|
) |
|
) |
|
) |
|
|
|
server <- function(input, output, session){ |
|
menu_tbl <- reactive({ |
|
|
|
|
|
pg_con |> |
|
tbl("menu") |
|
|
|
|
|
}) |
|
|
|
observeEvent(input$save, { |
|
shinyalert(text = "Yakin ingin menyimpan?", type = "info", showCancelButton = TRUE, |
|
callbackR = function(x){ |
|
if(x != FALSE){ |
|
shinyalert(text = "Menyimpan data ...", type = "info", showConfirmButton = FALSE, closeOnEsc = FALSE, closeOnClickOutside = FALSE) |
|
tgl_gejala <- if_else(input$gejala %in% c(NA, NULL, "", "-"), NA , as.Date(input$tgl_gejala)) |
|
|
|
|
|
|
|
|
|
menu_data <- tribble( |
|
~id_parent, ~id_anak, ~tanggal, ~karbo, ~protein_hewani, ~protein_nabati, ~buah_sayur, ~lemak_tambahan, ~camilan, ~gejala, ~tgl_gejala, ~created_date, |
|
1, 2, input$tgl, input$karbo, input$protein_hewani, input$protein_nabati, input$buah_sayur, input$lemak_tambahan, input$camilan, input$gejala, tgl_gejala, Sys.time() |
|
) |
|
|
|
pg_con |> |
|
dbAppendTable(name = "menu", value = menu_data) |
|
|
|
updateF7DatePicker(session = session, "tgl", NULL, value = Sys.Date()) |
|
updateF7TextArea(session = session, "karbo", NULL, value = "") |
|
updateF7TextArea(session = session, "protein_hewani", NULL, value = "") |
|
updateF7TextArea(session = session, "protein_nabati", NULL, value = "") |
|
updateF7TextArea(session = session, "buah_sayur", NULL, value = "") |
|
updateF7TextArea(session = session, "lemak_tambahan", NULL, value = "") |
|
updateF7TextArea(session = session, "camilan", NULL, value = "") |
|
updateF7TextArea(session = session, "gejala", NULL, value = "") |
|
updateF7DatePicker(session = session, "tgl_gejala", NULL, value = Sys.Date()) |
|
|
|
shinyalert(text = "Data berhasil disimpan.", type = "success", immediate = TRUE) |
|
|
|
} |
|
}) |
|
}) |
|
|
|
observeEvent(input$prev, { |
|
date_val <- reactiveValues() |
|
date_val$curr_dt <- input$cari_date |
|
updateF7DatePicker("cari_date", NULL, value = date_val$curr_dt - 1, session = session) |
|
} |
|
) |
|
|
|
observeEvent(input$nex, { |
|
date_val <- reactiveValues() |
|
date_val$curr_dt <- input$cari_date |
|
updateF7DatePicker("cari_date", NULL, value = date_val$curr_dt + 1, session = session) |
|
} |
|
) |
|
|
|
observeEvent(input$prev_history, { |
|
date_val_history <- reactiveValues() |
|
date_val_history$curr_dt_history <- as.Date(input$history_date) |
|
updateF7DatePicker(inputId = "history_date", NULL, value = date_val_history$curr_dt_history - 1, session = session) |
|
} |
|
) |
|
|
|
observeEvent(input$nex_history, { |
|
message("Next sampai sini bisa") |
|
date_val_history <- reactiveValues() |
|
message("Next sampai reactivevalues() bisa") |
|
date_val_history$curr_dt_history <- as.Date(input$history_date) |
|
message("Next sampai update reactiveValues bisa") |
|
updateF7DatePicker(inputId = "history_date", NULL, value = date_val_history$curr_dt_history + 1, session = session) |
|
} |
|
) |
|
|
|
output$out_cari_tgl <- renderUI({ |
|
cari_menu <- menu_tbl() |> |
|
collect() |> |
|
mutate(across(karbo:gejala, ~if_else(.x == "", "-", .x))) |> |
|
filter(tanggal == input$cari_date) |> |
|
mutate(tgl_gejala = tgl_gejala |> as.Date() |> format("%d %b %Y")) |
|
|
|
if(nrow(cari_menu) == 0){ |
|
p("Tidak ada catatan", style="text-align: center;") |
|
} else { |
|
f7List( |
|
f7ListItem(media = f7Icon("calendar"), |
|
header = "Tanggal", |
|
h5(format(input$cari_date, "%d %b %Y"), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("tray"), |
|
header = "Karbohidrat", |
|
h5(word_wrap(cari_menu$karbo), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("poultry_leg"), |
|
header = "Protein Hewani", |
|
h5(word_wrap(cari_menu$protein_hewani), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("tree"), |
|
header = "Protein Nabati", |
|
h5(word_wrap(cari_menu$protein_nabati), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("leaf_arrow_circlepath"), |
|
header = "Buah/Sayur", |
|
h5(word_wrap(cari_menu$buah_sayur), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("drop"), |
|
header = "Lemak Tambahan", |
|
h5(word_wrap(cari_menu$lemak_tambahan), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("circle_grid_hex"), |
|
header = "Camilan", |
|
h5(word_wrap(cari_menu$camilan), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("bandage"), |
|
header = "Gejala Alergi", |
|
h5(word_wrap(cari_menu$gejala), style="margin: 5px 0px;color: red;") |
|
), |
|
f7ListItem(media = f7Icon("calendar_today"), |
|
header = "Tanggal Terjadi Gejala", |
|
h5(ifelse(is.na(cari_menu$tgl_gejala), "-", cari_menu$tgl_gejala), style="margin: 5px 0px;color: red;") |
|
) |
|
) |
|
} |
|
}) |
|
|
|
cari_history <- reactive({ |
|
if(input$keyword != ""){ |
|
menu_tbl() |> |
|
collect() |> |
|
mutate(across(karbo:gejala, ~if_else(.x == "", "-", .x))) |> |
|
mutate(tgl_gejala = tgl_gejala |> as.Date() |> format("%d %b %Y")) |> |
|
mutate(kolom := tolower(!!sym(input$komponen))) |> |
|
filter(str_detect(kolom, tolower(input$keyword))) |> |
|
arrange(tanggal) |
|
} else { |
|
x <- data.frame(x = 0) |
|
return(x) |
|
} |
|
}) |
|
|
|
history <- reactive({ |
|
cari_history() |> |
|
slice(input$index_history_komponen) |
|
}) |
|
|
|
output$out_history <- renderUI({ |
|
if(ncol(cari_history()) == 1 | input$keyword == "" | nrow(history()) == 0){ |
|
wellPanel(style="background-color:transparent;", |
|
p("Tidak ada catatan", style="text-align: center;") |
|
) |
|
} else if(ncol(cari_history()) >= 1){ |
|
f7Card( |
|
f7List( |
|
|
|
f7ListItem(media = f7Icon("calendar"), |
|
header = "Tanggal", |
|
h5(format(as.Date(history()$tanggal), "%d %b %Y"), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("tray"), |
|
header = "Karbohidrat", |
|
h5(word_wrap(history()$karbo), |
|
style="margin: 5px 0px;max-width: 300px;overflow-wrap: inherit;word-wrap: inherit;hyphens: auto;") |
|
), |
|
f7ListItem(media = f7Icon("poultry_leg"), |
|
header = "Protein Hewani", |
|
h5(word_wrap(history()$protein_hewani), |
|
style="margin: 5px 0px;max-width: 300px;overflow-wrap: inherit;word-wrap: inherit;hyphens: auto;") |
|
), |
|
f7ListItem(media = f7Icon("tree"), |
|
header = "Protein Nabati", |
|
h5(word_wrap(history()$protein_nabati), style="margin: 5px 0px;max-width: 300px;") |
|
), |
|
f7ListItem(media = f7Icon("leaf_arrow_circlepath"), |
|
header = "Buah/Sayur", |
|
h5(word_wrap(history()$buah_sayur), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("drop"), |
|
header = "Lemak Tambahan", |
|
h5(word_wrap(history()$lemak_tambahan), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("circle_grid_hex"), |
|
header = "Camilan", |
|
h5(word_wrap(history()$camilan), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("bandage"), |
|
header = "Gejala Alergi", |
|
h5(word_wrap(history()$gejala), style="margin: 5px 0px;color: red;") |
|
), |
|
f7ListItem(media = f7Icon("calendar_today"), |
|
header = "Tanggal Terjadi Gejala", |
|
h5(ifelse(is.na(history()$tgl_gejala), "-", history()$tgl_gejala), style="margin: 5px 0px;color: red;") |
|
) |
|
) |
|
) |
|
} |
|
}) |
|
output$out_cari_komponen <- renderUI({ |
|
|
|
if(ncol(cari_history()) == 1 | input$keyword == "" | nrow(cari_history()) == 0){ |
|
f7Card(p("Tidak ada catatan", style="text-align: center;")) |
|
} else if(nrow(cari_history()) > 1){ |
|
n_history_komponen <- nrow(cari_history()) |
|
tagList( |
|
|
|
|
|
div(style="margin-left: 120px;width:150%;", |
|
f7Stepper("index_history_komponen", label = NULL, value = 1, min = 1, max = n_history_komponen, step = 1, |
|
raised = TRUE, rounded = TRUE, size = "small", fill = TRUE, color = "blue", wraps = TRUE) |
|
), |
|
|
|
|
|
|
|
|
|
uiOutput("out_history") |
|
) |
|
|
|
} else { |
|
f7Card( |
|
f7List( |
|
f7ListItem(media = f7Icon("calendar"), |
|
header = "Tanggal", |
|
h5(format(as.Date(cari_history()$tanggal), "%d %b %Y"), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("tray"), |
|
header = "Karbohidrat", |
|
h5(word_wrap(cari_history()$karbo), |
|
style="margin: 5px 0px;max-width: 300px;overflow-wrap: inherit;word-wrap: inherit;hyphens: auto;") |
|
), |
|
f7ListItem(media = f7Icon("poultry_leg"), |
|
header = "Protein Hewani", |
|
h5(word_wrap(cari_history()$protein_hewani), |
|
style="margin: 5px 0px;max-width: 300px;overflow-wrap: inherit;word-wrap: inherit;hyphens: auto;") |
|
), |
|
f7ListItem(media = f7Icon("tree"), |
|
header = "Protein Nabati", |
|
h5(word_wrap(cari_history()$protein_nabati), style="margin: 5px 0px;max-width: 300px;") |
|
), |
|
f7ListItem(media = f7Icon("leaf_arrow_circlepath"), |
|
header = "Buah/Sayur", |
|
h5(word_wrap(cari_history()$buah_sayur), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("drop"), |
|
header = "Lemak Tambahan", |
|
h5(word_wrap(cari_history()$lemak_tambahan), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("circle_grid_hex"), |
|
header = "Camilan", |
|
h5(word_wrap(cari_history()$camilan), style="margin: 5px 0px;") |
|
), |
|
f7ListItem(media = f7Icon("bandage"), |
|
header = "Gejala Alergi", |
|
h5(word_wrap(cari_history()$gejala), style="margin: 5px 0px;color: red;") |
|
), |
|
f7ListItem(media = f7Icon("calendar_today"), |
|
header = "Tanggal Terjadi Gejala", |
|
h5(ifelse(is.na(cari_history()$tgl_gejala), "-", cari_history()$tgl_gejala), style="margin: 5px 0px;color: red;") |
|
) |
|
) |
|
) |
|
} |
|
|
|
}) |
|
|
|
observeEvent(input$edit_update, { |
|
shinyalert(type = "info", |
|
text = "Anda yakin ingin memperbarui data?", |
|
showCancelButton = TRUE, showConfirmButton = TRUE, |
|
callbackR = function(x){ |
|
if(x != FALSE){ |
|
shinyalert(type = "info", text = "Sedang diproses...", immediate = TRUE, |
|
showConfirmButton = FALSE, closeOnEsc = FALSE, closeOnClickOutside = FALSE) |
|
|
|
if(menu_tbl() |> |
|
collect() |> |
|
filter(tanggal == input$edit_tanggal) |> |
|
nrow() < 1){ |
|
shinyalert(type = "warning", text = "Tidak ada data untuk tanggal MPASI tersebut", immediate = TRUE, |
|
showCancelButton = FALSE, showConfirmButton = TRUE, |
|
closeOnEsc = FALSE, closeOnClickOutside = FALSE) |
|
} else { |
|
qr <- glue("UPDATE public.menu SET gejala = '{input$edit_gejala}', tgl_gejala = '{input$edit_tgl_gejala}' WHERE tanggal = '{input$edit_tanggal}'") |
|
r <- dbSendQuery(pg_con, qr) |
|
dbClearResult(r) |
|
|
|
updateF7DatePicker("edit_tgl_gejala", NULL, value = Sys.Date(), session = session) |
|
updateF7TextArea("edit_gejala", NULL, value = "", session = session) |
|
updateF7DatePicker("edit_tanggal", NULL, value = Sys.Date(), session = session) |
|
|
|
shinyalert(type = "success", text = "Data berhasil diperbarui", immediate = TRUE, |
|
showCancelButton = FALSE, showConfirmButton = TRUE, |
|
closeOnEsc = FALSE, closeOnClickOutside = FALSE) |
|
} |
|
} |
|
}) |
|
}) |
|
} |
|
|
|
shinyApp(ui, server, |
|
onStart = function(){ |
|
source("dbconnect.R") |
|
onStop(function(){ |
|
dbDisconnect(pg_con) |
|
}) |
|
} |
|
) |
|
|