Skip to content

Commit d70a8b4

Browse files
committed
fix: separate page added for members
1 parent 2611f00 commit d70a8b4

File tree

2 files changed

+134
-99
lines changed

2 files changed

+134
-99
lines changed

platforms/pictique/src/routes/(protected)/group/[id]/+page.svelte

Lines changed: 5 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
import { onMount } from 'svelte';
33
import { ChatMessage, MessageInput } from '$lib/fragments';
44
import { Avatar, Button } from '$lib/ui';
5-
import { clickOutside } from '$lib/utils';
5+
import { goto } from '$app/navigation';
6+
import { page } from '$app/state';
67
78
let messagesContainer: HTMLDivElement;
89
let messageValue = $state('');
9-
let showMembers = $state(false);
1010
1111
let userId = 'user-1';
12+
let id = page.params.id;
1213
1314
let group = {
1415
id: 'group-123',
@@ -66,42 +67,6 @@
6667
messageValue = '';
6768
setTimeout(scrollToBottom, 0);
6869
}
69-
70-
function currentUserRole() {
71-
return group.members.find((m) => m.id === userId)?.role;
72-
}
73-
74-
function canManage(member: { id?: string; name?: string; avatar?: string; role: any; }) {
75-
const current = currentUserRole();
76-
if (member.role === 'owner') return false;
77-
if (current === 'owner') return true;
78-
if (current === 'admin' && member.role === 'member') return true;
79-
return false;
80-
}
81-
82-
function promoteToAdmin(memberId: string) {
83-
const m = group.members.find((m) => m.id === memberId);
84-
if (m && m.role === 'member') m.role = 'admin';
85-
openMenuId = null;
86-
}
87-
88-
function removeMember(memberId: string) {
89-
group.members = group.members.filter((m) => m.id !== memberId || m.role === 'owner');
90-
openMenuId = null;
91-
}
92-
93-
function addMember() {
94-
const newId = `user-${Date.now()}`;
95-
group.members = [
96-
...group.members,
97-
{
98-
id: newId,
99-
name: `New Member ${group.members.length + 1}`,
100-
avatar: `https://i.pravatar.cc/150?u=${newId}`,
101-
role: 'member'
102-
}
103-
];
104-
}
10570
</script>
10671

10772
<section class="flex items-center justify-between gap-4 px-4 py-3 border-b border-gray-200">
@@ -117,72 +82,13 @@
11782
size="sm"
11883
class="w-[max-content]"
11984
callback={() => {
120-
showMembers = !showMembers;
121-
openMenuId = null;
85+
goto(`/group/${id}/members`)
12286
}}
12387
>
124-
{showMembers ? 'Hide Members' : 'View Members'}
88+
View Members
12589
</Button>
12690
</section>
12791

