simpasi / app.R
aephidayatuloh
upd: word_wrap mengganti NA dengan "-"
0864583
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"),
# Content
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"),
# Content
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"),
# Content
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({
# source("dbconnect.R")
# menu <- pg_con |>
pg_con |>
tbl("menu")
# dbDisconnect(pg_con)
# return(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))
# source("dbconnect.R")
# query <- glue("INSERT INTO public.menu (id_parent, id_anak, tanggal, karbo, protein_hewani, protein_nabati, buah_sayur, lemak_tambahan, camilan, gejala, tgl_gejala, created_date)
# VALUES (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()}')")
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)
# dbDisconnect(pg_con)
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())
# closeAlert()
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))) |> #slice(1)
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(
# f7DatePicker("history_date", NULL,
# value = min(cari_history()$tanggal)),
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)
),
# f7Segment(container = "segment",
# f7Button("prev_history", "< Prev"),
# f7Button("nex_history", "Next >")
# ),
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)
})
}
)