Landed the topic list page (no topics yet, so appearances are deceiving)

This commit is contained in:
2025-10-28 16:32:05 -06:00
parent 86540e00b1
commit 086954f7b0
9 changed files with 443 additions and 5 deletions
+14
View File
@@ -50,6 +50,7 @@ type AmContext interface {
RC() int
OutputType() string
Parameter(string) string
QueryParamInt(string, int) int
RemoteIP() string
ReplaceUser(*database.User)
SaveSession() error
@@ -241,6 +242,19 @@ func (c *amContext) Parameter(name string) string {
return rc
}
// QueryParamInt returns the value of a query parameter as an integer, with a default.
func (c *amContext) QueryParamInt(name string, defval int) int {
s := c.echoContext.QueryParam(name)
if s == "" {
return defval
}
rc, err := strconv.Atoi(s)
if err != nil {
return defval
}
return rc
}
// RemoteIP returns the remote IP address.
func (c *amContext) RemoteIP() string {
return c.echoContext.RealIP()
+10
View File
@@ -96,6 +96,15 @@ func makeYearRange(a jet.Arguments) reflect.Value {
}
}
func immediateIf(a jet.Arguments) reflect.Value {
cond := a.Get(0).Convert(reflect.TypeFor[bool]()).Bool()
if cond {
return a.Get(1)
} else {
return a.Get(2)
}
}
// extractCommunityLogo extracts a community logo URL from a community.
func extractCommunityLogo(a jet.Arguments) reflect.Value {
rc := "/img/builtin/default-community.jpg"
@@ -189,6 +198,7 @@ func SetupTemplates() {
views.AddGlobal("AmsterdamVersion", config.AMSTERDAM_VERSION)
views.AddGlobal("AmsterdamCopyright", config.AMSTERDAM_COPYRIGHT)
views.AddGlobal("GlobalConfig", config.GlobalConfig)
views.AddGlobalFunc("iif", immediateIf)
views.AddGlobalFunc("MakeIntRange", makeIntRange)
views.AddGlobalFunc("MakeYearRange", makeYearRange)
views.AddGlobalFunc("ExtractCommunityLogo", extractCommunityLogo)
+1 -1
View File
@@ -23,7 +23,7 @@
<span class="text-lg pt-0.5 flex-shrink-0">🟣</span>
<div class="flex-1">
<div class="mb-2">
<a href="/TODO/comm/{{ commAlias }}/conf/{{ c.AliasesQ()[0] }}"
<a href="/comm/{{ commAlias }}/conf/{{ c.AliasesQ()[0] }}"
class="text-blue-700 hover:text-blue-900 font-bold text-lg">{{ c.Name }}</a>
<span class="text-gray-600 text-sm ml-2">- Latest activity: {{ DisplayActivity(c.LastUpdate, .) }}</span>
</div>
+143
View File
@@ -0,0 +1,143 @@
{*
* Amsterdam Web Communities System
* Copyright (c) 2025 Erbosoft Metaverse Design Solutions, All Rights Reserved
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*}
<div class="p-4">
<!-- Page Title -->
<div class="mb-6">
<h1 class="text-blue-800 text-4xl font-bold mb-2">Topics in {{ conferenceName }}</h1>
<hr class="border-2 border-gray-400 w-4/5 mb-6">
</div>
<!-- Action Buttons -->
<div class="max-w-6xl mb-6">
<div class="flex gap-2 flex-wrap mb-4">
<a href="{{ urlBack }}"
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors">
Conference List
</a>
<a href="/TODO{{ urlStem }}/new_topic"
class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors">
Add Topic
</a>
<a href="/TODO/find"
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors">
Find
</a>
<a href="/TODO{{ urlStem }}/manage"
class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded text-sm font-medium transition-colors">
Manage
</a>
</div>
<div class="text-xs text-gray-600">
<a href="{{ permalink }}"
class="text-blue-700 hover:text-blue-900">
[Permalink to this conference]
</a>
</div>
</div>
<!-- Topics Table -->
<div class="max-w-6xl">
<div class="bg-white border border-gray-300 rounded-lg overflow-hidden">
<table class="w-full">
<thead class="bg-gray-100 border-b border-gray-300">
<tr>
{{ sp := iif(sort == 1, -1, 1) }}
<th class="px-4 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">
<a href="{{ urlStem }}?sort={{ sp }}"
class="text-blue-700 hover:text-blue-900">#</a>
</th>
{{ sp = iif(sort == 2, -2, 2) }}
<th class="px-4 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">
<a href="{{ urlStem }}?sort={{ sp }}"
class="text-blue-700 hover:text-blue-900">Topic Name</a>
</th>
{{ sp = iif(sort == 3, -3, 3) }}
<th class="px-4 py-3 text-right text-xs font-bold text-gray-700 uppercase tracking-wider">
<a href="{{ urlStem }}?sort={{ sp }}"
class="text-blue-700 hover:text-blue-900">New</a>
</th>
{{ sp = iif(sort == 4, -4, 4) }}
<th class="px-4 py-3 text-right text-xs font-bold text-gray-700 uppercase tracking-wider">
<a href="{{ urlStem }}?sort={{ sp }}"
class="text-blue-700 hover:text-blue-900">Total</a>
</th>
{{ sp = iif(sort == 5, -5, 5) }}
<th class="px-4 py-3 text-left text-xs font-bold text-gray-700 uppercase tracking-wider">
<a href="{{ urlStem }}?sort={{ sp }}"
class="text-blue-700 hover:text-blue-900">Last Response</a>
</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
{{ range i, t := topics }}
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 whitespace-nowrap text-sm">
<a href="{{ urlStem }}/topic/{{ t.Number }}?new=1"
class="text-blue-700 hover:text-blue-900 font-medium">{{ t.Number }}</a>
</td>
<td class="px-4 py-3 text-sm">
<a href="{{ urlStem }}/topic/{{ t.Number }}?new=1"
class="text-blue-700 hover:text-blue-900 font-medium">{{ t.Name }}</a>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-right">
<a href="{{ urlStem }}/topic/{{ t.Number }}?new=1"
class="text-blue-700 hover:text-blue-900">{{ t.Unread }}</a>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm text-right">
<a href="{{ urlStem }}/topic/{{ t.Number }}?st=0&en=-1"
class="text-blue-700 hover:text-blue-900">{{ t.Total }}</a>
</td>
<td class="px-4 py-3 whitespace-nowrap text-sm">
<a href="{{ urlStem }}/topic/{{ t.Number }}?new=1"
class="text-blue-700 hover:text-blue-900">{{ formattedDate[i] }}</a>
</td>
</tr>
{{ end }}
</tbody>
</table>
</div>
<!-- View Filter -->
<div class="mt-6 text-center">
<div class="inline-flex items-center gap-2 text-sm">
<span class="font-bold">[</span>
{{ if view == 1 }}
<span class="font-bold">New</span>
{{ else }}
<a href="{{ urlStem }}?view=1" class="text-blue-700 hover:text-blue-900">New</a>
{{ end }}
<span class="font-bold">|</span>
{{ if view == 2 }}
<span class="font-bold">Active</span>
{{ else }}
<a href="{{ urlStem }}?view=2" class="text-blue-700 hover:text-blue-900">Active</a>
{{ end }}
<span class="font-bold">|</span>
{{ if view == 3 }}
<span class="font-bold">All</span>
{{ else }}
<a href="{{ urlStem }}?view=3" class="text-blue-700 hover:text-blue-900">All</a>
{{ end }}
<span class="font-bold">|</span>
{{ if view == 4 }}
<span class="font-bold">Hidden</span>
{{ else }}
<a href="{{ urlStem }}?view=4" class="text-blue-700 hover:text-blue-900">Hidden</a>
{{ end }}
<span class="font-bold">|</span>
{{ if view == 5 }}
<span class="font-bold">Archived</span>
{{ else }}
<a href="{{ urlStem }}?view=5" class="text-blue-700 hover:text-blue-900">Archived</a>
{{ end }}
<span class="font-bold">]</span>
</div>
</div>
</div>
</div>