improve display user badges

This commit is contained in:
SrGooglo 2023-07-12 17:14:10 +00:00
parent 1d98c33d7e
commit 9dce36f588
6 changed files with 142 additions and 99 deletions

View File

@ -0,0 +1,3 @@
<svg width="1em" height="1em" viewBox="0 0 248 248" fill="none" xmlns="http://www.w3.org/2000/svg">
<path id="icon" fill-rule="evenodd" clip-rule="evenodd" d="M37.938 1.777C30.587 5.524 19.514 19.874 11.914 35.5C-2.87402 65.906 -3.59402 100.339 9.89898 131.89C15.142 144.148 28.614 163.453 35.198 168.141C44.277 174.606 56.987 167.542 55.656 156.77C55.167 152.804 54.711 152.1 45.745 141.44C38.9 133.303 31.86 119.569 28.86 108.5C25.9 97.58 25.663 74.839 28.403 64.584C32.448 49.44 39.775 35.791 49.804 24.717C55.017 18.96 56.589 14.959 55.531 10.141C54.796 6.794 50.684 2.575 46.685 1.064C42.899 -0.367001 41.999 -0.294001 37.938 1.777ZM201 1.121C197.249 2.612 193.177 6.918 192.469 10.141C191.411 14.959 192.983 18.96 198.196 24.717C208.225 35.791 215.552 49.44 219.597 64.584C222.335 74.833 222.1 97.592 219.145 108.446C215.271 122.676 208.809 134.003 195.932 149.132C185.676 161.183 199.964 177.282 212.802 168.141C216.298 165.652 226.865 152.404 231.524 144.671C248.471 116.537 252.296 81.055 241.838 49C234.333 26 214.336 -0.409001 204.782 0.0629992C204.077 0.0979992 202.375 0.573999 201 1.121ZM67.313 40.891C63.175 43.492 57.754 54.669 54.994 66.291C52.644 76.181 52.228 91.226 54.028 101.152C56.186 113.058 62.901 127.664 68.82 133.33C74.705 138.963 84.165 137.303 88.231 129.923C90.701 125.439 90.095 120.929 86.116 114.189C76.511 97.921 75.655 79.438 83.68 61.621C87.985 52.063 87.858 47.397 83.167 42.706C79.207 38.746 72.034 37.925 67.313 40.891ZM167.299 40.96C163.663 43.176 161 47.649 161 51.538C161 52.989 162.605 57.827 164.567 62.288C172.122 79.473 171.661 94.064 163.005 111.696C157.489 122.932 157.141 124.93 159.827 129.938C162.854 135.582 169.597 138.244 175.339 136.061C182.163 133.467 190.982 116.799 194.077 100.646C196.984 85.479 194.279 64.854 187.514 50.598C182.296 39.602 175.129 36.185 167.299 40.96ZM116 61.537C101.954 65.898 94.933 82.724 101.381 96.571C103.959 102.108 109.582 107.377 114.723 109.073C117.629 110.033 117.923 110.457 117.321 112.827C116.949 114.297 111.635 135.525 105.512 160L94.381 204.5L81.441 205.041C67.271 205.633 64.181 206.619 59.659 211.994C56.49 215.76 55.671 219.809 56.152 229.335C56.464 235.51 56.969 237.271 59.313 240.344C64.609 247.287 61.816 247 124 247C186.184 247 183.391 247.287 188.687 240.344C191.031 237.271 191.536 235.51 191.848 229.335C192.329 219.809 191.51 215.76 188.341 211.994C183.819 206.619 180.729 205.633 166.559 205.041L153.619 204.5L141.874 157.518C135.415 131.678 130.213 110.515 130.315 110.489C130.417 110.462 132.088 109.721 134.029 108.842C143.441 104.578 148.973 95.927 148.99 85.446C149.008 74.225 142.003 64.584 131.568 61.471C125.582 59.685 121.913 59.701 116 61.537Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,23 @@
<svg width="1em" height="1em" viewBox="0 0 1837 1837" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_4_15)">
<path d="M380.565 0H0V380.565L537.935 918.5L0 1456.43V1837H380.565L918.5 1299.07L1456.43 1837H1837V1456.43L1299.07 918.5L1837 380.565V0H1456.43L918.5 537.935L380.565 0Z" fill="url(#paint0_linear_4_15)"/>
</g>
<defs>
<linearGradient id="paint0_linear_4_15" x1="918.5" y1="1837" x2="918.5" y2="0" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF8700"/>
<stop offset="0.03" stop-color="#FF8B09"/>
<stop offset="0.09" stop-color="#FF9723"/>
<stop offset="0.16" stop-color="#FFAB4C"/>
<stop offset="0.2" stop-color="#FFB664"/>
<stop offset="0.25" stop-color="#FFBF77"/>
<stop offset="0.35" stop-color="#FFD6A9"/>
<stop offset="0.49" stop-color="#FFFCF8"/>
<stop offset="0.5" stop-color="white"/>
<stop offset="0.8" stop-color="#0075BE"/>
<stop offset="0.99" stop-color="#005B97"/>
</linearGradient>
<clipPath id="clip0_4_15">
<rect width="1837" height="1837" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,47 +1,88 @@
import React from "react"
import * as antd from "antd"
import Loadable from "react-loadable"
import { createIconRender } from "components/Icons"
import { UserModel } from "models"
import "./index.less"
export default React.memo((props) => {
return React.createElement(Loadable({
loader: async () => {
let { user_id } = props
import DOMPurify from "dompurify"
import axios from "axios"
const badgesData = await UserModel.getUserBadges(user_id).catch((err) => {
console.error(err)
const RemoteSVG = (props) => {
// IMPORTANT: Only use this component for SVG files that you trust.
console.warn("RemoteSVGToComponent: This component is not safe at all, cause use __dangerouslySetInnerHTML. Only use it for SVG files that you trust.")
app.message.error("Failed to fetch user badges")
// make sure the url is local
if (!props.src.startsWith("/") && !props.remote) {
console.error("RemoteSVGToComponent: The file is not a local file.")
return () => null
}
return null
})
// make sure the file is a SVG
if (!props.src.endsWith(".svg")) {
console.error("RemoteSVGToComponent: The file is not a SVG.")
return () => null
}
if (!badgesData) {
return null
const [L_Badge, R_Badge, E_Badge] = app.cores.api.useRequest(async () => {
return await axios({
method: "GET",
url: props.src,
})
})
if (E_Badge || L_Badge) {
return <></>
}
return <div dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(R_Badge.data, {
USE_PROFILES: {
svg: true
}
})
}} />
}
return () => <div className="badges">
{
badgesData.map((badge, index) => {
return <antd.Tooltip placement="bottom" title={badge.description ?? "An badge"}>
<antd.Tag
color={badge.color ?? "default"}
key={index}
id={badge.name}
icon={createIconRender(badge.icon)}
className="badge"
>
<span>{badge.label}</span>
</antd.Tag>
</antd.Tooltip>
})
}
</div>
},
loading: antd.Skeleton,
}))
})
export default (props) => {
let { user_id } = props
const [L_Badges, R_Badges, E_Badges] = app.cores.api.useRequest(UserModel.getUserBadges, user_id)
if (E_Badges) {
return null
}
if (L_Badges) {
return null
}
if (!R_Badges) {
return null
}
return <div className="badges">
{
R_Badges.map((badge, index) => {
return <antd.Tooltip index={index} placement="bottom" title={badge.description ?? "An badge"}>
<div
key={index}
className="badge"
style={{
"--icon-color": badge.color ?? "var(--colorPrimary)"
}}
>
{
badge.iconUrl
? <RemoteSVG
src={badge.iconUrl}
/>
: createIconRender(badge.icon)
}
</div>
</antd.Tooltip>
})
}
</div>
}

