Skip to content

Commit 7501e3e

Browse files
authored
Added default avatar (#2947)
* Added default avatar
1 parent 11bdef0 commit 7501e3e

3 files changed

Lines changed: 84 additions & 9 deletions

File tree

cosv-frontend/src/main/kotlin/com/saveourtool/cosv/frontend/components/topbar/TopBarUserField.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package com.saveourtool.cosv.frontend.components.topbar
66

77
import com.saveourtool.frontend.common.components.basic.avatarRenderer
8+
import com.saveourtool.frontend.common.components.basic.renderTopBarAvatar
89
import com.saveourtool.frontend.common.components.modal.logoutModal
910
import com.saveourtool.frontend.common.externals.fontawesome.*
1011
import com.saveourtool.frontend.common.externals.i18next.useTranslation
@@ -19,7 +20,6 @@ import react.*
1920
import react.dom.aria.*
2021
import react.dom.html.ReactHTML.a
2122
import react.dom.html.ReactHTML.div
22-
import react.dom.html.ReactHTML.img
2323
import react.dom.html.ReactHTML.li
2424
import react.dom.html.ReactHTML.small
2525
import react.dom.html.ReactHTML.span
@@ -48,6 +48,7 @@ val topBarUserField: FC<UserInfoAwareProps> = FC { props ->
4848
val navigate = useNavigate()
4949
var isLogoutModalOpen by useState(false)
5050
var isAriaExpanded by useState(false)
51+
var (isError, setIsError) = useState(false)
5152

5253
ul {
5354
className = ClassName("navbar-nav ml-auto")
@@ -86,12 +87,14 @@ val topBarUserField: FC<UserInfoAwareProps> = FC { props ->
8687
}
8788
}
8889
}
89-
props.userInfo?.let { userInfo ->
90-
img {
91-
className =
92-
ClassName("ml-2 align-self-center avatar avatar-user width-full border color-bg-default rounded-circle fas mr-2")
93-
src = props.userInfo?.avatar?.avatarRenderer() ?: AVATAR_PROFILE_PLACEHOLDER
94-
style = logoSize
90+
props.userInfo?.let { it ->
91+
renderTopBarAvatar(
92+
it.avatar?.avatarRenderer() ?: AVATAR_PROFILE_PLACEHOLDER,
93+
"ml-2 align-self-center width-full fas mr-2",
94+
logoSize,
95+
isError,
96+
) {
97+
setIsError(true)
9598
}
9699
} ?: fontAwesomeIcon(icon = faUser) {
97100
it.className = "m-2 align-self-center fas fa-lg fa-fw mr-2 text-gray-400"

frontend-common/src/main/kotlin/com/saveourtool/frontend/common/components/basic/AvatarRenderers.kt

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import react.ChildrenBuilder
1818
import react.dom.html.ReactHTML.div
1919
import react.dom.html.ReactHTML.img
2020
import react.router.dom.Link
21+
import react.useState
2122
import web.cssom.ClassName
2223
import web.cssom.rem
2324

@@ -198,17 +199,81 @@ fun ChildrenBuilder.renderOrganizationWithName(
198199
}
199200
}
200201

202+
/**
203+
* Render organization avatar or placeholder
204+
*
205+
* @param organizationDto organization to render avatar
206+
* @param styleBuilder [CSSProperties] builder
207+
* @param errorAvatars
208+
* @param setErrorAvatars
209+
*/
210+
fun ChildrenBuilder.renderOrganizationAvatar(
211+
organizationDto: OrganizationDto,
212+
errorAvatars: Set<String>,
213+
setErrorAvatars: (String) -> Unit,
214+
styleBuilder: CSSProperties.() -> Unit = {},
215+
) {
216+
val avatarLink = organizationDto.avatar?.avatarRenderer() ?: AVATAR_ORGANIZATION_PLACEHOLDER
217+
val linkOrganization = "/${organizationDto.name}"
218+
219+
val renderImg: ChildrenBuilder.() -> Unit = {
220+
img {
221+
className = ClassName("avatar avatar-user border color-bg-default rounded-circle")
222+
src = if (errorAvatars.contains(organizationDto.name)) AVATAR_PROFILE_PLACEHOLDER else avatarLink
223+
style = jso { styleBuilder() }
224+
onError = {
225+
setErrorAvatars(organizationDto.name)
226+
}
227+
}
228+
}
229+
Link {
230+
to = linkOrganization
231+
renderImg()
232+
}
233+
}
234+
235+
/**
236+
* Render topBar avatar or placeholder
237+
*
238+
* @param avatarLink link to avatar
239+
* @param classes
240+
* @param styleBuilder [CSSProperties] builder
241+
* @param isError
242+
* @param setIsError
243+
*/
244+
fun ChildrenBuilder.renderTopBarAvatar(
245+
avatarLink: String,
246+
classes: String,
247+
styleBuilder: CSSProperties,
248+
isError: Boolean,
249+
setIsError: () -> Unit,
250+
) {
251+
img {
252+
className = ClassName("avatar avatar-user border color-bg-default rounded-circle $classes")
253+
src = if (!isError) avatarLink else AVATAR_PROFILE_PLACEHOLDER
254+
style = styleBuilder
255+
onError = {
256+
setIsError()
257+
}
258+
}
259+
}
260+
201261
private fun ChildrenBuilder.renderAvatar(
202262
avatarLink: String,
203263
classes: String,
204264
link: String?,
205265
styleBuilder: CSSProperties.() -> Unit,
206266
) {
267+
val (avatar, setAvatar) = useState(avatarLink)
268+
207269
val renderImg: ChildrenBuilder.() -> Unit = {
208270
img {
209271
className = ClassName("avatar avatar-user border color-bg-default rounded-circle $classes")
210-
src = avatarLink
272+
src = avatar
211273
style = jso { styleBuilder() }
274+
onError = {
275+
setAvatar(AVATAR_PROFILE_PLACEHOLDER)
276+
}
212277
}
213278
}
214279
link?.let {

frontend-common/src/main/kotlin/com/saveourtool/frontend/common/components/views/userprofile/UserProfileView.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package com.saveourtool.frontend.common.components.views.userprofile
66

77
import com.saveourtool.frontend.common.components.basic.renderAvatar
8+
import com.saveourtool.frontend.common.components.basic.renderOrganizationAvatar
89
import com.saveourtool.frontend.common.components.inputform.InputTypes
910
import com.saveourtool.frontend.common.components.modal.displayModal
1011
import com.saveourtool.frontend.common.components.modal.mediumTransparentModalStyle
@@ -47,6 +48,7 @@ val userProfileView: FC<UserProfileViewProps> = FC { props ->
4748
val (organizations, setOrganizations) = useState<List<OrganizationDto>>(emptyList())
4849
val (selectedMenu, setSelectedMenu) = useState(UserProfileTab.VULNERABILITIES)
4950
val (countUsers, setCountUsers) = useState(0)
51+
val (isError, setIsError) = useState(false)
5052

5153
useRequest {
5254
val userNew: UserInfo = get(
@@ -172,6 +174,7 @@ fun ChildrenBuilder.renderLeftUserMenu(
172174
) {
173175
val navigate = useNavigate()
174176
val banUserWindowOpenness = useWindowOpenness()
177+
val (errorAvatars, setErrorAvatars) = useState(emptySet<String>())
175178

176179
val banUser = useDeferredRequest {
177180
user?.name?.let {
@@ -369,7 +372,11 @@ fun ChildrenBuilder.renderLeftUserMenu(
369372
div {
370373
className = ClassName("row")
371374
organizations.forEach { organization ->
372-
renderAvatar(organization) {
375+
renderOrganizationAvatar(
376+
organization,
377+
errorAvatars = errorAvatars,
378+
setErrorAvatars = { name -> setErrorAvatars(errorAvatars.plus(name)) }
379+
) {
373380
width = 4.rem
374381
height = 4.rem
375382
}

0 commit comments

Comments
 (0)