feat(frontend): closed-channel read-only UI
Closed channels: composer replaced by a read-only banner; history still viewable; GuildChannel carries closed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -683,6 +683,17 @@ button {
|
|||||||
.dc-composer .btn {
|
.dc-composer .btn {
|
||||||
flex: none;
|
flex: none;
|
||||||
}
|
}
|
||||||
|
.dc-closed-banner {
|
||||||
|
flex: none;
|
||||||
|
margin: 0 16px 20px;
|
||||||
|
padding: 12px 14px;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--text-muted);
|
||||||
|
background: var(--elevated);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
/* members */
|
/* members */
|
||||||
.dc-members {
|
.dc-members {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ function timeOf(iso?: string): string {
|
|||||||
const X_TYPES = ['general', 'work', 'report', 'discuss', 'triage', 'custom'] as const
|
const X_TYPES = ['general', 'work', 'report', 'discuss', 'triage', 'custom'] as const
|
||||||
type XType = (typeof X_TYPES)[number]
|
type XType = (typeof X_TYPES)[number]
|
||||||
|
|
||||||
type GuildChannel = { id: string; name: string; guildId?: string; xType?: XType; isMember?: boolean; isPublic?: boolean }
|
type GuildChannel = { id: string; name: string; guildId?: string; xType?: XType; isMember?: boolean; isPublic?: boolean; closed?: boolean }
|
||||||
type MemberItem = { userId: string; email: string; name: string; status: string }
|
type MemberItem = { userId: string; email: string; name: string; status: string }
|
||||||
|
|
||||||
export default function ChatPage() {
|
export default function ChatPage() {
|
||||||
@@ -500,24 +500,28 @@ export default function ChatPage() {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form
|
{currentChannel?.closed ? (
|
||||||
className="dc-composer"
|
<div className="dc-closed-banner">This channel is closed — history is read-only.</div>
|
||||||
onSubmit={(e) => {
|
) : (
|
||||||
e.preventDefault()
|
<form
|
||||||
void sendMessage()
|
className="dc-composer"
|
||||||
}}
|
onSubmit={(e) => {
|
||||||
>
|
e.preventDefault()
|
||||||
<input
|
void sendMessage()
|
||||||
className="input"
|
}}
|
||||||
value={content}
|
>
|
||||||
onChange={(e) => setContent(e.target.value)}
|
<input
|
||||||
placeholder={currentChannel ? `Message #${currentChannel.name}` : 'Select a channel first'}
|
className="input"
|
||||||
disabled={!currentChannel}
|
value={content}
|
||||||
/>
|
onChange={(e) => setContent(e.target.value)}
|
||||||
<button className="btn" type="submit" disabled={!currentChannel || !content.trim()}>
|
placeholder={currentChannel ? `Message #${currentChannel.name}` : 'Select a channel first'}
|
||||||
Send
|
disabled={!currentChannel}
|
||||||
</button>
|
/>
|
||||||
</form>
|
<button className="btn" type="submit" disabled={!currentChannel || !content.trim()}>
|
||||||
|
Send
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{showMembers ? (
|
{showMembers ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user