Skip to main content

User Profiles & Settings

The Ever Works Template includes a user profile system with public profile pages, tabbed navigation, avatar management, social links, and profile display components. Users can showcase their about information, portfolio, skills, and submitted items through a structured profile interface.

Architecture Overview

ComponentPathPurpose
ProfileContentcomponents/profile/profile-content.tsxMain profile page content with tab routing
ProfileNavigationcomponents/profile/profile-navigation.tsxSticky tab navigation bar
ProfileHeadercomponents/profile/profile-header.tsxProfile cover, avatar, bio, and social links
ProfileTagcomponents/profile/profile-tag.tsxSkill/interest tag component
ProfileButtoncomponents/header/profile-button.tsxHeader profile menu trigger
ProfileMenucomponents/profile-button/profile-menu.tsxDropdown profile menu

Profile Data Structure

// lib/types/profile.ts
interface Profile {
displayName: string;
jobTitle: string;
bio: string;
avatar: string | null;
location: string | null;
company: string | null;
website: string | null;
socialLinks: SocialLink[];
}

interface SocialLink {
platform: string; // 'github', 'linkedin', 'twitter', etc.
url: string;
displayName: string;
}

Profile Header

The ProfileHeader component renders the top section of a user profile with a gradient cover banner, avatar with edit button, and biographical information:

import { ProfileHeader } from '@/components/profile/profile-header';

<ProfileHeader profile={userProfile} isOwnProfile={true} />

Features

FeatureDescription
Cover bannerGradient background using theme primary and secondary colors
AvatarCircular image with ring border, responsive sizing (24x24 to 28x28)
Edit buttonShown only when isOwnProfile is true
Image fallbackShows user icon placeholder on image load error
Social linksRenders platform-specific icons (GitHub, LinkedIn, Twitter)
Location & companyDisplays with map pin and briefcase icons
Website linkExternal link with globe icon

Avatar Error Handling

The component includes robust image error handling:

const [imageError, setImageError] = useState(false);

// Reset error when avatar URL changes
useEffect(() => {
setImageError(false);
}, [profile.avatar]);

// Render fallback on error
{!imageError && profile.avatar ? (
<Image src={profile.avatar} onError={() => setImageError(true)} />
) : (
<FiUser className="w-8 h-8 text-gray-400" />
)}

Social Platform Icons

PlatformIcon
githubFiGithub
linkedinFiLinkedin
twitterFiTwitter
OtherFiGlobe (generic)

Profile Navigation

The ProfileNavigation component provides a sticky tabbed navigation:

import { ProfileNavigation } from '@/components/profile/profile-navigation';

<ProfileNavigation
activeTab="about"
onTabChange={(tab) => setActiveTab(tab)}
/>

Available Tabs

Tab IDLabelIcon
aboutAboutFiUser
portfolioPortfolioFiBriefcase
skillsSkillsFiAward
submissionsSubmissionsFiFileText
  • Sticky positioning -- Stays at top when scrolling with blur backdrop
  • Mobile-friendly -- Horizontal scroll on small screens
  • Focus visible -- Ring indicator for keyboard navigation
  • Theme-aware -- Active tab uses theme primary colors

Profile Content

The ProfileContent component orchestrates the profile page by combining navigation and tab content:

import { ProfileContent } from '@/components/profile/profile-content';

function ProfilePage({ profile }) {
return <ProfileContent profile={profile} />;
}

Tab Sections

SectionComponentContent
AboutAboutSectionPersonal information, bio, details
PortfolioPortfolioSectionWork samples and projects
SkillsSkillsSectionSkills and expertise tags
SubmissionsSubmissionsSectionItems submitted by the user

Each section is rendered with a consistent header:

function ProfileSectionHeader({ title }) {
return (
<h2 className="text-2xl font-bold border-b border-gray-200 dark:border-gray-800 pb-2">
{title}
</h2>
);
}

Profile Button Components

Header Profile Button

A button in the site header that opens the profile menu:

import { ProfileButton } from '@/components/header/profile-button';

<ProfileButton />

Profile Header Display

Shows the user's name and avatar in compact form:

import { ProfileHeaderButton } from '@/components/profile-button/profile-header';

<ProfileHeaderButton user={currentUser} />

Profile Menu

A dropdown menu with profile actions:

import { ProfileMenu } from '@/components/profile-button/profile-menu';

<ProfileMenu
user={currentUser}
onSignOut={handleSignOut}
/>

Responsive Design

The profile components are built with a mobile-first approach:

BreakpointBehavior
MobileCentered avatar, stacked layout, horizontal tab scroll
Tablet+Left-aligned avatar, side-by-side layout
DesktopFull-width card with maximum width constraints

Avatar Sizing

ScreenSize
Mobile24x24 (96px)
Desktop28x28 (112px)

Theme Integration

The profile system uses the template's theme system:

  • Cover banner gradient uses --theme-primary and --theme-secondary CSS variables
  • Active tab states use theme primary colors
  • Dark mode is fully supported with appropriate contrast ratios
  • Hover states use theme-aware color transitions

Layout Structure

ProfileHeader (cover + avatar + info card)
|
+-- Cover Banner (gradient)
+-- Avatar (overlapping cover)
+-- Info Card
+-- Name & Title
+-- Bio
+-- Location / Company / Website
+-- Social Links

ProfileContent
|
+-- ProfileNavigation (sticky tabs)
+-- Active Section
+-- AboutSection
+-- PortfolioSection
+-- SkillsSection
+-- SubmissionsSection

Key Files

FilePath
Profile Contentcomponents/profile/profile-content.tsx
Profile Navigationcomponents/profile/profile-navigation.tsx
Profile Headercomponents/profile/profile-header.tsx
Profile Tagcomponents/profile/profile-tag.tsx
Header Profile Buttoncomponents/header/profile-button.tsx
Profile Menucomponents/profile-button/profile-menu.tsx
Profile Typeslib/types/profile.ts