Better Auction rendering for Auctions index

This commit is contained in:
2026-09-09 18:39:52 +03:00
parent eadf793882
commit b78fe7aeae
2 changed files with 27 additions and 19 deletions
+23 -8
View File
@@ -3,13 +3,13 @@ package controllers
import actors.auctions.AuctionPublisher import actors.auctions.AuctionPublisher
import controllers.authentication.AuthenticatedAction import controllers.authentication.AuthenticatedAction
import dao.{AuctionsDAO, AuthTokensDAO} import dao.{AuctionsDAO, AuthTokensDAO}
import models.Auction import models.AuctionStatus.Ready
import models.{Auction, User}
import org.apache.pekko.actor.typed.ActorRef import org.apache.pekko.actor.typed.ActorRef
import play.api.libs.functional.syntax.toFunctionalBuilderOps import play.api.libs.functional.syntax.toFunctionalBuilderOps
import play.api.libs.json.{JsError, JsPath, JsValue, Json, Reads, Writes} import play.api.libs.json.*
import play.api.mvc.{BaseController, ControllerComponents} import play.api.mvc.{BaseController, ControllerComponents}
import java.security.SecureRandom
import javax.inject.{Inject, Singleton} import javax.inject.{Inject, Singleton}
import scala.concurrent.{ExecutionContext, Future} import scala.concurrent.{ExecutionContext, Future}
@@ -21,6 +21,8 @@ class AuctionsController @Inject()(val controllerComponents: ControllerComponent
val auctionPublisher: ActorRef[AuctionPublisher.Command], val auctionPublisher: ActorRef[AuctionPublisher.Command],
implicit val ec: ExecutionContext) extends BaseController { implicit val ec: ExecutionContext) extends BaseController {
def index = authenticatedAction.async { implicit request => def index = authenticatedAction.async { implicit request =>
given Writes[Auction] = auctionWrites(request.user)
for { for {
auctions <- auctionsDAO.list_available(request.user) auctions <- auctionsDAO.list_available(request.user)
json = Json.toJson(auctions) json = Json.toJson(auctions)
@@ -35,15 +37,28 @@ class AuctionsController @Inject()(val controllerComponents: ControllerComponent
for { for {
auction <- auctionsDAO.create(auctionCreateData.name, auctionCreateData.startingPrice, request.user) auction <- auctionsDAO.create(auctionCreateData.name, auctionCreateData.startingPrice, request.user)
json = Json.toJson(auction) json = Json.toJson(auction)
response = Created(json)
_ = auctionPublisher ! AuctionPublisher.Publish(auction, request.user) _ = auctionPublisher ! AuctionPublisher.Publish(auction, request.user)
} yield response } yield Created(json)
} }
) )
} }
private case class AuctionCreateData(name: String, startingPrice: BigDecimal) private case class AuctionCreateData(name: String, startingPrice: BigDecimal)
private implicit val auctionCreateDataReads: Reads[AuctionCreateData] = (
(JsPath \ "name").read[String] and (JsPath \ "starting_price").read[BigDecimal] private given Reads[AuctionCreateData] = Json.reads[AuctionCreateData]
)(AuctionCreateData.apply)
private def auctionWrites(user: User): OWrites[Auction] = (o: Auction) => {
Json.toJsObject(o)(using Auction.writes) ++ Json.obj(
"actions" -> Json.obj(
"bid" -> (
(o.authorId != user.id.get) &&
(o.currentBidderId match {
case None => true // If there's no bidder, we can bid
case Some(bidderId) => bidderId != user.id.get
}) &&
(o.status == Ready)
)
)
)
}
} }
+4 -11
View File
@@ -1,6 +1,6 @@
package models package models
import play.api.libs.json.{JsValue, Json, Writes} import play.api.libs.json.{JsString, JsValue, Json, OWrites, Writes}
import java.time.Instant import java.time.Instant
@@ -24,6 +24,8 @@ enum AuctionStatus(val value: Short) {
object AuctionStatus { object AuctionStatus {
lazy val byValue: Map[Short, AuctionStatus] = Map.from(AuctionStatus.values.map{it => (it.value, it)}) lazy val byValue: Map[Short, AuctionStatus] = Map.from(AuctionStatus.values.map{it => (it.value, it)})
implicit val writes: Writes[AuctionStatus] = (o: AuctionStatus) => JsString(o.toString)
} }
case class Auction(id: Option[Int], name: String, status: AuctionStatus, gid: String, authorId: Int, case class Auction(id: Option[Int], name: String, status: AuctionStatus, gid: String, authorId: Int,
@@ -32,14 +34,5 @@ case class Auction(id: Option[Int], name: String, status: AuctionStatus, gid: St
createdAt: Instant) createdAt: Instant)
object Auction { object Auction {
implicit val writes: Writes[Auction] = (a: Auction) => Json.obj( implicit val writes: OWrites[Auction] = Json.writes[Auction]
"id" -> a.id,
"name" -> a.name,
"gid" -> a.gid,
"status" -> a.status.toString,
"starting_price" -> a.startingPrice,
"current_bid" -> a.currentBid,
"current_bidder_id" -> a.currentBidderId,
"current_bid_at" -> a.currentBidAt
)
} }