monacousa-portal/pages/profile/mockup.vue

1345 lines
29 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="profile-mockup">
<!-- Admin Header -->
<div
v-motion
:initial="{ opacity: 0, y: -20 }"
:enter="{ opacity: 1, y: 0 }"
class="profile-header"
>
<div class="profile-header__background">
<div class="profile-header__gradient"></div>
</div>
<div class="profile-header__content">
<div class="profile-header__avatar-section">
<div class="profile-avatar">
<img
v-if="profile.avatar"
:src="profile.avatar"
:alt="profile.name"
/>
<div v-else class="profile-avatar__placeholder">
{{ initials }}
</div>
</div>
<div class="member-status-badge">
<span
class="status-indicator"
:class="`status-indicator--${profile.memberStatus}`"
></span>
<span class="status-text">{{ profile.memberStatus }}</span>
</div>
</div>
<div class="profile-header__info">
<h1 class="profile-name">{{ profile.name }}</h1>
<p class="profile-title">{{ profile.title }} at {{ profile.company }}</p>
<p class="profile-member-id">Member ID: #{{ profile.memberId }}</p>
<div class="profile-badges">
<span
class="badge"
:class="`badge--${profile.memberStatus}`"
>
{{ profile.memberStatus }} Member
</span>
<span
class="badge"
:class="`badge--${profile.duesStatus}`"
>
Dues: {{ profile.duesStatus }}
</span>
<span class="badge badge--year">Joined {{ profile.memberSince }}</span>
</div>
</div>
<div class="profile-header__actions">
<MonacoButton variant="primary" icon="edit">
Edit Member
</MonacoButton>
<MonacoButton variant="glass" icon="mail">
Send Email
</MonacoButton>
<MonacoButton variant="ghost" icon="ban">
Suspend
</MonacoButton>
<MonacoButton variant="ghost" icon="trash">
Remove
</MonacoButton>
</div>
</div>
</div>
<!-- Admin Stats Overview -->
<div
v-motion
:initial="{ opacity: 0, y: 20 }"
:enter="{ opacity: 1, y: 0, transition: { delay: 200 } }"
class="profile-stats"
>
<div class="stat-card" v-for="stat in adminStats" :key="stat.label">
<span class="stat-card__value">{{ stat.value }}</span>
<span class="stat-card__label">{{ stat.label }}</span>
</div>
</div>
<!-- Main Content Grid -->
<div class="profile-grid">
<!-- Left Column -->
<div class="profile-grid__sidebar">
<!-- Contact Information -->
<GlassCard
title="Contact Information"
variant="glass"
:delay="300"
>
<div class="contact-list">
<div class="contact-item">
<span class="contact-item__icon">✉</span>
<div class="contact-item__content">
<span class="contact-item__label">Email</span>
<span class="contact-item__value">{{ profile.email }}</span>
</div>
</div>
<div class="contact-item">
<span class="contact-item__icon">📱</span>
<div class="contact-item__content">
<span class="contact-item__label">Phone</span>
<span class="contact-item__value">{{ profile.phone }}</span>
</div>
</div>
<div class="contact-item">
<span class="contact-item__icon">🔗</span>
<div class="contact-item__content">
<span class="contact-item__label">LinkedIn</span>
<a class="contact-item__value contact-item__value--link">
{{ profile.linkedin }}
</a>
</div>
</div>
<div class="contact-item">
<span class="contact-item__icon">📍</span>
<div class="contact-item__content">
<span class="contact-item__label">Location</span>
<span class="contact-item__value">{{ profile.location }}</span>
</div>
</div>
</div>
</GlassCard>
<!-- Account Information -->
<GlassCard
title="Account Information"
variant="glass"
:delay="400"
>
<div class="account-info">
<div class="account-item">
<span class="account-item__label">Portal Access</span>
<span
class="account-item__value"
:class="{ 'account-item__value--active': profile.hasPortalAccess }"
>
{{ profile.hasPortalAccess ? 'Active' : 'No Access' }}
</span>
</div>
<div class="account-item">
<span class="account-item__label">Last Login</span>
<span class="account-item__value">{{ profile.lastLogin }}</span>
</div>
<div class="account-item">
<span class="account-item__label">Login Count</span>
<span class="account-item__value">{{ profile.loginCount }}</span>
</div>
<div class="account-item">
<span class="account-item__label">Account Created</span>
<span class="account-item__value">{{ profile.accountCreated }}</span>
</div>
</div>
<MonacoButton
v-if="!profile.hasPortalAccess"
variant="primary"
size="sm"
block
>
Send Portal Invitation
</MonacoButton>
<MonacoButton
v-else
variant="ghost"
size="sm"
block
>
Reset Password
</MonacoButton>
</GlassCard>
<!-- Payment History -->
<GlassCard
title="Payment History"
variant="gradient"
:delay="500"
>
<div class="payment-history">
<div
v-for="payment in paymentHistory"
:key="payment.id"
class="payment-item"
>
<div class="payment-item__date">{{ payment.date }}</div>
<div class="payment-item__info">
<span class="payment-item__type">{{ payment.type }}</span>
<span class="payment-item__amount">${{ payment.amount }}</span>
</div>
<span
class="payment-item__status"
:class="`payment-item__status--${payment.status}`"
>
{{ payment.status }}
</span>
</div>
</div>
<MonacoButton variant="primary" size="sm" block>
Record Payment
</MonacoButton>
<MonacoButton variant="ghost" size="sm" block>
Send Invoice
</MonacoButton>
</GlassCard>
</div>
<!-- Main Column -->
<div class="profile-grid__main">
<!-- Administrative Actions Log -->
<GlassCard
title="Administrative Actions"
variant="glass"
:delay="350"
>
<div class="timeline">
<div
v-for="(activity, index) in activities"
:key="index"
v-motion
:initial="{ opacity: 0, x: -20 }"
:enter="{
opacity: 1,
x: 0,
transition: { delay: 600 + (index * 50) }
}"
class="timeline-item"
>
<div class="timeline-item__marker">
<span :class="`timeline-icon timeline-icon--${activity.type}`">
{{ activity.icon }}
</span>
</div>
<div class="timeline-item__content">
<h4 class="timeline-item__title">{{ activity.title }}</h4>
<p class="timeline-item__description">{{ activity.description }}</p>
<span class="timeline-item__time">{{ activity.time }}</span>
</div>
</div>
</div>
</GlassCard>
<!-- Member Notes -->
<GlassCard
title="Internal Notes"
variant="glass"
:delay="450"
>
<div class="notes-section">
<div
v-for="note in memberNotes"
:key="note.id"
class="note-item"
>
<div class="note-item__header">
<span class="note-item__author">{{ note.author }}</span>
<span class="note-item__date">{{ note.date }}</span>
</div>
<p class="note-item__content">{{ note.content }}</p>
</div>
<div class="add-note">
<textarea
placeholder="Add a new note..."
class="note-input"
rows="3"
></textarea>
<MonacoButton variant="primary" size="sm">
Add Note
</MonacoButton>
</div>
</div>
</GlassCard>
<!-- Events Attended -->
<GlassCard
title="Events Attended"
variant="glass"
:delay="550"
>
<div class="events-list">
<div
v-for="event in eventsAttended"
:key="event.id"
class="event-mini"
>
<div class="event-mini__date">
<span class="event-mini__day">{{ event.day }}</span>
<span class="event-mini__month">{{ event.month }}</span>
</div>
<div class="event-mini__info">
<h4 class="event-mini__title">{{ event.title }}</h4>
<p class="event-mini__role">{{ event.role }}</p>
</div>
</div>
</div>
<MonacoButton variant="ghost" size="sm" block>
View All Events
</MonacoButton>
</GlassCard>
</div>
<!-- Right Column -->
<div class="profile-grid__aside">
<!-- Admin Quick Actions -->
<GlassCard
variant="glass"
:delay="400"
>
<h3 class="card-title">Quick Actions</h3>
<div class="admin-actions">
<MonacoButton variant="glass" size="sm" icon="mail" block>
Send Email
</MonacoButton>
<MonacoButton variant="glass" size="sm" icon="dollar" block>
Record Payment
</MonacoButton>
<MonacoButton variant="glass" size="sm" icon="refresh" block>
Reset Password
</MonacoButton>
<MonacoButton variant="glass" size="sm" icon="user-plus" block>
Add to Group
</MonacoButton>
<MonacoButton variant="primary" size="sm" icon="chart" block>
View Reports
</MonacoButton>
</div>
</GlassCard>
<!-- Member Flags & Warnings -->
<GlassCard
title="Flags & Warnings"
variant="glass"
:delay="500"
>
<div class="warnings-list">
<div
v-for="warning in memberWarnings"
:key="warning.id"
class="warning-item"
:class="`warning-item--${warning.severity}`"
>
<span class="warning-item__icon">{{ warning.icon }}</span>
<div class="warning-item__content">
<h5 class="warning-item__title">{{ warning.title }}</h5>
<p class="warning-item__description">{{ warning.description }}</p>
<span class="warning-item__date">{{ warning.date }}</span>
</div>
</div>
</div>
<MonacoButton variant="ghost" size="sm" block>
Add Flag
</MonacoButton>
</GlassCard>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import GlassCard from '~/components/ui/GlassCard.vue'
import MonacoButton from '~/components/ui/MonacoButton.vue'
const profile = ref({
name: 'Alexandra Martin',
title: 'CEO & Founder',
company: 'Monaco Ventures',
memberId: 'MCA2021-0234',
avatar: '/api/placeholder/200/200',
email: 'alexandra@monacoventures.com',
phone: '+1 (555) 123-4567',
linkedin: 'linkedin.com/in/alexandra-martin',
location: 'Monaco & New York',
memberSince: 'January 2021',
memberStatus: 'active',
duesStatus: 'current',
hasPortalAccess: true,
lastLogin: '2 hours ago',
loginCount: 234,
accountCreated: 'Jan 15, 2021'
})
const initials = computed(() => {
return profile.value.name.split(' ').map(n => n[0]).join('').toUpperCase()
})
const adminStats = ref([
{ label: 'Total Paid', value: '$12,500' },
{ label: 'Portal Logins', value: '234' },
{ label: 'Events Attended', value: '18' },
{ label: 'Days Overdue', value: '0' }
])
const activities = ref([
{
type: 'admin',
icon: '✏',
title: 'Profile Updated',
description: 'Admin Jane Doe updated contact information',
time: '2 days ago'
},
{
type: 'payment',
icon: '💵',
title: 'Annual Dues Paid',
description: 'Payment of $2,500 processed successfully',
time: '1 month ago'
},
{
type: 'email',
icon: '✉',
title: 'Portal Invitation Sent',
description: 'Member accepted invitation and logged in',
time: '2 months ago'
},
{
type: 'status',
icon: '✅',
title: 'Status Changed to Active',
description: 'Member activated after payment verification',
time: '3 months ago'
}
])
const memberNotes = ref([
{
id: 1,
author: 'Admin Jane Doe',
date: 'Dec 1, 2024',
content: 'VIP member - ensure priority support and invitations to exclusive events.'
},
{
id: 2,
author: 'Admin John Smith',
date: 'Nov 15, 2024',
content: 'Requested paper invoices instead of electronic billing. Updated preferences.'
},
{
id: 3,
author: 'System',
date: 'Oct 10, 2024',
content: 'Automatic renewal scheduled for January 2025.'
}
])
const eventsAttended = ref([
{ id: 1, day: '15', month: 'DEC', title: 'Winter Gala 2024', role: 'Speaker' },
{ id: 2, day: '01', month: 'NOV', title: 'Business Summit', role: 'Attendee' },
{ id: 3, day: '20', month: 'OCT', title: 'Tech Innovation Day', role: 'Panelist' }
])
const paymentHistory = ref([
{ id: 1, date: 'Dec 2024', type: 'Annual Dues', amount: 2500, status: 'paid' },
{ id: 2, date: 'Nov 2024', type: 'Event Ticket', amount: 150, status: 'paid' },
{ id: 3, date: 'Oct 2024', type: 'Special Assessment', amount: 500, status: 'paid' },
{ id: 4, date: 'Jan 2024', type: 'Annual Dues', amount: 2500, status: 'paid' }
])
const memberWarnings = ref([
{
id: 1,
severity: 'info',
icon: '',
title: 'VIP Member',
description: 'Priority support required',
date: 'Active'
},
{
id: 2,
severity: 'warning',
icon: '⚠',
title: 'Paper Invoices',
description: 'Requires printed billing',
date: 'Nov 2024'
}
])
</script>
<style scoped lang="scss">
.profile-mockup {
max-width: 1400px;
margin: 0 auto;
padding: 0 0 2rem;
background: linear-gradient(135deg, #fef2f2 0%, #ffffff 100%);
min-height: 100vh;
}
.profile-header {
position: relative;
margin-bottom: 2rem;
&__background {
position: absolute;
top: 0;
left: 0;
right: 0;
height: 250px;
overflow: hidden;
background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
}
&__gradient {
position: absolute;
inset: 0;
background: linear-gradient(
to bottom,
transparent 0%,
rgba(255, 255, 255, 0.1) 50%,
rgba(255, 255, 255, 0.3) 100%
);
}
&__content {
position: relative;
display: flex;
align-items: flex-end;
gap: 2rem;
padding: 2rem 2rem 2rem;
z-index: 1;
}
&__avatar-section {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
}
&__info {
flex: 1;
padding-top: 4rem;
}
&__actions {
display: flex;
gap: 0.5rem;
padding-top: 4rem;
}
}
.profile-avatar {
position: relative;
width: 150px;
height: 150px;
border-radius: 20px;
overflow: hidden;
background: white;
padding: 4px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 16px;
}
&__placeholder {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
border-radius: 16px;
font-size: 3rem;
font-weight: 700;
color: #dc2626;
}
&__edit {
position: absolute;
bottom: 0.5rem;
right: 0.5rem;
width: 2.5rem;
height: 2.5rem;
display: flex;
align-items: center;
justify-content: center;
background: white;
border: none;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
cursor: pointer;
transition: all 0.2s;
&:hover {
transform: scale(1.1);
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.15);
}
}
}
.member-status-badge {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
background: white;
border-radius: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.status-indicator {
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
&--active {
background: #10b981;
animation: pulse 2s infinite;
}
&--inactive {
background: #6b7280;
}
&--suspended {
background: #ef4444;
}
&--pending {
background: #fb923c;
}
}
.status-text {
font-size: 0.875rem;
font-weight: 500;
text-transform: capitalize;
color: #27272a;
}
.profile-name {
margin: 0 0 0.5rem;
font-size: 2.5rem;
font-weight: 700;
color: white;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.profile-title {
margin: 0 0 1rem;
font-size: 1.125rem;
color: rgba(255, 255, 255, 0.9);
}
.profile-member-id {
margin: 0 0 1.5rem;
font-size: 1rem;
color: #6b7280;
font-family: monospace;
}
.profile-badges {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.badge {
padding: 0.5rem 1rem;
border-radius: 20px;
font-size: 0.875rem;
font-weight: 600;
&--active {
background: rgba(16, 185, 129, 0.1);
color: #10b981;
}
&--inactive {
background: rgba(107, 114, 128, 0.1);
color: #6b7280;
}
&--suspended {
background: rgba(239, 68, 68, 0.1);
color: #ef4444;
}
&--pending {
background: rgba(251, 146, 60, 0.1);
color: #fb923c;
}
&--current {
background: rgba(16, 185, 129, 0.1);
color: #10b981;
}
&--overdue {
background: rgba(239, 68, 68, 0.1);
color: #ef4444;
}
&--exempt {
background: rgba(107, 114, 128, 0.1);
color: #6b7280;
}
&--year {
background: rgba(107, 114, 128, 0.1);
color: #6b7280;
}
}
.profile-stats {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 1rem;
padding: 0 2rem;
margin-bottom: 2rem;
}
.stat-card {
display: flex;
flex-direction: column;
align-items: center;
padding: 1.5rem;
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 16px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.05);
&__value {
font-size: 2rem;
font-weight: 700;
color: #dc2626;
margin-bottom: 0.25rem;
}
&__label {
font-size: 0.875rem;
color: #6b7280;
}
}
.profile-grid {
display: grid;
grid-template-columns: 320px 1fr 280px;
gap: 1.5rem;
padding: 0 2rem;
&__sidebar,
&__main,
&__aside {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
}
.contact-list {
display: flex;
flex-direction: column;
gap: 1rem;
}
.contact-item {
display: flex;
align-items: flex-start;
gap: 0.75rem;
&__icon {
display: flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
background: rgba(220, 38, 38, 0.1);
border-radius: 8px;
font-size: 1rem;
}
&__content {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.25rem;
}
&__label {
font-size: 0.75rem;
color: #6b7280;
}
&__value {
font-size: 0.875rem;
color: #27272a;
word-break: break-all;
&--link {
color: #dc2626;
cursor: pointer;
&:hover {
text-decoration: underline;
}
}
}
}
.account-info {
display: flex;
flex-direction: column;
gap: 1rem;
margin-bottom: 1rem;
}
.account-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem;
background: rgba(255, 255, 255, 0.5);
border-radius: 8px;
&__label {
font-size: 0.875rem;
color: #6b7280;
}
&__value {
font-size: 0.875rem;
font-weight: 500;
color: #27272a;
&--active {
color: #10b981;
font-weight: 600;
}
}
}
.payment-history {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-bottom: 1rem;
}
.payment-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem;
background: rgba(255, 255, 255, 0.5);
border-radius: 8px;
&__date {
font-size: 0.75rem;
color: #6b7280;
min-width: 60px;
}
&__info {
flex: 1;
display: flex;
flex-direction: column;
gap: 0.125rem;
margin: 0 1rem;
}
&__type {
font-size: 0.875rem;
font-weight: 500;
color: #27272a;
}
&__amount {
font-size: 0.75rem;
color: #6b7280;
}
&__status {
padding: 0.25rem 0.5rem;
border-radius: 12px;
font-size: 0.75rem;
font-weight: 500;
text-transform: capitalize;
&--paid {
background: rgba(16, 185, 129, 0.1);
color: #10b981;
}
&--pending {
background: rgba(251, 146, 60, 0.1);
color: #fb923c;
}
&--overdue {
background: rgba(239, 68, 68, 0.1);
color: #ef4444;
}
}
}
.membership-details {
display: flex;
flex-direction: column;
gap: 1rem;
margin-bottom: 1.5rem;
}
.membership-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0.75rem;
background: rgba(255, 255, 255, 0.5);
border-radius: 8px;
&__label {
font-size: 0.875rem;
color: #6b7280;
}
&__value {
font-size: 0.875rem;
font-weight: 600;
color: #27272a;
&--active {
color: #10b981;
}
&--paid {
color: #10b981;
}
}
}
.timeline {
position: relative;
padding-left: 2rem;
&::before {
content: '';
position: absolute;
left: 0.75rem;
top: 0;
bottom: 0;
width: 2px;
background: linear-gradient(
to bottom,
#dc2626 0%,
rgba(220, 38, 38, 0.1) 100%
);
}
}
.timeline-item {
position: relative;
display: flex;
gap: 1rem;
margin-bottom: 2rem;
&__marker {
position: absolute;
left: -2rem;
}
&__content {
flex: 1;
padding: 1rem;
background: rgba(255, 255, 255, 0.5);
border-radius: 12px;
transition: all 0.2s;
&:hover {
background: rgba(255, 255, 255, 0.7);
transform: translateX(4px);
}
}
&__title {
margin: 0 0 0.25rem;
font-size: 1rem;
font-weight: 600;
color: #27272a;
}
&__description {
margin: 0 0 0.5rem;
font-size: 0.875rem;
color: #6b7280;
}
&__time {
font-size: 0.75rem;
color: #a3a3a3;
}
}
.timeline-icon {
display: flex;
align-items: center;
justify-content: center;
width: 1.5rem;
height: 1.5rem;
background: white;
border-radius: 50%;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
font-size: 0.875rem;
&--event {
background: rgba(168, 85, 247, 0.1);
}
&--achievement {
background: rgba(251, 146, 60, 0.1);
}
&--connection {
background: rgba(59, 130, 246, 0.1);
}
&--post {
background: rgba(16, 185, 129, 0.1);
}
}
.notes-section {
display: flex;
flex-direction: column;
gap: 1rem;
}
.note-item {
padding: 1rem;
background: rgba(255, 255, 255, 0.5);
border-radius: 8px;
border-left: 3px solid #dc2626;
&__header {
display: flex;
justify-content: space-between;
margin-bottom: 0.5rem;
}
&__author {
font-size: 0.875rem;
font-weight: 600;
color: #dc2626;
}
&__date {
font-size: 0.75rem;
color: #6b7280;
}
&__content {
margin: 0;
font-size: 0.875rem;
color: #27272a;
line-height: 1.5;
}
}
.add-note {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.note-input {
width: 100%;
padding: 0.75rem;
background: rgba(255, 255, 255, 0.7);
border: 2px solid rgba(220, 38, 38, 0.1);
border-radius: 8px;
font-size: 0.875rem;
resize: vertical;
outline: none;
transition: all 0.2s;
&:focus {
border-color: #dc2626;
background: white;
}
}
.events-list {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-bottom: 1rem;
}
.event-mini {
display: flex;
gap: 1rem;
padding: 0.75rem;
background: rgba(255, 255, 255, 0.5);
border-radius: 10px;
transition: all 0.2s;
&:hover {
background: rgba(255, 255, 255, 0.7);
transform: translateX(4px);
}
&__date {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 3rem;
height: 3rem;
background: linear-gradient(135deg, #dc2626 0%, #b91c1c 100%);
color: white;
border-radius: 8px;
flex-shrink: 0;
}
&__day {
font-size: 1.125rem;
font-weight: 700;
line-height: 1;
}
&__month {
font-size: 0.625rem;
text-transform: uppercase;
}
&__info {
flex: 1;
}
&__title {
margin: 0 0 0.25rem;
font-size: 0.875rem;
font-weight: 600;
color: #27272a;
}
&__role {
margin: 0;
font-size: 0.75rem;
color: #6b7280;
}
}
.card-title {
margin: 0 0 1rem;
font-size: 1rem;
font-weight: 600;
color: #dc2626;
}
.admin-actions {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.warnings-list {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-bottom: 1rem;
}
.warning-item {
display: flex;
gap: 0.75rem;
padding: 0.75rem;
border-radius: 8px;
border-left: 3px solid;
&--info {
background: rgba(59, 130, 246, 0.05);
border-color: #3b82f6;
.warning-item__icon {
color: #3b82f6;
}
}
&--warning {
background: rgba(251, 146, 60, 0.05);
border-color: #fb923c;
.warning-item__icon {
color: #fb923c;
}
}
&--error {
background: rgba(239, 68, 68, 0.05);
border-color: #ef4444;
.warning-item__icon {
color: #ef4444;
}
}
&__icon {
font-size: 1.25rem;
flex-shrink: 0;
}
&__content {
flex: 1;
}
&__title {
margin: 0 0 0.25rem;
font-size: 0.875rem;
font-weight: 600;
color: #27272a;
}
&__description {
margin: 0 0 0.25rem;
font-size: 0.75rem;
color: #6b7280;
}
&__date {
font-size: 0.625rem;
color: #a3a3a3;
}
}
.connections-list {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin-bottom: 1rem;
}
.connection-item {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.5rem;
border-radius: 8px;
transition: all 0.2s;
cursor: pointer;
&:hover {
background: rgba(220, 38, 38, 0.05);
}
&__avatar,
&__avatar-placeholder {
width: 2.5rem;
height: 2.5rem;
border-radius: 8px;
flex-shrink: 0;
}
&__avatar {
object-fit: cover;
}
&__avatar-placeholder {
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
font-size: 0.75rem;
font-weight: 600;
color: #dc2626;
}
&__info {
flex: 1;
min-width: 0;
}
&__name {
margin: 0 0 0.125rem;
font-size: 0.875rem;
font-weight: 600;
color: #27272a;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
&__title {
margin: 0;
font-size: 0.75rem;
color: #6b7280;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
// Animations
@keyframes pulse {
0%, 100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
// Responsive
@media (max-width: 1200px) {
.profile-grid {
grid-template-columns: 280px 1fr;
&__aside {
grid-column: 1 / -1;
order: 3;
}
}
}
@media (max-width: 768px) {
.profile-header__content {
flex-direction: column;
align-items: center;
text-align: center;
}
.profile-header__actions {
width: 100%;
justify-content: center;
}
.profile-grid {
grid-template-columns: 1fr;
}
.achievements-grid {
grid-template-columns: 1fr;
}
}
</style>