Skip to content

Commit 3e49b47

Browse files
authored
feat: add social links to backoffice (#6911)
1 parent 4e8d10c commit 3e49b47

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

server/polar/web_backoffice/components/_description_list.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,91 @@ def get_currency(self, item: M) -> str:
258258
return getattr(item, "currency", "usd")
259259

260260

261+
class DescriptionListSocialsItem[M](DescriptionListItem[M]):
262+
"""A description list item that displays social links with platform icons.
263+
264+
This item displays social links from the model, including both the socials
265+
list and twitter_username field, with appropriate formatting and icons.
266+
267+
Args:
268+
M: Type parameter for the model type.
269+
"""
270+
271+
def render(self, request: Request, item: M) -> Generator[None] | None:
272+
"""Render social links with platform icons and external links.
273+
274+
Args:
275+
request: The FastAPI request object.
276+
item: The data object to render social links from.
277+
"""
278+
socials = getattr(item, "socials", [])
279+
twitter_username = getattr(item, "twitter_username", None)
280+
281+
with tag.div(classes="flex flex-col gap-2"):
282+
# Display Twitter/X username if available
283+
if twitter_username:
284+
with tag.div(classes="flex items-center gap-2"):
285+
with tag.span(classes="text-sm font-medium"):
286+
text("𝕏 (Twitter):")
287+
with tag.a(
288+
href=f"https://twitter.com/{twitter_username}",
289+
classes="link flex items-center gap-1",
290+
target="_blank",
291+
rel="noopener noreferrer",
292+
):
293+
text(f"@{twitter_username}")
294+
with tag.div(classes="icon-external-link"):
295+
pass
296+
297+
# Display social links from socials field
298+
if socials:
299+
for social in socials:
300+
platform = social.get("platform", "")
301+
url = social.get("url", "")
302+
if platform and url:
303+
with tag.div(classes="flex items-center gap-2"):
304+
with tag.span(classes="text-sm font-medium"):
305+
# Add platform-specific icons/emojis
306+
if platform.lower() in ["twitter", "x"]:
307+
text("𝕏:")
308+
elif platform.lower() == "github":
309+
text("GitHub:")
310+
elif platform.lower() == "linkedin":
311+
text("LinkedIn:")
312+
elif platform.lower() == "youtube":
313+
text("YouTube:")
314+
elif platform.lower() == "instagram":
315+
text("Instagram:")
316+
elif platform.lower() == "facebook":
317+
text("Facebook:")
318+
elif platform.lower() == "discord":
319+
text("Discord:")
320+
else:
321+
text(f"{platform.title()}:")
322+
with tag.a(
323+
href=url,
324+
classes="link flex items-center gap-1",
325+
target="_blank",
326+
rel="noopener noreferrer",
327+
):
328+
# Display the URL or just the platform name
329+
display_text = url
330+
if url.startswith("https://"):
331+
display_text = url[8:] # Remove https://
332+
elif url.startswith("http://"):
333+
display_text = url[7:] # Remove http://
334+
text(display_text)
335+
with tag.div(classes="icon-external-link"):
336+
pass
337+
338+
# Show message if no social links
339+
if not socials and not twitter_username:
340+
with tag.span(classes="text-gray-500 italic"):
341+
text("No social links available")
342+
343+
return None
344+
345+
261346
class DescriptionList[M]:
262347
"""A complete description list component for displaying structured data.
263348

server/polar/web_backoffice/organizations/endpoints.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,6 +1457,7 @@ async def get(
14571457
description_list.DescriptionListAttrItem(
14581458
"email", "Support email", clipboard=True
14591459
),
1460+
description_list.DescriptionListSocialsItem("Social Links"),
14601461
).render(request, organization):
14611462
pass
14621463
# Simple users table

0 commit comments

Comments
 (0)