mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-10 02:54:15 +00:00
display user links on UserCard
This commit is contained in:
parent
f34165c02c
commit
202528bce3
55
packages/app/constants/userLinksDecorators.js
Normal file
55
packages/app/constants/userLinksDecorators.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
export default {
|
||||||
|
"github": {
|
||||||
|
icon: "SiGithub",
|
||||||
|
label: "GitHub",
|
||||||
|
hrefResolve: "https://github.com/"
|
||||||
|
},
|
||||||
|
"twitter": {
|
||||||
|
icon: "SiTwitter",
|
||||||
|
label: "Twitter",
|
||||||
|
hrefResolve: "https://twitter.com/"
|
||||||
|
},
|
||||||
|
"instagram": {
|
||||||
|
icon: "SiInstagram",
|
||||||
|
label: "Instagram",
|
||||||
|
hrefResolve: "https://instagram.com/"
|
||||||
|
},
|
||||||
|
"facebook": {
|
||||||
|
icon: "SiFacebook",
|
||||||
|
label: "Facebook",
|
||||||
|
hrefResolve: "https://facebook.com/"
|
||||||
|
},
|
||||||
|
"youtube": {
|
||||||
|
icon: "SiYoutube",
|
||||||
|
label: "YouTube",
|
||||||
|
hrefResolve: "https://youtube.com/channel/"
|
||||||
|
},
|
||||||
|
"twitch": {
|
||||||
|
icon: "SiTwitch",
|
||||||
|
label: "Twitch",
|
||||||
|
hrefResolve: "https://twitch.tv/"
|
||||||
|
},
|
||||||
|
"linkedin": {
|
||||||
|
icon: "SiLinkedin",
|
||||||
|
label: "LinkedIn",
|
||||||
|
hrefResolve: "https://linkedin.com/in/"
|
||||||
|
},
|
||||||
|
"reddit": {
|
||||||
|
icon: "SiReddit",
|
||||||
|
label: "Reddit",
|
||||||
|
hrefResolve: "https://reddit.com/u/"
|
||||||
|
},
|
||||||
|
"vrchat": {
|
||||||
|
icon: "VrChat",
|
||||||
|
label: "VRChat",
|
||||||
|
hrefResolve: "https://vrchat.com/home/user/"
|
||||||
|
},
|
||||||
|
"discord": {
|
||||||
|
icon: "SiDiscord",
|
||||||
|
label: "Discord",
|
||||||
|
},
|
||||||
|
"custom": {
|
||||||
|
icon: "MdLink",
|
||||||
|
label: "Custom",
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,68 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
import * as antd from "antd"
|
import * as antd from "antd"
|
||||||
|
|
||||||
import { Icons } from "components/Icons"
|
import { Icons, createIconRender } from "components/Icons"
|
||||||
import { Image, UserBadges } from "components"
|
import { Image, UserBadges } from "components"
|
||||||
|
|
||||||
|
import linksDecorators from "schemas/userLinksDecorators"
|
||||||
|
|
||||||
import "./index.less"
|
import "./index.less"
|
||||||
|
|
||||||
|
function processValue(value, decorator) {
|
||||||
|
if (decorator.hrefResolve) {
|
||||||
|
if (!String(value).includes(decorator.hrefResolve)) {
|
||||||
|
return `${decorator.hrefResolve}${value}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
const UserLink = (props) => {
|
||||||
|
let { index, link } = props
|
||||||
|
|
||||||
|
link.key = link.key.toLowerCase()
|
||||||
|
|
||||||
|
const decorator = linksDecorators[link.key] ?? {}
|
||||||
|
|
||||||
|
link.value = processValue(link.value, decorator)
|
||||||
|
|
||||||
|
const hasHref = String(link.value).includes("://")
|
||||||
|
|
||||||
|
const handleOnClick = () => {
|
||||||
|
if (!hasHref) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
window.open(link.value, "_blank")
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderName = () => {
|
||||||
|
if (decorator.hrefResolve) {
|
||||||
|
return decorator.label ?? link.value
|
||||||
|
}
|
||||||
|
|
||||||
|
return link.value
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div
|
||||||
|
key={index}
|
||||||
|
id={`link-${index}-${link.key}`}
|
||||||
|
className={`userLink ${hasHref ? "clickable" : ""}`}
|
||||||
|
onClick={handleOnClick}
|
||||||
|
>
|
||||||
|
{
|
||||||
|
createIconRender(decorator.icon ?? "MdLink")
|
||||||
|
}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
{
|
||||||
|
renderName()
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
export default React.forwardRef((props, ref) => {
|
export default React.forwardRef((props, ref) => {
|
||||||
const [user, setUser] = React.useState(props.user)
|
const [user, setUser] = React.useState(props.user)
|
||||||
|
|
||||||
@ -36,7 +93,11 @@ export default React.forwardRef((props, ref) => {
|
|||||||
{
|
{
|
||||||
user.roles.includes("admin") &&
|
user.roles.includes("admin") &&
|
||||||
<antd.Tooltip title="Administrators Team">
|
<antd.Tooltip title="Administrators Team">
|
||||||
<Icons.MdAdminPanelSettings />
|
<Icons.FaCertificate
|
||||||
|
style={{
|
||||||
|
fontSize: "1em",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</antd.Tooltip>
|
</antd.Tooltip>
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
@ -45,6 +106,12 @@ export default React.forwardRef((props, ref) => {
|
|||||||
<Icons.MdLoyalty />
|
<Icons.MdLoyalty />
|
||||||
</antd.Tooltip>
|
</antd.Tooltip>
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
user.roles.includes("internal_dev") &&
|
||||||
|
<antd.Tooltip title="Internal developer">
|
||||||
|
<Icons.MdCode />
|
||||||
|
</antd.Tooltip>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -59,5 +126,15 @@ export default React.forwardRef((props, ref) => {
|
|||||||
<UserBadges user_id={user._id} />
|
<UserBadges user_id={user._id} />
|
||||||
</React.Suspense>
|
</React.Suspense>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{
|
||||||
|
user.links && Array.isArray(user.links) && user.links.length > 0 && <div className="userLinks">
|
||||||
|
{
|
||||||
|
user.links.map((link, index) => {
|
||||||
|
return <UserLink index={index} link={link} />
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
})
|
})
|
@ -120,4 +120,52 @@
|
|||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.userLinks {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
margin-top: 20px;
|
||||||
|
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
|
.userLink {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
|
gap: 5px;
|
||||||
|
|
||||||
|
transition: all 0.3s ease-in-out;
|
||||||
|
|
||||||
|
&.clickable {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
|
||||||
|
svg,
|
||||||
|
p {
|
||||||
|
color: var(--app-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-right: 0 !important;
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
font-family: "Space grotesk", sans-serif;
|
||||||
|
font-weight: 600;
|
||||||
|
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user