package be.simplenotes.app.views import be.simplenotes.app.utils.StaticFileResolver import be.simplenotes.app.views.components.* import be.simplenotes.types.PersistedNote import be.simplenotes.types.PersistedNoteMetadata import be.simplenotes.domain.security.JwtPayload import io.konform.validation.ValidationError import kotlinx.html.* class NoteView(staticFileResolver: StaticFileResolver) : View(staticFileResolver) { fun noteEditor( jwtPayload: JwtPayload, error: String? = null, textarea: String? = null, validationErrors: List = emptyList(), ) = renderPage(title = "New note", jwtPayload = jwtPayload) { div("container mx-auto p-4") { error?.let { alert(Alert.Warning, error) } validationErrors.forEach { alert(Alert.Warning, it.dataPath.substringAfter('.') + ": " + it.message) } form(method = FormMethod.post) { textArea { attributes.also { it["rows"] = "20" it["id"] = "markdown" it["name"] = "markdown" it["aria-label"] = "markdown text area" it["spellcheck"] = "false" } textarea?.let { +it } ?: +""" |--- |title: '' |tags: [] |--- | """.trimMargin("|") } submitButton("Save") } } } fun notes( jwtPayload: JwtPayload, notes: List, currentPage: Int, numberOfPages: Int, numberOfDeletedNotes: Int, tag: String?, ) = renderPage(title = "Notes", jwtPayload = jwtPayload) { div("container mx-auto p-4") { noteListHeader(numberOfDeletedNotes) if (notes.isNotEmpty()) noteTable(notes) else span { if (numberOfPages > 1) +"You went too far" else +"No notes yet" } if (numberOfPages > 1) pagination(currentPage, numberOfPages, tag) } } fun search( jwtPayload: JwtPayload, notes: List, query: String, numberOfDeletedNotes: Int, ) = renderPage("Notes", jwtPayload = jwtPayload) { div("container mx-auto p-4") { noteListHeader(numberOfDeletedNotes, query) noteTable(notes) } } fun trash( jwtPayload: JwtPayload, notes: List, currentPage: Int, numberOfPages: Int, ) = renderPage(title = "Notes", jwtPayload = jwtPayload) { div("container mx-auto p-4") { div("flex justify-between mb-4") { h1("text-2xl underline") { +"Deleted notes" } } if (notes.isNotEmpty()) deletedNoteTable(notes) else span { if (numberOfPages > 1) +"You went too far" else +"No deleted notes" } if (numberOfPages > 1) pagination(currentPage, numberOfPages, null) } } private fun DIV.pagination(currentPage: Int, numberOfPages: Int, tag: String?) { val links = mutableListOf>() // if (currentPage > 1) links += "Previous" to "?page=${currentPage - 1}" links += (1..numberOfPages).map { page -> "$page" to (tag?.let { "?page=$page&tag=$it" } ?: "?page=$page") } // if (currentPage < numberOfPages) links += "Next" to "?page=${currentPage + 1}" nav("pages") { links.forEach { (name, href) -> a(href, classes = if (name == currentPage.toString()) "active" else null) { +name } } } } fun renderedNote(jwtPayload: JwtPayload?, note: PersistedNote, shared: Boolean) = renderPage( note.meta.title, jwtPayload = jwtPayload, scripts = listOf("/highlight.10.1.2.js", "/init-highlight.0.0.1.js") ) { div("container mx-auto p-4") { if (shared) { p("p-4 bg-gray-800") { +"You are viewing a public note " } hr { } } div("flex items-center justify-between mb-4") { h1("text-3xl fond-bold underline") { +note.meta.title } span("space-x-2") { note.meta.tags.forEach { a(href = "/notes?tag=$it", classes = "tag") { +"#$it" } } } } if (!shared) { noteActionForm(note) if (note.public) { p("my-4") { +"You can share this link : " a(href = "/notes/public/${note.uuid}", classes = "text-blue-300 underline") { +"/notes/public/${note.uuid}" } } hr { } } } div { attributes["id"] = "note" unsafe { +note.html } } } } private fun DIV.noteActionForm(note: PersistedNote) { form(method = FormMethod.post, classes = "inline flex space-x-2 justify-end mb-4") { a( href = "/notes/${note.uuid}/edit", classes = "btn btn-green" ) { +"Edit" } span { button( type = ButtonType.submit, name = if (note.public) "private" else "public", classes = "font-semibold border-b-4 ${if (note.public) "border-teal-200" else "border-green-500"}" + " p-2 rounded-l bg-teal-200 text-gray-800" ) { +"Private" } button( type = ButtonType.submit, name = if (note.public) "private" else "public", classes = "font-semibold border-b-4 ${if (!note.public) "border-teal-200" else "border-green-500"}" + " p-2 rounded-r bg-teal-200 text-gray-800" ) { +"Public" } } button( type = ButtonType.submit, name = "delete", classes = "btn btn-red" ) { +"Delete" } } } }