128-
{#if showMembers}
129-
<section class="px-4 py-3 border-b border-gray-200 space-y-4">
130-
{#each group.members as member (member.id)}
131-
<div class="flex items-center justify-between">
132-
<div class="flex items-center gap-3">
133-
<Avatar src={member.avatar} size="sm" />
134-
<div>
135-
<span class="text-sm font-medium">{member.name}</span>
136-
{#if member.role !== 'member'}
137-
<span class="ml-2 text-xs text-gray-500">({member.role})</span>
138-
{/if}
139-
</div>
140-
</div>
141-
142-
{#if canManage(member)}
143-
<div class="relative" use:clickOutside={() => (openMenuId = null)}>
144-
<button
145-
onclick={() => {(openMenuId = openMenuId === member.id ? null : member.id)}}
146-
>
147-
148-
</button>
149-
150-
{#if openMenuId === member.id}
151-
<div class="absolute right-0 mt-2 w-40 rounded-md bg-white shadow-lg border z-10">
152-
<ul class="text-sm">
153-
<!-- svelte-ignore a11y_click_events_have_key_events -->
154-
{#if currentUserRole() === 'owner' && member.role === 'member'}
155-
<!-- svelte-ignore a11y_click_events_have_key_events -->
156-
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
157-
<li
158-
class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
159-
onclick={() => promoteToAdmin(member.id)}
160-
>
161-
Make admin
162-
</li>
163-
{/if}
164-
<!-- svelte-ignore a11y_click_events_have_key_events -->
165-
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
166-
<li
167-
class="px-4 py-2 hover:bg-red-50 text-red-600 cursor-pointer"
168-
onclick={() => removeMember(member.id)}
169-
>
170-
Remove member
171-
</li>
172-
</ul>
173-
</div>
174-
{/if}
175-
</div>
176-
{/if}
177-
</div>
178-
{/each}
179-
180-
<Button size="sm" variant="primary" class="w-[max-content] mt-4" callback={addMember}>
181-
Add Member
182-
</Button>
183-
</section>
184-
{/if}
185-
18692
<section class="chat relative px-0">
18793
<div class="h-[calc(100vh-300px)] mt-4 overflow-auto" bind:this={messagesContainer}>
18894
{#each messages as msg (msg.id)}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<script lang="ts">
2+
import { page } from '$app/state';
3+
import { Avatar, Button } from '$lib/ui';
4+
import { clickOutside } from '$lib/utils';
5+
6+
let groupId = page.params.id;
7+
8+
let userId = 'user-1'; // Simulated current user
9+
10+
let group = $state({
11+
id: groupId,
12+
name: 'Design Team',
13+
avatar: 'https://i.pravatar.cc/150?img=15',
14+
description: 'Discuss all design-related tasks and updates here.',
15+
members: [
16+
{ id: 'user-1', name: 'Alice', avatar: 'https://i.pravatar.cc/150?img=1', role: 'owner' },
17+
{ id: 'user-2', name: 'Bob', avatar: 'https://i.pravatar.cc/150?img=2', role: 'admin' },
18+
{ id: 'user-3', name: 'Charlie', avatar: 'https://i.pravatar.cc/150?img=3', role: 'member' }
19+
]
20+
});
21+
22+
let openMenuId = $state<string | null>(null);
23+
24+
function currentUserRole() {
25+
return group.members.find((m) => m.id === userId)?.role;
26+
}
27+
28+
function canManage(member: { id?: string; name?: string; avatar?: string; role: any; }) {
29+
const current = currentUserRole();
30+
if (member.role === 'owner') return false;
31+
if (current === 'owner') return true;
32+
if (current === 'admin' && member.role === 'member') return true;
33+
return false;
34+
}
35+
36+
function promoteToAdmin(memberId: string) {
37+
const m = group.members.find((m) => m.id === memberId);
38+
if (m && m.role === 'member') m.role = 'admin';
39+
openMenuId = null;
40+
}
41+
42+
function removeMember(memberId: string) {
43+
group.members = group.members.filter((m) => m.id !== memberId || m.role === 'owner');
44+
openMenuId = null;
45+
}
46+
47+
function addMember() {
48+
const newId = `user-${Date.now()}`;
49+
group.members = [
50+
...group.members,
51+
{
52+
id: newId,
53+
name: `New Member ${group.members.length + 1}`,
54+
avatar: `https://i.pravatar.cc/150?u=${newId}`,
55+
role: 'member'
56+
}
57+
];
58+
}
59+
</script>
60+
61+
<section class="mx-auto w-full h-[80vh] flex flex-col justify-between">
62+
<div>
63+
<div class="flex items-center gap-4 mb-6">
64+
<Avatar src={group.avatar} />
65+
<div>
66+
<h1 class="text-xl font-semibold">{group.name}</h1>
67+
<p class="text-sm text-gray-600">{group.description}</p>
68+
</div>
69+
</div>
70+
71+
<div class="space-y-6">
72+
{#each group.members as member (member.id)}
73+
<div class="flex items-center justify-between">
74+
<div class="flex items-center gap-3">
75+
<Avatar src={member.avatar} size="sm" />
76+
<div>
77+
<p class="text-sm font-medium">{member.name}</p>
78+
{#if member.role !== 'member'}
79+
<p class="text-xs text-gray-500">{member.role}</p>
80+
{/if}
81+
</div>
82+
</div>
83+
84+
{#if canManage(member)}
85+
<div class="relative" use:clickOutside={() => (openMenuId = null)}>
86+
<button
87+
onclick={() => (openMenuId = openMenuId === member.id ? null : member.id)}
88+
>
89+
90+
</button>
91+
92+
{#if openMenuId === member.id}
93+
<div class="absolute right-0 mt-2 w-40 rounded-md bg-white shadow-lg border z-10">
94+
<!-- svelte-ignore a11y_click_events_have_key_events -->
95+
<ul class="text-sm">
96+
{#if currentUserRole() === 'owner' && member.role === 'member'}
97+
<!-- svelte-ignore a11y_click_events_have_key_events -->
98+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
99+
<li
100+
class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
101+
onclick={() => promoteToAdmin(member.id)}
102+
>
103+
Make admin
104+
</li>
105+
{/if}
106+
<!-- svelte-ignore a11y_click_events_have_key_events -->
107+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
108+
<li
109+
class="px-4 py-2 hover:bg-red-50 text-red-600 cursor-pointer"
110+
onclick={() => removeMember(member.id)}
111+
>
112+
Remove member
113+
</li>
114+
</ul>
115+
</div>
116+
{/if}
117+
</div>
118+
{/if}
119+
</div>
120+
{/each}
121+
</div>
122+
</div>
123+
124+
<div class="flex justify-center">
125+
<Button size="sm" variant="secondary" class="mt-6" callback={addMember}>
126+
Add Member
127+
</Button>
128+
</div>
129+
</section>

0 commit comments

Comments
 (0)