Redesign public user pages with new layout
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
Major improvements to public user page display: ✨ Layout changes: - Cover image moved to top, full-width stretch - User profile card made semi-transparent and overlaid - Cover placeholder when no image available - Fixed avatar display with fallback to initials 🎨 Design system alignment: - All layouts now match dashboard exactly (list, grid, cards, compact, sidebar) - Proper Fragment support for list layout expansion - Consistent group and link styling - Improved responsive design 📱 User experience: - Better visual hierarchy with cover → profile → content - Enhanced transparency effects with backdrop blur - Proper hover states and transitions - Statistics display (groups/links count) 🔧 Technical: - Added Fragment import for proper React rendering - Improved icon handling with icon_url consistency - Better error handling for missing images - Enhanced accessibility with proper alt text
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
import { notFound } from 'next/navigation'
|
import { notFound } from 'next/navigation'
|
||||||
import Image from 'next/image'
|
import Image from 'next/image'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState, Fragment } from 'react'
|
||||||
|
|
||||||
interface LinkItem {
|
interface LinkItem {
|
||||||
id: number
|
id: number
|
||||||
@@ -144,273 +144,262 @@ export default function UserPage({
|
|||||||
|
|
||||||
// Базовый список (по умолчанию)
|
// Базовый список (по умолчанию)
|
||||||
const renderListLayout = () => (
|
const renderListLayout = () => (
|
||||||
<div className="row">
|
<div className="card">
|
||||||
{data!.groups.map((group) => {
|
<div className="card-header">
|
||||||
const isExpanded = expandedGroups.has(group.id)
|
<h5 className="mb-0">Группы ссылок</h5>
|
||||||
return (
|
</div>
|
||||||
<div key={group.id} className="col-12 mb-4">
|
<div className="list-group list-group-flush">
|
||||||
<div className="card shadow-sm">
|
{data!.groups.map((group) => {
|
||||||
<div
|
const isExpanded = expandedGroups.has(group.id)
|
||||||
className="card-header d-flex align-items-center justify-content-between"
|
return (
|
||||||
onClick={() => toggleGroup(group.id)}
|
<Fragment key={group.id}>
|
||||||
style={{
|
<div className="list-group-item d-flex justify-content-between align-items-center">
|
||||||
backgroundColor: group.header_color || designSettings.theme_color + '20',
|
<div
|
||||||
borderColor: group.header_color || designSettings.theme_color,
|
className="d-flex align-items-center"
|
||||||
cursor: 'pointer'
|
style={{ cursor: 'pointer' }}
|
||||||
}}
|
onClick={() => toggleGroup(group.id)}
|
||||||
>
|
>
|
||||||
<div className="d-flex align-items-center flex-grow-1">
|
{group.icon_url && designSettings.show_group_icons && (
|
||||||
{designSettings.show_group_icons && group.icon && (
|
|
||||||
<img
|
<img
|
||||||
src={group.icon}
|
src={group.icon_url}
|
||||||
alt=""
|
|
||||||
width={32}
|
width={32}
|
||||||
height={32}
|
height={32}
|
||||||
className="me-2 rounded"
|
className="me-2 rounded"
|
||||||
|
alt={group.name}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<h5 className="mb-0 flex-grow-1" style={{ color: designSettings.group_text_color || designSettings.theme_color }}>
|
<strong className="me-2" style={{ color: designSettings.group_text_color || designSettings.theme_color }}>
|
||||||
{group.name}
|
{group.name}
|
||||||
</h5>
|
</strong>
|
||||||
<div className="d-flex align-items-center ms-2">
|
<span className="badge bg-secondary rounded-pill">
|
||||||
{group.is_favorite && (
|
{group.links.length}
|
||||||
<i className="bi bi-star-fill text-warning me-2" title="Избранная группа"></i>
|
</span>
|
||||||
)}
|
{group.is_favorite && (
|
||||||
<span
|
<i className="bi bi-star-fill text-warning ms-2" title="Избранная группа"></i>
|
||||||
className="badge rounded-pill me-2"
|
)}
|
||||||
style={{
|
|
||||||
backgroundColor: designSettings.theme_color,
|
|
||||||
color: 'white'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{group.links.length}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<i className={`bi ${isExpanded ? 'bi-chevron-up' : 'bi-chevron-down'} ms-2`}></i>
|
<i className={`bi ${isExpanded ? 'bi-chevron-up' : 'bi-chevron-down'}`}></i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isExpanded && (
|
{isExpanded && group.links.length > 0 && (
|
||||||
<div
|
<div className="list-group-item bg-light">
|
||||||
className="card-body"
|
<div className="row g-2">
|
||||||
style={{
|
{group.links.map((link) => (
|
||||||
backgroundImage: group.background_image ? `url(${group.background_image})` : 'none',
|
<div key={link.id} className="col-12 col-md-6 col-lg-4">
|
||||||
backgroundSize: 'cover',
|
<Link
|
||||||
backgroundPosition: 'center'
|
href={link.url}
|
||||||
}}
|
target="_blank"
|
||||||
>
|
rel="noopener noreferrer"
|
||||||
{group.description && (
|
className="d-block text-decoration-none"
|
||||||
<p className="text-muted mb-3">{group.description}</p>
|
>
|
||||||
)}
|
<div className="border rounded p-2 h-100 hover-shadow"
|
||||||
{group.links.length > 0 ? (
|
style={{
|
||||||
<div className="row">
|
borderColor: designSettings.theme_color + '40',
|
||||||
{group.links.map((link) => (
|
transition: 'all 0.2s ease'
|
||||||
<div key={link.id} className="col-12 col-md-6 col-lg-4 mb-3">
|
}}
|
||||||
<Link
|
|
||||||
href={link.url}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="d-block text-decoration-none"
|
|
||||||
>
|
>
|
||||||
<div className="card h-100 shadow-sm border-start border-3 hover-shadow"
|
<div className="d-flex align-items-center">
|
||||||
style={{
|
{designSettings.show_link_icons && link.icon_url && (
|
||||||
borderColor: designSettings.theme_color + '60',
|
<img
|
||||||
cursor: 'pointer',
|
src={link.icon_url}
|
||||||
transition: 'all 0.2s ease'
|
width={20}
|
||||||
}}
|
height={20}
|
||||||
>
|
className="me-2 rounded"
|
||||||
<div className="card-body d-flex align-items-center">
|
alt={link.title}
|
||||||
{designSettings.show_link_icons && link.icon_url && (
|
/>
|
||||||
<Image
|
)}
|
||||||
src={link.icon_url}
|
<div className="flex-grow-1">
|
||||||
alt=""
|
<h6 className="mb-0 small" style={{ color: designSettings.link_text_color || designSettings.theme_color }}>
|
||||||
width={24}
|
{link.title}
|
||||||
height={24}
|
</h6>
|
||||||
className="me-2 rounded"
|
{link.description && (
|
||||||
priority
|
<small className="text-muted d-block text-truncate">{link.description}</small>
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
<div className="flex-grow-1">
|
|
||||||
<h6 className="card-title mb-1" style={{ color: designSettings.link_text_color || designSettings.theme_color }}>
|
|
||||||
{link.title}
|
|
||||||
</h6>
|
|
||||||
{link.description && (
|
|
||||||
<p className="card-text small text-muted mb-0">{link.description}</p>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</div>
|
||||||
</div>
|
</Link>
|
||||||
))}
|
</div>
|
||||||
</div>
|
))}
|
||||||
) : (
|
</div>
|
||||||
<p className="text-muted mb-0">
|
|
||||||
В этой группе пока нет ссылок.
|
|
||||||
</p>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</Fragment>
|
||||||
</div>
|
)
|
||||||
)
|
})}
|
||||||
})}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
// Сетка групп
|
// Сетка групп
|
||||||
const renderGridLayout = () => (
|
const renderGridLayout = () => (
|
||||||
<div className="row">
|
<div>
|
||||||
{data!.groups.map((group) => (
|
<div className="d-flex justify-content-between align-items-center mb-3">
|
||||||
<div key={group.id} className="col-12 col-md-6 col-lg-4 mb-4">
|
<h5 className="mb-0">Группы ссылок</h5>
|
||||||
<div className="card h-100 shadow-sm">
|
</div>
|
||||||
<div
|
<div className="row g-3">
|
||||||
className="card-header text-center"
|
{data!.groups.map((group) => (
|
||||||
style={{
|
<div key={group.id} className="col-md-6 col-lg-4">
|
||||||
backgroundColor: group.header_color || designSettings.theme_color + '20',
|
<div className="card h-100">
|
||||||
borderColor: group.header_color || designSettings.theme_color
|
<div className="card-header d-flex justify-content-between align-items-center">
|
||||||
}}
|
<div className="d-flex align-items-center">
|
||||||
>
|
{group.icon_url && designSettings.show_group_icons && (
|
||||||
{designSettings.show_group_icons && group.icon && (
|
<img
|
||||||
<img
|
src={group.icon_url}
|
||||||
src={group.icon}
|
width={24}
|
||||||
alt=""
|
height={24}
|
||||||
width={40}
|
className="me-2 rounded"
|
||||||
height={40}
|
alt={group.name}
|
||||||
className="rounded-circle mb-2"
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
<h6 className="mb-0" style={{ color: designSettings.group_text_color || designSettings.theme_color }}>
|
||||||
<h6 className="mb-0" style={{ color: designSettings.group_text_color || designSettings.theme_color }}>
|
{group.name}
|
||||||
{group.name}
|
</h6>
|
||||||
</h6>
|
{group.is_favorite && (
|
||||||
{group.is_favorite && (
|
<i className="bi bi-star-fill text-warning ms-2"></i>
|
||||||
<i className="bi bi-star-fill text-warning mt-1"></i>
|
)}
|
||||||
)}
|
</div>
|
||||||
</div>
|
<span className="badge bg-secondary rounded-pill">
|
||||||
<div
|
{group.links.length}
|
||||||
className="card-body"
|
</span>
|
||||||
style={{
|
|
||||||
backgroundImage: group.background_image ? `url(${group.background_image})` : 'none',
|
|
||||||
backgroundSize: 'cover',
|
|
||||||
backgroundPosition: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{group.description && (
|
|
||||||
<p className="text-muted small mb-3">{group.description}</p>
|
|
||||||
)}
|
|
||||||
<div className="d-grid gap-2">
|
|
||||||
{group.links.map((link) => (
|
|
||||||
<Link
|
|
||||||
key={link.id}
|
|
||||||
href={link.url}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="btn btn-outline-primary btn-sm d-flex align-items-center"
|
|
||||||
style={{
|
|
||||||
borderColor: designSettings.theme_color,
|
|
||||||
color: designSettings.link_text_color || designSettings.theme_color
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{designSettings.show_link_icons && link.icon && (
|
|
||||||
<img
|
|
||||||
src={link.icon}
|
|
||||||
alt=""
|
|
||||||
width={16}
|
|
||||||
height={16}
|
|
||||||
className="me-2 rounded"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{link.title}
|
|
||||||
</Link>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div className="card-body"
|
||||||
</div>
|
style={{
|
||||||
</div>
|
backgroundImage: group.background_image ? `url(${group.background_image})` : 'none',
|
||||||
))}
|
backgroundSize: 'cover',
|
||||||
</div>
|
backgroundPosition: 'center'
|
||||||
)
|
}}
|
||||||
|
>
|
||||||
// Карточки (большие карточки с описанием)
|
|
||||||
const renderCardsLayout = () => (
|
|
||||||
<div className="row">
|
|
||||||
{data!.groups.map((group) => (
|
|
||||||
<div key={group.id} className="col-12 col-lg-6 mb-4">
|
|
||||||
<div className="card h-100 shadow">
|
|
||||||
<div
|
|
||||||
className="card-header d-flex align-items-center"
|
|
||||||
style={{
|
|
||||||
backgroundColor: group.header_color || designSettings.theme_color + '20',
|
|
||||||
borderColor: group.header_color || designSettings.theme_color
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{designSettings.show_group_icons && group.icon && (
|
|
||||||
<img
|
|
||||||
src={group.icon}
|
|
||||||
alt=""
|
|
||||||
width={48}
|
|
||||||
height={48}
|
|
||||||
className="me-3 rounded"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div>
|
|
||||||
<h5 className="mb-1" style={{ color: designSettings.group_text_color || designSettings.theme_color }}>
|
|
||||||
{group.name}
|
|
||||||
</h5>
|
|
||||||
{group.description && (
|
{group.description && (
|
||||||
<p className="text-muted mb-0 small">{group.description}</p>
|
<p className="text-muted small mb-3">{group.description}</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
<div className="d-grid gap-2">
|
||||||
{group.is_favorite && (
|
{group.links.slice(0, 5).map((link) => (
|
||||||
<i className="bi bi-star-fill text-warning ms-auto"></i>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="card-body"
|
|
||||||
style={{
|
|
||||||
backgroundImage: group.background_image ? `url(${group.background_image})` : 'none',
|
|
||||||
backgroundSize: 'cover',
|
|
||||||
backgroundPosition: 'center'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="row">
|
|
||||||
{group.links.map((link) => (
|
|
||||||
<div key={link.id} className="col-12 col-md-6 mb-2">
|
|
||||||
<Link
|
<Link
|
||||||
|
key={link.id}
|
||||||
href={link.url}
|
href={link.url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="d-flex align-items-center p-2 border rounded text-decoration-none hover-shadow"
|
className="btn btn-outline-primary btn-sm d-flex align-items-center justify-content-start"
|
||||||
style={{
|
style={{
|
||||||
borderColor: designSettings.theme_color + '40',
|
borderColor: designSettings.theme_color,
|
||||||
color: designSettings.link_text_color || designSettings.theme_color
|
color: designSettings.link_text_color || designSettings.theme_color
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{designSettings.show_link_icons && link.icon && (
|
{designSettings.show_link_icons && link.icon_url && (
|
||||||
<img
|
<img
|
||||||
src={link.icon}
|
src={link.icon_url}
|
||||||
alt=""
|
width={16}
|
||||||
width={24}
|
height={16}
|
||||||
height={24}
|
|
||||||
className="me-2 rounded"
|
className="me-2 rounded"
|
||||||
|
alt={link.title}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<div>
|
<span className="text-truncate">{link.title}</span>
|
||||||
<h6 className="mb-0" style={{ color: designSettings.link_text_color || designSettings.theme_color }}>
|
|
||||||
{link.title}
|
|
||||||
</h6>
|
|
||||||
{link.description && (
|
|
||||||
<small className="text-muted">{link.description}</small>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
))}
|
||||||
))}
|
{group.links.length > 5 && (
|
||||||
|
<small className="text-muted text-center">+{group.links.length - 5} еще...</small>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
))}
|
||||||
))}
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
// Карточки (большие карточки с описанием)
|
||||||
|
const renderCardsLayout = () => (
|
||||||
|
<div>
|
||||||
|
<div className="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h5 className="mb-0">Группы ссылок</h5>
|
||||||
|
</div>
|
||||||
|
<div className="row g-4">
|
||||||
|
{data!.groups.map((group) => (
|
||||||
|
<div key={group.id} className="col-12">
|
||||||
|
<div className="card shadow-sm">
|
||||||
|
<div className="card-header bg-light">
|
||||||
|
<div className="row align-items-center">
|
||||||
|
<div className="col">
|
||||||
|
<div className="d-flex align-items-center">
|
||||||
|
{group.icon_url && designSettings.show_group_icons && (
|
||||||
|
<img
|
||||||
|
src={group.icon_url}
|
||||||
|
width={40}
|
||||||
|
height={40}
|
||||||
|
className="me-3 rounded"
|
||||||
|
alt={group.name}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div>
|
||||||
|
<h5 className="mb-1" style={{ color: designSettings.group_text_color || designSettings.theme_color }}>
|
||||||
|
{group.name}
|
||||||
|
</h5>
|
||||||
|
<div className="d-flex align-items-center">
|
||||||
|
<small className="text-muted me-2">{group.links.length} ссылок</small>
|
||||||
|
{group.is_favorite && (
|
||||||
|
<i className="bi bi-star-fill text-warning" title="Избранная группа"></i>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="card-body"
|
||||||
|
style={{
|
||||||
|
backgroundImage: group.background_image ? `url(${group.background_image})` : 'none',
|
||||||
|
backgroundSize: 'cover',
|
||||||
|
backgroundPosition: 'center'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{group.description && (
|
||||||
|
<p className="text-muted mb-3">{group.description}</p>
|
||||||
|
)}
|
||||||
|
<div className="row g-3">
|
||||||
|
{group.links.map((link) => (
|
||||||
|
<div key={link.id} className="col-md-6 col-lg-4">
|
||||||
|
<Link
|
||||||
|
href={link.url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="d-block text-decoration-none"
|
||||||
|
>
|
||||||
|
<div className="border rounded p-3 h-100 hover-shadow"
|
||||||
|
style={{
|
||||||
|
borderColor: designSettings.theme_color + '40',
|
||||||
|
transition: 'all 0.2s ease'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="d-flex align-items-center mb-2">
|
||||||
|
{link.icon_url && designSettings.show_link_icons && (
|
||||||
|
<img
|
||||||
|
src={link.icon_url}
|
||||||
|
width={20}
|
||||||
|
height={20}
|
||||||
|
className="me-2 rounded"
|
||||||
|
alt={link.title}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<h6 className="mb-0" style={{ color: designSettings.link_text_color || designSettings.theme_color }}>
|
||||||
|
{link.title}
|
||||||
|
</h6>
|
||||||
|
</div>
|
||||||
|
{link.description && (
|
||||||
|
<small className="text-muted d-block">{link.description}</small>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -636,18 +625,59 @@ export default function UserPage({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<main style={containerStyle}>
|
<main style={containerStyle}>
|
||||||
|
<div className="container-fluid px-0">
|
||||||
|
{/* Обложка пользователя - растягиваем на всю ширину экрана */}
|
||||||
|
{data.cover && (
|
||||||
|
<div className="position-relative mb-4" style={{ height: '300px' }}>
|
||||||
|
<Image
|
||||||
|
src={data.cover}
|
||||||
|
alt="Обложка"
|
||||||
|
fill
|
||||||
|
className="object-cover"
|
||||||
|
style={{ objectFit: 'cover' }}
|
||||||
|
priority
|
||||||
|
/>
|
||||||
|
{/* Cover overlay если включен */}
|
||||||
|
{designSettings.cover_overlay_enabled && (
|
||||||
|
<div
|
||||||
|
className="position-absolute top-0 start-0 w-100 h-100"
|
||||||
|
style={{
|
||||||
|
backgroundColor: designSettings.cover_overlay_color || '#000000',
|
||||||
|
opacity: designSettings.cover_overlay_opacity || 0.3,
|
||||||
|
pointerEvents: 'none'
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Если обложки нет, показываем плашку */}
|
||||||
|
{!data.cover && (
|
||||||
|
<div
|
||||||
|
className="position-relative mb-4 d-flex align-items-center justify-content-center text-white"
|
||||||
|
style={{
|
||||||
|
height: '300px',
|
||||||
|
backgroundColor: designSettings.theme_color || '#6c757d',
|
||||||
|
backgroundImage: 'linear-gradient(135deg, rgba(0,0,0,0.1) 0%, rgba(255,255,255,0.1) 100%)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<h2 className="mb-0 fw-bold opacity-75">Обложка</h2>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="container">
|
<div className="container">
|
||||||
{/* Профиль пользователя */}
|
{/* Профиль пользователя - полупрозрачный */}
|
||||||
<div className="row justify-content-center mb-5">
|
<div className="row justify-content-center" style={{ marginTop: '-100px', position: 'relative', zIndex: 10 }}>
|
||||||
<div className="col-12 col-md-8 col-lg-6">
|
<div className="col-12 col-md-8 col-lg-6">
|
||||||
<div className="card shadow-lg border-0" style={{
|
<div className="card shadow-lg border-0" style={{
|
||||||
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
backgroundColor: 'rgba(255, 255, 255, 0.85)',
|
||||||
backdropFilter: 'blur(10px)',
|
backdropFilter: 'blur(15px)',
|
||||||
borderRadius: '20px'
|
borderRadius: '20px'
|
||||||
}}>
|
}}>
|
||||||
<div className="card-body text-center p-4">
|
<div className="card-body text-center p-4">
|
||||||
{/* Аватар пользователя */}
|
{/* Аватар пользователя */}
|
||||||
{data.avatar && (
|
{data.avatar ? (
|
||||||
<div className="mb-3 position-relative d-inline-block">
|
<div className="mb-3 position-relative d-inline-block">
|
||||||
<Image
|
<Image
|
||||||
src={data.avatar}
|
src={data.avatar}
|
||||||
@@ -670,6 +700,30 @@ export default function UserPage({
|
|||||||
}}
|
}}
|
||||||
></div>
|
></div>
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="mb-3 position-relative d-inline-block">
|
||||||
|
<div
|
||||||
|
className="rounded-circle border border-4 shadow-sm d-flex align-items-center justify-content-center"
|
||||||
|
style={{
|
||||||
|
width: '120px',
|
||||||
|
height: '120px',
|
||||||
|
backgroundColor: designSettings.theme_color || '#6c757d',
|
||||||
|
borderColor: designSettings.theme_color,
|
||||||
|
color: 'white',
|
||||||
|
fontSize: '3rem'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{(data.full_name || data.username).charAt(0).toUpperCase()}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="position-absolute bottom-0 end-0 rounded-circle border border-2 border-white"
|
||||||
|
style={{
|
||||||
|
width: '24px',
|
||||||
|
height: '24px',
|
||||||
|
backgroundColor: designSettings.theme_color
|
||||||
|
}}
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Имя пользователя */}
|
{/* Имя пользователя */}
|
||||||
@@ -707,37 +761,8 @@ export default function UserPage({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Обложка пользователя если есть */}
|
|
||||||
{data.cover && (
|
|
||||||
<div className="row justify-content-center mb-4">
|
|
||||||
<div className="col-12 col-lg-10">
|
|
||||||
<div className="card border-0 shadow position-relative">
|
|
||||||
<Image
|
|
||||||
src={data.cover}
|
|
||||||
alt="Обложка"
|
|
||||||
width={800}
|
|
||||||
height={300}
|
|
||||||
className="card-img rounded"
|
|
||||||
style={{ objectFit: 'cover', maxHeight: '300px' }}
|
|
||||||
/>
|
|
||||||
{/* Cover overlay если включен */}
|
|
||||||
{designSettings.cover_overlay_enabled && (
|
|
||||||
<div
|
|
||||||
className="position-absolute top-0 start-0 w-100 h-100 rounded"
|
|
||||||
style={{
|
|
||||||
backgroundColor: designSettings.cover_overlay_color || '#000000',
|
|
||||||
opacity: designSettings.cover_overlay_opacity || 0.3,
|
|
||||||
pointerEvents: 'none'
|
|
||||||
}}
|
|
||||||
></div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Группы ссылок */}
|
{/* Группы ссылок */}
|
||||||
<div className="row justify-content-center">
|
<div className="row justify-content-center mt-5">
|
||||||
<div className="col-12">
|
<div className="col-12">
|
||||||
{renderGroupsLayout()}
|
{renderGroupsLayout()}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user