(fix) Umbau zu SCS

This commit is contained in:
stefan
2025-07-19 11:26:09 +02:00
parent e1125a3fc0
commit e76db7e924
39 changed files with 1107 additions and 342 deletions
@@ -0,0 +1,24 @@
import at.mocode.events.ui.components.VeranstaltungsListe
import react.create
/**
* Main entry point for the JavaScript build.
*
* This function serves as the entry point for the Kotlin/JS application.
* It registers the React component as a web component using r2wc.
*/
fun main() {
console.log("Event Management JS module loaded successfully!")
// Import r2wc function from @r2wc/react-to-web-component npm package
val r2wc = js("require('@r2wc/react-to-web-component')")
// Convert React component to Web Component using r2wc
val VeranstaltungsListeWebComponent = r2wc(VeranstaltungsListe, js("{}"))
// Register the new component with a custom HTML tag
js("customElements.define('veranstaltungs-liste', arguments[0])")(VeranstaltungsListeWebComponent)
console.log("Web component 'veranstaltungs-liste' registered successfully!")
console.log("You can now use <veranstaltungs-liste></veranstaltungs-liste> in your HTML")
}
@@ -0,0 +1,176 @@
package at.mocode.events.ui.components
import at.mocode.events.domain.model.Veranstaltung
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.plugins.contentnegotiation.*
import io.ktor.client.request.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlinx.serialization.json.Json
import react.*
import react.dom.html.ReactHTML.div
import react.dom.html.ReactHTML.h1
import react.dom.html.ReactHTML.h3
import react.dom.html.ReactHTML.p
import react.dom.html.ReactHTML.span
import emotion.react.css
/**
* Props for the VeranstaltungsListe component
*/
external interface VeranstaltungsListeProps : Props
// Create Ktor client for API calls
private val apiClient = HttpClient {
install(ContentNegotiation) {
json(Json {
ignoreUnknownKeys = true
})
}
}
/**
* React component that displays a list of events (Veranstaltungen).
*
* This component loads event data from the API and renders it as HTML.
* Uses useState for state management and useEffectOnce for data loading.
*/
val VeranstaltungsListe = FC<VeranstaltungsListeProps> { _ ->
// State management with useState
var events by useState<List<Veranstaltung>>(emptyList())
var loading by useState(true)
var error by useState<String?>(null)
// Data loading with useEffectOnce hook
useEffectOnce {
val scope = MainScope()
scope.launch {
try {
loading = true
error = null
// Load data with Ktor client
val response = apiClient.get("http://localhost:8080/api/events")
val loadedEvents: List<Veranstaltung> = response.body()
events = loadedEvents
} catch (e: Exception) {
error = "Fehler beim Laden der Veranstaltungen: ${e.message}"
console.error("Error loading events:", e)
} finally {
loading = false
}
}
}
// Render HTML with React DOM elements
div {
css {
// Basic styling for the main container
}
h1 {
+"Veranstaltungen"
}
when {
loading -> {
div {
+"Lade Veranstaltungen..."
}
}
error != null -> {
div {
+error!!
}
}
events.isEmpty() -> {
div {
+"Keine Veranstaltungen verfügbar"
}
}
else -> {
div {
events.forEach { event ->
div {
h3 {
+event.name
}
p {
span {
+"📍"
}
+" ${event.ort}"
}
p {
span {
+"📅"
}
if (event.isMultiDay()) {
+" ${event.startDatum} - ${event.endDatum} (${event.getDurationInDays()} Tage)"
} else {
+" ${event.startDatum} (Eintägige Veranstaltung)"
}
}
// Status indicators
val statusList = mutableListOf<String>()
if (event.istAktiv) statusList.add("Aktiv")
if (event.istOeffentlich) statusList.add("Öffentlich")
if (event.isRegistrationOpen()) statusList.add("Anmeldung offen")
if (statusList.isNotEmpty()) {
p {
span {
+""
}
+" Status: ${statusList.joinToString(", ")}"
}
}
// Description
if (!event.beschreibung.isNullOrBlank()) {
p {
span {
+"📝"
}
+" ${event.beschreibung}"
}
}
// Sports/Sparten
if (event.sparten.isNotEmpty()) {
p {
span {
+"🏆"
}
+" Sparten: ${event.sparten.joinToString(", ") { it.name }}"
}
}
// Additional info
event.maxTeilnehmer?.let { max ->
p {
span {
+"👥"
}
+" Max. Teilnehmer: $max"
}
}
event.anmeldeschluss?.let { deadline ->
p {
span {
+""
}
+" Anmeldeschluss: $deadline"
}
}
}
}
}
}
}
}
}
@@ -1,4 +1,4 @@
package at.mocode.events.ui
package at.mocode.events.ui.utils
import at.mocode.events.domain.model.Veranstaltung
@@ -42,10 +42,3 @@ object EventUIUtils {
}
}
/**
* Main entry point for the JS application
*/
fun main() {
console.log("Event Management JS module loaded successfully!")
console.log("React dependencies are available for UI development")
}
@@ -11,6 +11,7 @@ import kotlinx.serialization.json.Json
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
import org.jetbrains.exposed.sql.statements.UpdateBuilder
/**
* Exposed-based implementation of VeranstaltungRepository.