Spaces:
Running
Running
| <div class="page"> | |
| <!-- Top Bar --> | |
| <header class="topbar"> | |
| <h1>Community Forum</h1> | |
| <div class="searchbar"> | |
| <input type="search" placeholder="Search threads, tags, tickers…" /> | |
| <select aria-label="Sort"> | |
| <option>Latest</option> | |
| <option>Most Active</option> | |
| <option>Top Voted</option> | |
| <option>Unanswered</option> | |
| </select> | |
| </div> | |
| <button class="btn" (click)="toggleModal(true)">New Post</button> | |
| </header> | |
| <!-- Sidebar (unchanged) --> | |
| <aside class="sidebar"> | |
| <div class="block"> | |
| <h3>CATEGORIES</h3> | |
| <div class="cat-list"> | |
| <div class="cat active"><span>General Discussion</span><small style="color:var(--muted)">—</small></div> | |
| <div class="cat"><span>Intraday Trading</span><small style="color:var(--muted)">—</small></div> | |
| <div class="cat"><span>Swing & Position</span><small style="color:var(--muted)">—</small></div> | |
| <div class="cat"><span>Options & Futures</span><small style="color:var(--muted)">—</small></div> | |
| <div class="cat"><span>Fundamental Analysis</span><small style="color:var(--muted)">—</small></div> | |
| <div class="cat"><span>Brokers & Tools</span><small style="color:var(--muted)">—</small></div> | |
| <div class="cat"><span>Announcements</span><small style="color:var(--muted)">—</small></div> | |
| </div> | |
| </div> | |
| <div class="block"> | |
| <h3>POPULAR TAGS</h3> | |
| <div class="tag-list" style="gap:8px;flex-wrap:wrap;"> | |
| <span class="tag">#NSE</span> | |
| <span class="tag">#BANKNIFTY</span> | |
| <span class="tag">#Earnings</span> | |
| <span class="tag">#Result</span> | |
| <span class="tag">#IPO</span> | |
| <span class="tag">#Strategy</span> | |
| <span class="tag">#Beginner</span> | |
| </div> | |
| </div> | |
| </aside> | |
| <!-- Main Content --> | |
| <main class="content"> | |
| <!-- Thread List --> | |
| <section class="panel"> | |
| <div class="toolbar"> | |
| <span class="pill">General</span> | |
| <span class="pill">Showing: Latest</span> | |
| </div> | |
| <div class="threads" id="threadList"> | |
| <div *ngIf="loading" class="tiny" style="color:var(--muted)">Loading…</div> | |
| <div *ngIf="!loading && loadError" class="tiny" style="color:var(--danger)">{{loadError}}</div> | |
| <article class="thread" *ngFor="let p of posts" (click)="openThread(p.id)"> | |
| <div class="title"> | |
| {{ p.title || (p.body | slice:0:60) + (p.body.length > 60 ? '…' : '') }} | |
| </div> | |
| <div class="meta"> | |
| <span>by <strong>{{ p.userName }}</strong></span> | |
| <span>• {{ p.createdAt | date:'short' }}</span> | |
| <div class="chips" *ngIf="p.tags"> | |
| <span class="chip" *ngFor="let t of splitTags(p.tags)">{{ t }}</span> | |
| </div> | |
| </div> | |
| <!-- Body content --> | |
| <div class="body-text">{{ p.body }}</div> | |
| <!-- Actions --> | |
| <div class="actions" (click)="$event.stopPropagation()"> | |
| <button class="btn ghost" (click)="likePost(p)">👍 Like <span class="count">{{ p.likeCount ?? 0 }}</span></button> | |
| <button class="btn ghost" (click)="dislikePost(p)">👎 Dislike <span class="count">{{ p.dislikeCount ?? 0 }}</span></button> | |
| <button class="btn ghost" (click)="toggleReply(p.id)">💬 Reply <span class="count">{{ p.commentCount ?? 0 }}</span></button> | |
| </div> | |
| <!-- Inline reply editor --> | |
| <div class="reply" *ngIf="isReplyOpen(p.id)" (click)="$event.stopPropagation()"> | |
| <textarea [(ngModel)]="replyDraft[p.id]" placeholder="Write your reply…"></textarea> | |
| <div style="display:flex; gap:8px; justify-content:flex-end"> | |
| <button class="btn ghost" (click)="toggleReply(p.id)">Cancel</button> | |
| <button class="btn" [disabled]="!(replyDraft[p.id] || '').trim()" (click)="submitReply(p.id)">Post Reply</button> | |
| </div> | |
| </div> | |
| <div class="tiny" style="color:var(--muted)">{{ p.category || 'General' }}</div> | |
| </article> | |
| <div *ngIf="!loading && posts.length === 0" class="tiny" style="color:var(--muted)">No posts yet.</div> | |
| </div> | |
| </section> | |
| </main> | |
| </div> | |
| <!-- New Thread Modal --> | |
| <div id="modal" | |
| [style.display]="showModal ? 'block' : 'none'" | |
| style="position:fixed; inset:0; z-index:1000; backdrop-filter: blur(6px); background:rgba(4,8,12,.35)"> | |
| <div style="max-width:720px; margin:60px auto; background:rgba(17,23,35,.98); border:1px solid var(--border); border-radius:16px; padding:16px; box-shadow:0 20px 60px rgba(0,0,0,.6);"> | |
| <div style="display:flex; align-items:center; gap:8px; margin-bottom:8px;"> | |
| <h2 style="margin:0; font-size:18px;">Turn your thoughts into impact</h2> | |
| </div> | |
| <div style="display:grid; gap:10px;"> | |
| <input [(ngModel)]="title" placeholder="Title" | |
| style="padding:10px 12px; border-radius:12px; background:#0b121c; border:1px solid var(--border); color:var(--text)" /> | |
| <div style="display:flex; gap:8px; flex-wrap:wrap"> | |
| <select [(ngModel)]="category" | |
| style="padding:10px 12px; border-radius:12px; background:#0b121c; border:1px solid var(--border); color:var(--text)"> | |
| <option>General Discussion</option> | |
| <option>Intraday Trading</option> | |
| <option>Swing & Position</option> | |
| <option>Options & Futures</option> | |
| <option>Fundamental Analysis</option> | |
| </select> | |
| <input [(ngModel)]="tags" placeholder="#tags (comma separated)" | |
| style="flex:1; padding:10px 12px; border-radius:12px; background:#0b121c; border:1px solid var(--border); color:var(--text)" /> | |
| </div> | |
| <textarea [(ngModel)]="body" placeholder="Write your post…" style="min-height:180px"></textarea> | |
| <div style="display:flex; gap:8px; justify-content:flex-end"> | |
| <button class="btn ghost" (click)="toggleModal(false)">Cancel</button> | |
| <button class="btn" [disabled]="!body.trim()" (click)="publish()">Post</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |