add: forums ui

This commit is contained in:
trisua 2025-08-04 12:12:04 -04:00
parent 2be87c397d
commit 9ec52abfe4
24 changed files with 770 additions and 64 deletions

View file

@ -6,41 +6,52 @@
(main
("class" "flex flex_col gap_2")
(div
("class" "pillmenu")
(a
("href" "#/general")
("data-tab-button" "general")
("class" "active")
(text "{{ icon \"settings\" }}")
(span
(text "{{ text \"settings:tab.general\" }}")))
(a
("href" "#/images")
("data-tab-button" "images")
(text "{{ icon \"image\" }}")
(span
(text "{{ text \"settings:tab.images\" }}")))
(a
("href" "#/members")
("data-tab-button" "members")
(text "{{ icon \"users-round\" }}")
(span
(text "{{ text \"communities:tab.members\" }}")))
(text "{% if can_manage_channels -%}")
(a
("href" "#/channels")
("data-tab-button" "channels")
(text "{{ icon \"rss\" }}")
(span
(text "{{ text \"communities:tab.channels\" }}")))
(text "{%- endif %} {% if can_manage_emojis -%}")
(a
("href" "#/emojis")
("data-tab-button" "emojis")
(text "{{ icon \"smile\" }}")
(span
(text "{{ text \"communities:tab.emojis\" }}")))
(text "{%- endif %}"))
("class" "pillmenu rows w-full")
(div
("class" "row")
(a
("href" "#/general")
("data-tab-button" "general")
("class" "active")
(text "{{ icon \"settings\" }}")
(span
(text "{{ text \"settings:tab.general\" }}")))
(a
("href" "#/images")
("data-tab-button" "images")
(text "{{ icon \"image\" }}")
(span
(text "{{ text \"settings:tab.images\" }}")))
(a
("href" "#/members")
("data-tab-button" "members")
(text "{{ icon \"users-round\" }}")
(span
(text "{{ text \"communities:tab.members\" }}"))))
(div
("class" "row")
(text "{% if can_manage_channels -%}")
(a
("href" "#/channels")
("data-tab-button" "channels")
(text "{{ icon \"rss\" }}")
(span
(text "{{ text \"communities:tab.channels\" }}")))
(text "{%- endif %} {% if community.is_forum -%}")
(a
("href" "#/topics")
("data-tab-button" "topics")
(icon (text "list"))
(span
(str (text "communities:tab.topics"))))
(text "{%- endif %} {% if can_manage_emojis -%}")
(a
("href" "#/emojis")
("data-tab-button" "emojis")
(text "{{ icon \"smile\" }}")
(span
(text "{{ text \"communities:tab.emojis\" }}")))
(text "{%- endif %}")))
(div
("class" "w_full flex flex_col gap_2")
("data-tab" "general")
@ -564,6 +575,235 @@
]);
});
};"))
(text "{%- endif %}")
(text "{% if community.is_forum -%}")
(script ("type" "application/json") ("id" "community_topics") (text "{{ community.topics | json_encode() | safe }}"))
(div
("class" "card lowered w_full hidden flex flex_col gap_2")
("data-tab" "topics")
(div
("class" "card_nest")
(div
("class" "card small")
(b
(str (text "communities:action.create_topic"))))
(form
("class" "card flex flex_col gap_2")
("onsubmit" "create_topic_from_form(event)")
(div
("class" "flex flex_col gap_1")
(label
("for" "title")
(text "{{ text \"communities:label.name\" }}"))
(input
("type" "text")
("name" "title")
("id" "title")
("placeholder" "name")
("required" "")
("minlength" "2")
("maxlength" "32")))
(div
("class" "flex flex_col gap_1")
(label
("for" "description")
(str (text "communities:label.description")))
(input
("type" "text")
("name" "description")
("id" "description")
("placeholder" "description")
("required" "")
("minlength" "2")
("maxlength" "256")))
(div
("class" "flex flex_col gap_1")
(label
("for" "color")
(str (text "communities:label.color")))
(input
("type" "color")
("name" "color")
("id" "color")
("placeholder" "color")
("required" "")
("style" "width: 8rem")))
(div
("class" "flex flex_col gap_1")
(label
("for" "position")
(str (text "communities:label.position")))
(input
("type" "number")
("name" "position")
("id" "position")
("placeholder" "position")
("required" "")
("value" "0")
("min" "0")
("max" "256")))
(button
(text "{{ text \"communities:action.create\" }}"))))
(text "{% for id, topic in community.topics %}")
(div
("class" "card_nest")
(div
("class" "card small flex justify_between gap_2")
(div
("class" "flex gap_2")
(b
(text "{{ topic.position }} "))
(text "{{ topic.title }}"))
(button
("class" "red lowered small")
("onclick" "delete_topic('{{ id }}')")
(icon (text "trash"))
(str (text "general:action.delete"))))
(div
("class" "card flex flex_col gap_2")
(details
("class" "accordion")
(summary ("class" "flex items_center gap_2") (icon (text "pencil")) (str (text "general:label.edit")))
(form
("class" "inner flex flex_col gap_2")
("style" "background: var(--color-super-raised)")
("onsubmit" "update_topic_from_form(event, '{{ id }}')")
(div
("class" "flex flex_col gap_1")
(label
("for" "title")
(text "{{ text \"communities:label.name\" }}"))
(input
("type" "text")
("name" "title")
("id" "title")
("placeholder" "name")
("value" "{{ topic.title }}")
("required" "")
("minlength" "2")
("maxlength" "32")))
(div
("class" "flex flex_col gap_1")
(label
("for" "description")
(str (text "communities:label.description")))
(input
("type" "text")
("name" "description")
("id" "description")
("placeholder" "description")
("value" "{{ topic.description }}")
("required" "")
("minlength" "2")
("maxlength" "256")))
(div
("class" "flex flex_col gap_1")
(label
("for" "color")
(str (text "communities:label.color")))
(input
("type" "color")
("name" "color")
("id" "color")
("placeholder" "color")
("required" "")
("value" "{{ topic.color }}")
("style" "width: 8rem")))
(div
("class" "flex flex_col gap_1")
(label
("for" "position")
(str (text "communities:label.position")))
(input
("type" "number")
("name" "position")
("id" "position")
("placeholder" "position")
("required" "")
("value" "{{ topic.position }}")
("min" "0")
("max" "256")))
(button
(icon (text "check"))
(str (text "general:action.save")))))))
(text "{% endfor %}"))
(script
(text "globalThis.delete_topic = async (id) => {
if (
!(await trigger(\"atto::confirm\", [
\"Are you sure you would like to do this?\",
]))
) {
return;
}
fetch(`/api/v1/communities/{{ community.id }}/topics/${id}`, {
method: \"DELETE\",
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
});
};
async function create_topic_from_form(e) {
e.preventDefault();
await trigger(\"atto::debounce\", [\"topics::create\"]);
fetch(\"/api/v1/communities/{{ community.id }}/topics\", {
method: \"POST\",
headers: {
\"Content-Type\": \"application/json\",
},
body: JSON.stringify({
title: e.target.title.value,
description: e.target.description.value,
color: e.target.color.value,
position: Number.parseInt(e.target.position.value),
}),
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
if (res.ok) {
e.target.reset();
window.location.reload();
}
});
}
async function update_topic_from_form(e, id) {
e.preventDefault();
await trigger(\"atto::debounce\", [\"topics::update\"]);
fetch(`/api/v1/communities/{{ community.id }}/topics/${id}`, {
method: \"POST\",
headers: {
\"Content-Type\": \"application/json\",
},
body: JSON.stringify({
title: e.target.title.value,
description: e.target.description.value,
color: e.target.color.value,
position: Number.parseInt(e.target.position.value),
}),
})
.then((res) => res.json())
.then((res) => {
trigger(\"atto::toast\", [
res.ok ? \"success\" : \"error\",
res.message,
]);
});
}"))
(text "{%- endif %}"))
(script