package cc.essaenko.modules.news import io.ktor.http.* import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* import kotlinx.serialization.Serializable import cc.essaenko.shared.pagination.Page @Serializable data class NewsUpdateRequest( val title: String? = null, val slug: String? = null, val summary: String? = null, val content: String? = null, val status: String? = null, val imageUrl: String? = null, ) fun Route.adminNewsRoutes(svc: NewsService) = route("/admin/news") { get { val limit = call.request.queryParameters["limit"]?.toIntOrNull() ?: 50 val page = call.request.queryParameters["page"]?.toIntOrNull() ?: 1 if (page < 1) { return@get call.respond( HttpStatusCode.BadRequest, mapOf("error" to "page must be greater than 0") ) } val offset = (page - 1) * limit val pageData = svc.listAdmin(limit, offset) call.respond( Page( items = pageData.items.map { it.toDto() }, total = pageData.total, limit = pageData.limit, offset = pageData.offset ) ) } post { val payload = call.receive() val id = svc.create(payload) call.respond(mapOf("id" to id)) } put("{slug}") { val slug = call.parameters["slug"]!! val body = call.receive() val ok = svc.update(slug, body.toDomain()) call.respond(mapOf("updated" to ok)) } post("{slug}/publish") { val slug = call.parameters["slug"]!! val ok = svc.publish(slug) call.respond(mapOf("published" to ok)) } delete("{slug}") { val slug = call.parameters["slug"]!! val ok = svc.delete(slug) call.respond(mapOf("deleted" to ok)) } } fun Route.publicNewsRoutes(svc: NewsService) = route("/news") { get { val limit = call.request.queryParameters["limit"]?.toIntOrNull() ?: 20 val page = call.request.queryParameters["page"]?.toIntOrNull() ?: 1 if (page < 1) { return@get call.respond( HttpStatusCode.BadRequest, mapOf("error" to "page must be greater than 0") ) } val offset = (page - 1) * limit val pageData = svc.list(limit, offset) call.respond( Page( items = pageData.items.map { it.toDto() }, total = pageData.total, limit = pageData.limit, offset = pageData.offset ) ) } get("{slug}") { val slug = call.parameters["slug"]!! val item = svc.get(slug) call.respond(item.toDto()) } } private fun NewsUpdateRequest.toDomain() = NewsUpdate( title = title, slug = slug, summary = summary, content = content, status = status, imageUrl = imageUrl ) private fun News.toDto() = NewsDTO( id = id, title = title, content = content, imageUrl = imageUrl, slug = slug, summary = summary, publishedAt = publishedAt, status = status, )