View File

@ -16,17 +16,33 @@
.badges {
display: flex;
flex-direction: column;
flex-direction: row;
align-items: center;
height: fit-content;
gap: 7px;
.ant-tag {
display: inline-flex;
background-color: var(--background-color-primary);
border-radius: 12px;
padding: 7px 15px;
.badge {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
margin: 0 !important;
--outline-color: var(--icon-color);
svg {
font-size: 1rem;
margin: 0 !important;
color: var(--icon-color);
}
}
}

View File

@ -111,7 +111,7 @@ export const UserCard = React.forwardRef((props, ref) => {
</div>
<div className="username">
<div>
<div className="username_text">
<h1>
{user.fullName || user.username}
{user.verified && <Icons.verifiedBadge />}
@ -121,30 +121,7 @@ export const UserCard = React.forwardRef((props, ref) => {
</span>
</div>
<div className="indicators">
{
user.roles.includes("admin") &&
<antd.Tooltip title="Administrators Team">
<Icons.FaCertificate
style={{
fontSize: "1em",
}}
/>
</antd.Tooltip>
}
{
user.early_supporter &&
<antd.Tooltip title="Early supporter">
<Icons.MdLoyalty />
</antd.Tooltip>
}
{
user.roles.includes("internal_dev") &&
<antd.Tooltip title="Internal developer">
<Icons.MdCode />
</antd.Tooltip>
}
</div>
<UserBadges user_id={user._id} />
</div>
<div className="description">
@ -153,12 +130,6 @@ export const UserCard = React.forwardRef((props, ref) => {
</h3>
</div>
<div className="badges">
<React.Suspense fallback={<antd.Skeleton />}>
<UserBadges user_id={user._id} />
</React.Suspense>
</div>
{
user.links && Array.isArray(user.links) && user.links.length > 0 && <div className="userLinks">
{

View File

@ -273,28 +273,28 @@
flex-direction: row;
margin-top: 20px;
h1 {
display: inline-flex;
font-size: 1.5rem;
font-weight: 600;
font-family: "Space grotesk", sans-serif;
}
span {
font-size: 0.8rem;
font-style: italic;
}
svg {
fill: var(--app-color);
font-size: 0.8rem;
}
div {
.username_text {
display: flex;
flex-direction: column;
width: 100%;
h1 {
display: inline-flex;
font-size: 1.5rem;
font-weight: 600;
font-family: "Space grotesk", sans-serif;
}
span {
font-size: 0.8rem;
font-style: italic;
}
svg {
fill: var(--app-color);
font-size: 0.8rem;
}
}
.indicators {
@ -331,18 +331,7 @@
}
.badges {
display: flex;
flex-direction: row;
margin-top: 20px;
flex-wrap: wrap;
.badge {
margin-left: 5px;
margin-bottom: 5px;
}
justify-content: flex-end;
}
.userLinks {