Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
571f62e
Update libraries
Isti01 Feb 8, 2026
53ab65e
Changed api response types to custom enums
SzBeni2003 Feb 8, 2026
d597751
Tinder question api hooks
SzBeni2003 Feb 8, 2026
458cd8d
Tinder interaction api hook
SzBeni2003 Feb 12, 2026
d4d6421
get user tinder answers api and hook
SzBeni2003 Feb 12, 2026
b304845
type-only imports
SzBeni2003 Feb 12, 2026
ab8b01d
stuff
SzBeni2003 Feb 12, 2026
6f1fe6c
UserAnswerController
SzBeni2003 Feb 12, 2026
c928c73
TinderQuestions page
SzBeni2003 Feb 13, 2026
8c4abe1
stuff
SzBeni2003 Feb 13, 2026
d5de41c
TinderInteractionController
SzBeni2003 Feb 13, 2026
1ac1c05
tinder card (working buttons, ugly and not updating automatically)
SzBeni2003 Feb 13, 2026
be30cd7
Swipe animation
SzBeni2003 Feb 13, 2026
867db5c
Swiping
SzBeni2003 Feb 13, 2026
f675b4e
Handle touch swiping
SzBeni2003 Feb 13, 2026
b778de5
button for liked communities' list
SzBeni2003 Feb 13, 2026
287713e
Liked Communities' list
SzBeni2003 Feb 13, 2026
a04116b
tindercard
SzBeni2003 Feb 14, 2026
4f7d3c0
resortName updating at onEntityPreSave
SzBeni2003 Feb 14, 2026
0331a48
tindercard
SzBeni2003 Feb 14, 2026
5275a61
fix inconsistencies between api and admin controller
SzBeni2003 Feb 15, 2026
2e88dc5
search-bar
SzBeni2003 Feb 15, 2026
324205f
search-bar
SzBeni2003 Feb 15, 2026
2910986
Enhance responsiveness and layout of community and Tinder pages for m…
DankaMarci Feb 15, 2026
b1989d4
/tinder url redirecting based on answers given or not; buttons on pages
SzBeni2003 Feb 16, 2026
0de5c4a
fixie-wixie
albi005 Feb 15, 2026
f5442aa
fixes
Isti01 Feb 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class CommunitiesComponent(
fieldName = "Körök leírása", description = "Ez jelenik meg a körök lapon",
type = SettingType.LONG_TEXT_MARKDOWN)

final var seachEnabled by BooleanSettingRef(defaultValue = false, fieldName = "Keresés engedélyezése",
description = "Engedélyezi a körök közötti keresést")

/// -------------------------------------------------------------------------------------------------------------------

val resortGroup by SettingGroup(fieldName = "Reszortok")
Expand All @@ -57,6 +60,20 @@ class CommunitiesComponent(
fieldName = "Körök leírása", description = "Ez jelenik meg a körök lapon",
type = SettingType.LONG_TEXT_MARKDOWN)

final var seachEnabledResort by BooleanSettingRef(defaultValue = false, fieldName = "Keresés engedélyezése",
description = "Engedélyezi a reszortok közötti keresést")

///-------------------------------------------------------------------------------------------------------------------

val tinderGroup by SettingGroup(fieldName = "Tinder")

final var tinderEnabled by BooleanSettingRef(defaultValue = false, fieldName = "Tinder engedélyezése",
description = "Engedélyezi a körök és userek közötti tinder szerű párosítást")

final var minRoleTinder by MinRoleSettingRef(defaultValue = setOf(), fieldName = "Jogosultságok",
description = "Melyik roleokkal nyitható meg az oldal")


