feat: implement user profiles and social walls (Tasks #171, #173, #174)

This commit is contained in:
2026-01-13 23:24:19 +01:00
parent 477f447b67
commit ed62ac0641
8 changed files with 372 additions and 20 deletions

View File

@@ -3,12 +3,13 @@ import { useChatStore } from '../stores/chat';
import { storeToRefs } from 'pinia';
import MessageList from './MessageList.vue';
import UserList from './UserList.vue';
import UserList from './UserList.vue';
import MusicPlayer from './MusicPlayer.vue';
import TokenCreator from './TokenCreator.vue';
import { Hash, Volume2, VolumeX, Settings, X, Coins, Menu } from 'lucide-vue-next';
import { Hash, Volume2, VolumeX, Settings, X, Coins, Menu, User } from 'lucide-vue-next';
import { ref } from 'vue';
const showTokenCreator = ref(false);
const showProfile = ref(false);
const selectedProfileAddress = ref(null);
const showMobileMenu = ref(false);
const chatStore = useChatStore();
@@ -102,24 +103,24 @@ const saveSettings = () => {
</div>
<div class="flex-1 overflow-y-auto py-3 space-y-0.5 px-2">
<!-- Token Creator Link -->
<!-- Profile Link -->
<button
@click="showTokenCreator = true; showMobileMenu = false"
@click="selectedProfileAddress = walletAddress; showProfile = true; showMobileMenu = false"
:class="['w-full flex items-center gap-2 px-2 py-1.5 rounded-md transition-all group mb-4',
showTokenCreator ? 'bg-[#3f4147] text-white' : 'text-gray-400 hover:bg-[#35373c] hover:text-gray-200']"
showProfile && selectedProfileAddress === walletAddress ? 'bg-[#3f4147] text-white' : 'text-gray-400 hover:bg-[#35373c] hover:text-gray-200']"
>
<Coins size="18" class="text-violet-400" />
<span class="text-sm font-medium">Token Creator</span>
<User size="18" class="text-violet-400" />
<span class="text-sm font-medium">My Profile</span>
</button>
<div class="px-2 mb-2 text-[11px] font-bold text-gray-500 uppercase tracking-wider">Text Channels</div>
<div v-for="channel in channels" :key="channel.id">
<button
@click="chatStore.setChannel(channel.id); showTokenCreator = false; showMobileMenu = false"
@click="chatStore.setChannel(channel.id); showProfile = false; showMobileMenu = false"
:class="['w-full flex items-center gap-2 px-2 py-1.5 rounded-md transition-all group',
currentChannel === channel.id && !showTokenCreator ? 'bg-[#3f4147] text-white' : 'text-gray-400 hover:bg-[#35373c] hover:text-gray-200']"
currentChannel === channel.id && !showProfile ? 'bg-[#3f4147] text-white' : 'text-gray-400 hover:bg-[#35373c] hover:text-gray-200']"
>
<Hash size="18" :class="currentChannel === channel.id && !showTokenCreator ? 'text-gray-200' : 'text-gray-500 group-hover:text-gray-400'" />
<Hash size="18" :class="currentChannel === channel.id && !showProfile ? 'text-gray-200' : 'text-gray-500 group-hover:text-gray-400'" />
<span class="text-sm font-medium">{{ channel.name }}</span>
</button>
</div>
@@ -156,18 +157,18 @@ const saveSettings = () => {
<Menu size="24" />
</button>
<Hash size="20" class="text-gray-400 mr-2" />
<span class="font-bold text-white mr-4">{{ showTokenCreator ? 'Token Creator' : currentChannel }}</span>
<span class="font-bold text-white mr-4">{{ showProfile ? (selectedProfileAddress === walletAddress ? 'My Profile' : 'User Profile') : currentChannel }}</span>
</div>
<div class="flex-1 flex overflow-hidden">
<div class="flex-1 flex flex-col relative overflow-hidden">
<TokenCreator v-if="showTokenCreator" @back="showTokenCreator = false" />
<MessageList v-else />
<UserProfile v-if="showProfile" :address="selectedProfileAddress" />
<MessageList v-else @view-profile="(addr) => { selectedProfileAddress = addr; showProfile = true; }" />
</div>
<!-- Member List (Discord Style) -->
<div class="w-60 bg-discord-sidebar border-l border-black/20 hidden xl:flex flex-col">
<UserList />
<UserList @view-profile="(addr) => { selectedProfileAddress = addr; showProfile = true; }" />
</div>
</div>
</div>