sneakers routes
This commit is contained in:
parent
e360cab7b0
commit
1f9ddbe883
@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
<component name="GradleSettings">
|
<component name="GradleSettings">
|
||||||
<option name="linkedExternalProjectsSettings">
|
<option name="linkedExternalProjectsSettings">
|
||||||
<GradleProjectSettings>
|
<GradleProjectSettings>
|
||||||
|
@ -6,6 +6,7 @@ import io.ktor.server.netty.Netty
|
|||||||
import io.ktor.server.routing.route
|
import io.ktor.server.routing.route
|
||||||
import org.example.auth.authRoutes
|
import org.example.auth.authRoutes
|
||||||
import io.ktor.server.routing.routing
|
import io.ktor.server.routing.routing
|
||||||
|
import org.example.auth.sneakerRoutes
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
embeddedServer(Netty, port = 8080, host = "localhost") {
|
embeddedServer(Netty, port = 8080, host = "localhost") {
|
||||||
@ -19,6 +20,7 @@ fun Application.configureRouting() {
|
|||||||
routing {
|
routing {
|
||||||
route("/api") {
|
route("/api") {
|
||||||
authRoutes()
|
authRoutes()
|
||||||
|
sneakerRoutes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
96
src/main/kotlin/auth/SneakerRoutes.kt
Normal file
96
src/main/kotlin/auth/SneakerRoutes.kt
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package org.example.auth
|
||||||
|
|
||||||
|
import io.ktor.server.routing.Route
|
||||||
|
import io.ktor.server.routing.route
|
||||||
|
import org.example.data.DataRepository
|
||||||
|
import io.ktor.server.application.*
|
||||||
|
import io.ktor.server.auth.authenticate
|
||||||
|
import io.ktor.server.auth.jwt.JWTPrincipal
|
||||||
|
import io.ktor.server.auth.principal
|
||||||
|
import io.ktor.server.request.*
|
||||||
|
import io.ktor.server.response.*
|
||||||
|
import io.ktor.server.routing.*
|
||||||
|
import org.example.dto.requests.AddToCartRequest
|
||||||
|
import org.example.dto.responses.CartResponse
|
||||||
|
import org.example.dto.responses.FavoritesResponse
|
||||||
|
import org.example.dto.responses.OperationResponse
|
||||||
|
import org.example.dto.responses.SneakerResponse
|
||||||
|
|
||||||
|
fun Route.sneakerRoutes() {
|
||||||
|
route("/sneakers") {
|
||||||
|
get {
|
||||||
|
val sneakers = DataRepository.getAllSneakers()
|
||||||
|
call.respond(SneakerResponse(sneakers))
|
||||||
|
}
|
||||||
|
|
||||||
|
authenticate {
|
||||||
|
route("/favorites") {
|
||||||
|
get {
|
||||||
|
val userId = call.principal<JWTPrincipal>()?.payload?.getClaim("userId")?.asInt()
|
||||||
|
?: throw IllegalArgumentException("Invalid user")
|
||||||
|
|
||||||
|
val favoriteIds = DataRepository.getFavorites(userId)
|
||||||
|
val sneakers = favoriteIds.mapNotNull { DataRepository.getSneakerById(it) }
|
||||||
|
|
||||||
|
call.respond(FavoritesResponse(favoriteIds, sneakers))
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
val userId = call.principal<JWTPrincipal>()?.payload?.getClaim("userId")?.asInt()
|
||||||
|
?: throw IllegalArgumentException("Invalid user")
|
||||||
|
val sneakerId = call.request.queryParameters["sneakerId"]?.toIntOrNull()
|
||||||
|
?: throw IllegalArgumentException("Missing sneakerId")
|
||||||
|
|
||||||
|
val success = DataRepository.addToFavorites(userId, sneakerId)
|
||||||
|
call.respond(
|
||||||
|
OperationResponse(
|
||||||
|
success,
|
||||||
|
if (success) "Added to favorites" else "Failed to add to favorites"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
delete {
|
||||||
|
val userId = call.principal<JWTPrincipal>()?.payload?.getClaim("userId")?.asInt()
|
||||||
|
?: throw IllegalArgumentException("Invalid user")
|
||||||
|
val sneakerId = call.request.queryParameters["sneakerId"]?.toIntOrNull()
|
||||||
|
?: throw IllegalArgumentException("Missing sneakerId")
|
||||||
|
|
||||||
|
val success = DataRepository.removeFromFavorites(userId, sneakerId)
|
||||||
|
call.respond(OperationResponse(success, if (success) "Removed from favorites" else "Failed to remove from favorites"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
route("/cart") {
|
||||||
|
get {
|
||||||
|
val userId = call.principal<JWTPrincipal>()?.payload?.getClaim("userId")?.asInt()
|
||||||
|
?: throw IllegalArgumentException("Invalid user")
|
||||||
|
|
||||||
|
val cartItems = DataRepository.getCart(userId)
|
||||||
|
val sneakers = cartItems.mapNotNull { DataRepository.getSneakerById(it.sneakerId) }
|
||||||
|
|
||||||
|
call.respond(CartResponse(cartItems, sneakers))
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
val userId = call.principal<JWTPrincipal>()?.payload?.getClaim("userId")?.asInt()
|
||||||
|
?: throw IllegalArgumentException("Invalid user")
|
||||||
|
val request = call.receive<AddToCartRequest>()
|
||||||
|
|
||||||
|
val success = DataRepository.addToCart(userId, request.sneakerId, request.quantity)
|
||||||
|
call.respond(OperationResponse(success, if (success) "Added to cart" else "Failed to add to cart"))
|
||||||
|
}
|
||||||
|
|
||||||
|
delete {
|
||||||
|
val userId = call.principal<JWTPrincipal>()?.payload?.getClaim("userId")?.asInt()
|
||||||
|
?: throw IllegalArgumentException("Invalid user")
|
||||||
|
val sneakerId = call.request.queryParameters["sneakerId"]?.toIntOrNull()
|
||||||
|
?: throw IllegalArgumentException("Missing sneakerId")
|
||||||
|
|
||||||
|
val success = DataRepository.removeFromCart(userId, sneakerId)
|
||||||
|
call.respond(OperationResponse(success, if (success) "Removed from cart" else "Failed to remove from cart"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,11 @@
|
|||||||
package org.example.data
|
package org.example.data
|
||||||
|
|
||||||
|
import org.example.data.Models.CartItem
|
||||||
|
import org.example.data.Models.Sneaker
|
||||||
import org.example.dto.requests.SignInRequest
|
import org.example.dto.requests.SignInRequest
|
||||||
import org.example.dto.requests.SignUpRequest
|
import org.example.dto.requests.SignUpRequest
|
||||||
import org.example.data.Models.User
|
import org.example.data.Models.User
|
||||||
|
import org.example.data.Models.UserData
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
||||||
object DataRepository {
|
object DataRepository {
|
||||||
@ -10,6 +13,16 @@ object DataRepository {
|
|||||||
private val idCounter = AtomicInteger(1)
|
private val idCounter = AtomicInteger(1)
|
||||||
private val passwordResetCodes = mutableMapOf<String, String>()
|
private val passwordResetCodes = mutableMapOf<String, String>()
|
||||||
|
|
||||||
|
private val sneakers = mutableListOf(
|
||||||
|
Sneaker(1, "Nike Air Max", 179.39, "Nike", "outdoor", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSycZAb9c3gwov211CDjqS4n-RHt_4kAqDezw&s"),
|
||||||
|
Sneaker(2, "Adidas Ultraboost", 169.39, "Adidas", "outdoor", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSycZAb9c3gwov211CDjqS4n-RHt_4kAqDezw&s"),
|
||||||
|
Sneaker(3, "Puma RS-X", 159.39, "Puma", "tennis", "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSycZAb9c3gwov211CDjqS4n-RHt_4kAqDezw&s")
|
||||||
|
)
|
||||||
|
|
||||||
|
private val userData = mutableMapOf<Int, UserData>()
|
||||||
|
|
||||||
|
// ауф
|
||||||
|
|
||||||
fun createUser(request: SignUpRequest): User {
|
fun createUser(request: SignUpRequest): User {
|
||||||
val user = User(
|
val user = User(
|
||||||
id = idCounter.getAndIncrement(),
|
id = idCounter.getAndIncrement(),
|
||||||
@ -60,4 +73,49 @@ object DataRepository {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// кросовка
|
||||||
|
|
||||||
|
fun getAllSneakers(): List<Sneaker> = sneakers.toList()
|
||||||
|
|
||||||
|
fun getSneakerById(id: Int): Sneaker? = sneakers.find { it.id == id }
|
||||||
|
|
||||||
|
fun addToFavorites(userId: Int, sneakerId: Int): Boolean {
|
||||||
|
val sneaker = getSneakerById(sneakerId) ?: return false
|
||||||
|
val data = userData.getOrPut(userId) { UserData(userId) }
|
||||||
|
if (!data.favoriteSneakers.contains(sneakerId)) {
|
||||||
|
data.favoriteSneakers.add(sneakerId)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeFromFavorites(userId: Int, sneakerId: Int): Boolean {
|
||||||
|
return userData[userId]?.favoriteSneakers?.remove(sneakerId) ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addToCart(userId: Int, sneakerId: Int, quantity: Int = 1): Boolean {
|
||||||
|
val sneaker = getSneakerById(sneakerId) ?: return false
|
||||||
|
val data = userData.getOrPut(userId) { UserData(userId) }
|
||||||
|
val existingItem = data.cartItems.find { it.sneakerId == sneakerId }
|
||||||
|
|
||||||
|
if (existingItem != null) {
|
||||||
|
existingItem.quantity += quantity
|
||||||
|
} else {
|
||||||
|
data.cartItems.add(CartItem(sneakerId, quantity))
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun removeFromCart(userId: Int, sneakerId: Int): Boolean {
|
||||||
|
return userData[userId]?.cartItems?.removeIf { it.sneakerId == sneakerId } ?: false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getCart(userId: Int): List<CartItem> {
|
||||||
|
return userData[userId]?.cartItems?.toList() ?: emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getFavorites(userId: Int): List<Int> {
|
||||||
|
return userData[userId]?.favoriteSneakers?.toList() ?: emptyList()
|
||||||
|
}
|
||||||
}
|
}
|
9
src/main/kotlin/data/Models/CartItem.kt
Normal file
9
src/main/kotlin/data/Models/CartItem.kt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.example.data.Models
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CartItem(
|
||||||
|
val sneakerId: Int,
|
||||||
|
var quantity: Int
|
||||||
|
)
|
13
src/main/kotlin/data/Models/Sneaker.kt
Normal file
13
src/main/kotlin/data/Models/Sneaker.kt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package org.example.data.Models
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class Sneaker(
|
||||||
|
val id: Int,
|
||||||
|
val name: String,
|
||||||
|
val price: Double,
|
||||||
|
val brand: String,
|
||||||
|
val category: String,
|
||||||
|
val imageUrl: String
|
||||||
|
)
|
10
src/main/kotlin/data/Models/UserData.kt
Normal file
10
src/main/kotlin/data/Models/UserData.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package org.example.data.Models
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class UserData(
|
||||||
|
val userId: Int,
|
||||||
|
val favoriteSneakers: MutableList<Int> = mutableListOf(),
|
||||||
|
val cartItems: MutableList<CartItem> = mutableListOf()
|
||||||
|
)
|
9
src/main/kotlin/dto/requests/AddToCartRequest.kt
Normal file
9
src/main/kotlin/dto/requests/AddToCartRequest.kt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.example.dto.requests
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class AddToCartRequest(
|
||||||
|
val sneakerId: Int,
|
||||||
|
val quantity: Int = 1
|
||||||
|
)
|
11
src/main/kotlin/dto/responses/CartResponse.kt
Normal file
11
src/main/kotlin/dto/responses/CartResponse.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package org.example.dto.responses
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.example.data.Models.CartItem
|
||||||
|
import org.example.data.Models.Sneaker
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class CartResponse(
|
||||||
|
val items: List<CartItem>,
|
||||||
|
val sneakers: List<Sneaker>
|
||||||
|
)
|
10
src/main/kotlin/dto/responses/FavoritesResponse.kt
Normal file
10
src/main/kotlin/dto/responses/FavoritesResponse.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package org.example.dto.responses
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.example.data.Models.Sneaker
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class FavoritesResponse(
|
||||||
|
val sneakerIds: List<Int>,
|
||||||
|
val sneakers: List<Sneaker>
|
||||||
|
)
|
9
src/main/kotlin/dto/responses/OperationResponse.kt
Normal file
9
src/main/kotlin/dto/responses/OperationResponse.kt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.example.dto.responses
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class OperationResponse(
|
||||||
|
val success: Boolean,
|
||||||
|
val message: String? = null
|
||||||
|
)
|
9
src/main/kotlin/dto/responses/SneakerResponse.kt
Normal file
9
src/main/kotlin/dto/responses/SneakerResponse.kt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package org.example.dto.responses
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import org.example.data.Models.Sneaker
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class SneakerResponse(
|
||||||
|
val sneakers: List<Sneaker>
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user