override fun getAdditionalMenus(role: RoleType): List<MenuSettingItem> {
val result = mutableListOf<MenuSettingItem>()
if (minRoleResort.isAvailableForRole(role) || role.isAdmin) {
Expand All @@ -66,6 +83,13 @@ class CommunitiesComponent(
visible = false, subMenu = false, external = false
))
}
if (tinderEnabled && (minRoleTinder.isAvailableForRole(role) || role.isAdmin)) {
result.add(MenuSettingItem(
this.javaClass.simpleName + "@tinder",
"Tinder", "/tinder", 0,
visible = false, subMenu = false, external = false
))
}
return result
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import kotlin.jvm.optionals.getOrNull
@ConditionalOnBean(CommunitiesComponent::class)
class CommunitiesController(
val tinderService: TinderService,
val organizationService: OrganizationService,
repo: CommunityRepository,
importService: ImportService,
adminMenuService: AdminMenuService,
Expand Down Expand Up @@ -99,7 +100,7 @@ class CommunitiesController(
wide = false
)

private val reader = objectMapper.readerFor(object: TypeReference<Map<Int, String>>(){})
private val reader = objectMapper.readerFor(object: TypeReference<Map<String, String>>(){})

@GetMapping("/tinder/show/{id}")
fun showTinderAnswers(@PathVariable id: Int, model: Model, auth: Authentication): String {
Expand Down Expand Up @@ -192,7 +193,7 @@ class CommunitiesController(
private fun getTinderEditComponent(communityId: Int): DashboardComponent {
val answerEntity = transactionManager.transaction(readOnly = true) { tinderService.getAnswerForCommunity(communityId).getOrNull() }
.let {
reader.readValue<Map<Int, String>>(it?.answers)
reader.readValue<Map<String, String>>(it?.answers)
}
?: return DashboardFormCard(
id = 3,
Expand All @@ -210,11 +211,11 @@ class CommunitiesController(
val formElements = mutableListOf<FormElement>()
for (question in questions) {
formElements.add(FormElement(
fieldName = "question_${question.id}",
fieldName = question.question,
label = question.question,
type = FormElementType.SELECT,
values = ","+question.answerOptions,
defaultValue = answerEntity[question.id] ?: ""
defaultValue = answerEntity[question.question] ?: ""
))
}

Expand Down Expand Up @@ -259,7 +260,7 @@ class CommunitiesController(
private fun getTinderShowComponent(communityId: Int): DashboardComponent {
val answerEntity = transactionManager.transaction(readOnly = true) { tinderService.getAnswerForCommunity(communityId).getOrNull() }
.let {
reader.readValue<Map<Int, String>>(it?.answers)
reader.readValue<Map<String, String>>(it?.answers)
}
?: return DashboardFormCard(
id = 3,
Expand All @@ -277,10 +278,10 @@ class CommunitiesController(
for (i in 0..<questions.size) {
val questionText = questions[i].question
formElements.add(FormElement(
fieldName = "question_$i",
fieldName = questionText,
label = questionText,
type = FormElementType.INFO_BOX,
values = answerEntity[questions[i].id] ?: "Nincs válasz"
values = answerEntity[questions[i].question] ?: "Nincs válasz"
))
}

Expand All @@ -300,4 +301,11 @@ class CommunitiesController(
tinderService.ensureCommunityAnswer(entity)
}

override fun onEntityPreSave(entity: CommunityEntity, auth: Authentication): Boolean {
val resName = organizationService.getOrganizationById(entity.resortId).map { it.name }
.getOrNull() ?: return false
entity.resortName = resName
return true
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@ package hu.bme.sch.cmsch.component.communities

import hu.bme.sch.cmsch.service.UserService
import hu.bme.sch.cmsch.util.getUserEntityFromDatabaseOrNull
import io.swagger.v3.oas.annotations.parameters.RequestBody
import hu.bme.sch.cmsch.util.getUserOrNull
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
import org.springframework.http.ResponseEntity
import org.springframework.security.core.Authentication
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.bind.annotation.*
import kotlin.jvm.optionals.getOrElse

@RestController
@RequestMapping("/api")
Expand All @@ -20,46 +16,52 @@ class CommunitiesTinderApiController(
private val userService: UserService
) {

@RequestMapping("/tinder/question")
@GetMapping("/tinder/question")
fun allQuestions(): List<TinderQuestionDto> {
return tinderService.getAllQuestions().map{ TinderQuestionDto(it) }
}

@PostMapping("/tinder/question")
@GetMapping("/tinder/question/answers")
fun getAnswers(auth: Authentication?): TinderAnswerStatus {
val user = auth?.getUserOrNull() ?: return TinderAnswerStatus()
val answer: Map<String, String> = tinderService.getAnswerMapForUser(user.id)
.getOrElse{return TinderAnswerStatus() }
return TinderAnswerStatus(answered = true, answer = answer)
}

@PostMapping("/tinder/question/answers")
fun submitAnswers(
auth: Authentication?,
@RequestBody answers: TinderAnswerDto
): ResponseEntity<Unit> {
val user = auth?.getUserEntityFromDatabaseOrNull(userService) ?: return ResponseEntity.status(401).build()
tinderService.submitAnswers(false, user, answers)
return ResponseEntity.ok().build()
@RequestBody data: Map<String, String>,
auth: Authentication?
): TinderAnswerResponseStatus {
val user = auth?.getUserOrNull()
?: return TinderAnswerResponseStatus.NO_PERMISSION
return tinderService.submitAnswers(false, user, data)
}

@PutMapping("/tinder/question")
@PutMapping("/tinder/question/answers")
fun updateAnswers(
auth: Authentication?,
@RequestBody answers: TinderAnswerDto
): ResponseEntity<Unit> {
val user = auth?.getUserEntityFromDatabaseOrNull(userService) ?: return ResponseEntity.status(401).build()
tinderService.submitAnswers(true, user, answers)
return ResponseEntity.ok().build()
@RequestBody answers: Map<String, String>,
auth: Authentication?
): TinderAnswerResponseStatus {
val user = auth?.getUserOrNull()
?: return TinderAnswerResponseStatus.NO_PERMISSION
return tinderService.submitAnswers(true, user, answers)
}

@GetMapping("tinder/communities")
fun getTinderCommunities(auth: Authentication?): ResponseEntity<List<CommunitiesTinderDto>> {
val user = auth?.getUserEntityFromDatabaseOrNull(userService) ?: return ResponseEntity.status(401).build()
val res = tinderService.getTinderCommunities(user)
return ResponseEntity.ok(res)
@GetMapping("/tinder/community")
fun getTinderCommunities(auth: Authentication?): List<CommunitiesTinderDto> {
val user = auth?.getUserEntityFromDatabaseOrNull(userService) ?: return emptyList()
return tinderService.getTinderCommunities(user)
}

@PostMapping("tinder/communities/interact")
@PostMapping("/tinder/community/interact")
fun interactWithCommunity(
auth: Authentication?,
@RequestBody interaction: TinderInteractionDto
): ResponseEntity<Unit> {
val user = auth?.getUserEntityFromDatabaseOrNull(userService) ?: return ResponseEntity.status(401).build()
tinderService.interactWithCommunity(user, interaction)
return ResponseEntity.ok().build()
): Boolean {
val user = auth?.getUserEntityFromDatabaseOrNull(userService) ?: return false
return tinderService.interactWithCommunity(user, interaction)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package hu.bme.sch.cmsch.component.communities

import hu.bme.sch.cmsch.controller.admin.OneDeepEntityPage
import hu.bme.sch.cmsch.controller.admin.calculateSearchSettings
import hu.bme.sch.cmsch.repository.ManualRepository
import hu.bme.sch.cmsch.service.*
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
import org.springframework.core.env.Environment
import org.springframework.stereotype.Controller
import org.springframework.transaction.PlatformTransactionManager
import org.springframework.web.bind.annotation.RequestMapping
import tools.jackson.databind.ObjectMapper
import java.util.Optional


@Controller
@RequestMapping("/admin/control/tinder-answer")
@ConditionalOnBean(CommunitiesComponent::class)
class TinderAnswerController(
val tinderService: TinderService,
repo: TinderAnswerRepository,
importService: ImportService,
adminMenuService: AdminMenuService,
component: CommunitiesComponent,
auditLog: AuditLogService,
objectMapper: ObjectMapper,
transactionManager: PlatformTransactionManager,
env: Environment,
storageService: StorageService
) : OneDeepEntityPage<TinderAnswerEntity>(
"tinder-answer",
TinderAnswerEntity::class, ::TinderAnswerEntity,
"Tinder válasz", "Tinder válaszok",
"Tinder válaszok kezelése",

transactionManager,
object: ManualRepository<TinderAnswerEntity, Int>(){
override fun findAll(): MutableIterable<TinderAnswerEntity> {
return repo.findAllWithUserIdNotNull()
}
override fun findById(id: Int): Optional<TinderAnswerEntity> {
return repo.findById(id)
}
override fun delete(entity: TinderAnswerEntity) {
repo.delete(entity)
}
},
importService,
adminMenuService,
storageService,
component,
auditLog,
objectMapper,
env,

showPermission = StaffPermissions.PERMISSION_SHOW_COMMUNITIES,
createPermission = StaffPermissions.PERMISSION_CREATE_COMMUNITIES,
editPermission = StaffPermissions.PERMISSION_EDIT_COMMUNITIES,
deletePermission = StaffPermissions.PERMISSION_DELETE_COMMUNITIES,

createEnabled = true,
editEnabled = true,
deleteEnabled = true,
importEnabled = false,
exportEnabled = false,

adminMenuIcon = "inbox",
adminMenuPriority = 4,

searchSettings = calculateSearchSettings<TinderAnswerEntity>(false),
) {
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package hu.bme.sch.cmsch.component.communities

import hu.bme.sch.cmsch.repository.EntityPageDataSource
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.CrudRepository
Expand All @@ -9,15 +10,15 @@ import java.util.*

@Repository
@ConditionalOnBean(CommunitiesComponent::class)
interface TinderAnswerRepository : CrudRepository<TinderAnswerEntity, Int> {
interface TinderAnswerRepository : CrudRepository<TinderAnswerEntity, Int>, EntityPageDataSource<TinderAnswerEntity, Int> {

fun findByCommunityId(communityId: Int): Optional<TinderAnswerEntity>
fun findByUserId(userId: Int): Optional<TinderAnswerEntity>

@Query("select t from TinderAnswerEntity t where t.communityId is not null")
fun findAllWithCommunityIdNotNull(): List<TinderAnswerEntity>
fun findAllWithCommunityIdNotNull(): MutableList<TinderAnswerEntity>

@Query("select t from TinderAnswerEntity t where t.userId is not null")
fun findAllWithUserIdNotNull(): List<TinderAnswerEntity>
fun findAllWithUserIdNotNull(): MutableList<TinderAnswerEntity>

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package hu.bme.sch.cmsch.component.communities

import hu.bme.sch.cmsch.admin.GenerateOverview
import hu.bme.sch.cmsch.admin.OverviewType
import hu.bme.sch.cmsch.model.IdentifiableEntity

data class TinderCommunityVirtualEntity(
@property:GenerateOverview(renderer = OverviewType.ID, columnName = "ID", order = -1)
override var id: Int,

@property:GenerateOverview(columnName = "Név", order = 1)
val name: String,

@property:GenerateOverview(columnName = "Jobbra húzva", order = 2)
val likes: Int,

@property:GenerateOverview(columnName = "Balra húzva", order = 3)
val dislikes: Int,

) : IdentifiableEntity
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,27 @@ package hu.bme.sch.cmsch.component.communities
data class TinderQuestionDto(
var id: Int = 0,
var question: String = "",
var answers: List<String> = emptyList()
var options: List<String> = emptyList()
) {
constructor(entity: TinderQuestionEntity) : this(
id = entity.id,
question = entity.question,
answers = entity.answerOptions.split(", *")
options = entity.answerOptions.split(",").map { it.trim() }
)
}

data class TinderAnswerDto(
var userId: Int? = null,
var answers: Map<Int, String> = emptyMap()
class TinderAnswerStatus(
var answered: Boolean = false,
var answer: Map<String, String> = emptyMap()
)

enum class TinderAnswerResponseStatus {
OK,
INVALID_ANSWER,
NO_PERMISSION,
ERROR
}

enum class TinderStatus{
NOT_SEEN,
LIKED,
Expand Down
Loading
Loading