✨ Realm list
This commit is contained in:
parent
1505244726
commit
cbea87f74d
@ -1,5 +1,13 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
|
type RealmType = int
|
||||||
|
|
||||||
|
const (
|
||||||
|
RealmTypePublic = RealmType(iota)
|
||||||
|
RealmTypeRestricted
|
||||||
|
RealmTypePrivate
|
||||||
|
)
|
||||||
|
|
||||||
type Realm struct {
|
type Realm struct {
|
||||||
BaseModel
|
BaseModel
|
||||||
|
|
||||||
@ -8,7 +16,7 @@ type Realm struct {
|
|||||||
Articles []Article `json:"article"`
|
Articles []Article `json:"article"`
|
||||||
Moments []Moment `json:"moments"`
|
Moments []Moment `json:"moments"`
|
||||||
Members []RealmMember `json:"members"`
|
Members []RealmMember `json:"members"`
|
||||||
IsPublic bool `json:"is_public"`
|
RealmType RealmType `json:"realm_type"`
|
||||||
AccountID uint `json:"account_id"`
|
AccountID uint `json:"account_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,14 +60,14 @@ func createRealm(c *fiber.Ctx) error {
|
|||||||
var data struct {
|
var data struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
IsPublic bool `json:"is_public"`
|
RealmType int `json:"realm_type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := BindAndValidate(c, &data); err != nil {
|
if err := BindAndValidate(c, &data); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
realm, err := services.NewRealm(user, data.Name, data.Description, data.IsPublic)
|
realm, err := services.NewRealm(user, data.Name, data.Description, data.RealmType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||||
}
|
}
|
||||||
@ -150,7 +150,7 @@ func editRealm(c *fiber.Ctx) error {
|
|||||||
var data struct {
|
var data struct {
|
||||||
Name string `json:"name" validate:"required"`
|
Name string `json:"name" validate:"required"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
IsPublic bool `json:"is_public"`
|
RealmType int `json:"realm_type"`
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := BindAndValidate(c, &data); err != nil {
|
if err := BindAndValidate(c, &data); err != nil {
|
||||||
@ -165,7 +165,7 @@ func editRealm(c *fiber.Ctx) error {
|
|||||||
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
return fiber.NewError(fiber.StatusNotFound, err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
realm, err := services.EditRealm(realm, data.Name, data.Description, data.IsPublic)
|
realm, err := services.EditRealm(realm, data.Name, data.Description, data.RealmType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
return fiber.NewError(fiber.StatusBadRequest, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -274,7 +274,7 @@ func NewPost[T models.PostInterface](item T) (T, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if item.GetRealm() != nil {
|
if item.GetRealm() != nil {
|
||||||
if !item.GetRealm().IsPublic {
|
if item.GetRealm().RealmType != models.RealmTypePublic {
|
||||||
var member models.RealmMember
|
var member models.RealmMember
|
||||||
if err := database.C.Where(&models.RealmMember{
|
if err := database.C.Where(&models.RealmMember{
|
||||||
RealmID: item.GetRealm().ID,
|
RealmID: item.GetRealm().ID,
|
||||||
|
@ -38,7 +38,7 @@ func ListRealmIsAvailable(user models.Account) ([]models.Realm, error) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err := database.C.Where(&models.Realm{
|
if err := database.C.Where(&models.Realm{
|
||||||
IsPublic: true,
|
RealmType: models.RealmTypePublic,
|
||||||
}).Or("id IN ?", idx).Find(&realms).Error; err != nil {
|
}).Or("id IN ?", idx).Find(&realms).Error; err != nil {
|
||||||
return realms, err
|
return realms, err
|
||||||
}
|
}
|
||||||
@ -46,12 +46,12 @@ func ListRealmIsAvailable(user models.Account) ([]models.Realm, error) {
|
|||||||
return realms, nil
|
return realms, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRealm(user models.Account, name, description string, isPublic bool) (models.Realm, error) {
|
func NewRealm(user models.Account, name, description string, realmType int) (models.Realm, error) {
|
||||||
realm := models.Realm{
|
realm := models.Realm{
|
||||||
Name: name,
|
Name: name,
|
||||||
Description: description,
|
Description: description,
|
||||||
AccountID: user.ID,
|
AccountID: user.ID,
|
||||||
IsPublic: isPublic,
|
RealmType: realmType,
|
||||||
Members: []models.RealmMember{
|
Members: []models.RealmMember{
|
||||||
{AccountID: user.ID},
|
{AccountID: user.ID},
|
||||||
},
|
},
|
||||||
@ -86,10 +86,10 @@ func KickRealmMember(user models.Account, target models.Realm) error {
|
|||||||
return database.C.Delete(&member).Error
|
return database.C.Delete(&member).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func EditRealm(realm models.Realm, name, description string, isPublic bool) (models.Realm, error) {
|
func EditRealm(realm models.Realm, name, description string, realmType int) (models.Realm, error) {
|
||||||
realm.Name = name
|
realm.Name = name
|
||||||
realm.Description = description
|
realm.Description = description
|
||||||
realm.IsPublic = isPublic
|
realm.RealmType = realmType
|
||||||
|
|
||||||
err := database.C.Save(&realm).Error
|
err := database.C.Save(&realm).Error
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="icon" type="image/xml+svg" href="/favicon.svg">
|
<link rel="icon" type="image/xml+svg" href="/favicon.png">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Solarplaza</title>
|
<title>Solarplaza</title>
|
||||||
</head>
|
</head>
|
||||||
|
BIN
pkg/views/public/favicon.png
Executable file
BIN
pkg/views/public/favicon.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 51 KiB |
116
pkg/views/src/components/realms/RealmList.vue
Normal file
116
pkg/views/src/components/realms/RealmList.vue
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<template>
|
||||||
|
<v-list density="comfortable">
|
||||||
|
<v-list-subheader>Realms</v-list-subheader>
|
||||||
|
<v-list-item v-for="item in realms" prepend-icon="mdi-account-multiple" :title="item.name" />
|
||||||
|
|
||||||
|
<v-divider v-if="realms.length > 0" class="border-opacity-75 my-2" />
|
||||||
|
|
||||||
|
<v-list-item
|
||||||
|
prepend-icon="mdi-plus"
|
||||||
|
title="Create a realm"
|
||||||
|
:disabled="!id.userinfo.isLoggedIn"
|
||||||
|
@click="creating = true"
|
||||||
|
/>
|
||||||
|
</v-list>
|
||||||
|
|
||||||
|
<v-dialog v-model="creating" class="max-w-[540px]">
|
||||||
|
<v-card title="Create a realm" prepend-icon="mdi-account-multiple-plus" :loading="loading">
|
||||||
|
<v-form @submit.prevent="submit">
|
||||||
|
<v-card-text>
|
||||||
|
<v-text-field
|
||||||
|
label="Name"
|
||||||
|
variant="outlined"
|
||||||
|
density="comfortable"
|
||||||
|
v-model="requestData.name"
|
||||||
|
/>
|
||||||
|
<v-textarea
|
||||||
|
label="Description"
|
||||||
|
variant="outlined"
|
||||||
|
density="comfortable"
|
||||||
|
v-model="requestData.description"
|
||||||
|
/>
|
||||||
|
<v-select
|
||||||
|
label="Realm type"
|
||||||
|
item-title="label"
|
||||||
|
item-value="value"
|
||||||
|
variant="outlined"
|
||||||
|
density="comfortable"
|
||||||
|
:items="realmTypeOptions"
|
||||||
|
v-model="requestData.realm_type"
|
||||||
|
/>
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
|
||||||
|
<v-btn type="reset" color="grey-darken-3" @click="creating = false">Cancel</v-btn>
|
||||||
|
<v-btn type="submit" :disabled="loading">Save</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-form>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
|
||||||
|
<!-- @vue-ignore -->
|
||||||
|
<v-snackbar v-model="error" :timeout="5000">Something went wrong... {{ error }}</v-snackbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { getAtk, useUserinfo } from "@/stores/userinfo";
|
||||||
|
|
||||||
|
const id = useUserinfo();
|
||||||
|
|
||||||
|
const realms = ref<any[]>([]);
|
||||||
|
const requestData = ref({
|
||||||
|
name: "",
|
||||||
|
description: "",
|
||||||
|
realm_type: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
const realmTypeOptions = [
|
||||||
|
{ label: "Public Realm", value: 0 },
|
||||||
|
{ label: "Restricted Realm", value: 1 },
|
||||||
|
{ label: "Private Realm", value: 2 }
|
||||||
|
];
|
||||||
|
|
||||||
|
const creating = ref(false);
|
||||||
|
|
||||||
|
const error = ref<string | null>(null);
|
||||||
|
const reverting = ref(false);
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
|
async function list() {
|
||||||
|
reverting.value = true;
|
||||||
|
const res = await fetch("/api/realms/me/available", {
|
||||||
|
headers: { Authorization: `Bearer ${getAtk()}` }
|
||||||
|
});
|
||||||
|
if (res.status !== 200) {
|
||||||
|
error.value = await res.text();
|
||||||
|
} else {
|
||||||
|
realms.value = await res.json();
|
||||||
|
}
|
||||||
|
reverting.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function submit(evt: SubmitEvent) {
|
||||||
|
const form = evt.target as HTMLFormElement;
|
||||||
|
const payload = requestData.value;
|
||||||
|
if (!payload.name) return;
|
||||||
|
|
||||||
|
loading.value = true;
|
||||||
|
const res = await fetch("/api/realms", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json", Authorization: `Bearer ${getAtk()}` },
|
||||||
|
body: JSON.stringify(payload)
|
||||||
|
});
|
||||||
|
if (res.status !== 200) {
|
||||||
|
error.value = await res.text();
|
||||||
|
} else {
|
||||||
|
await list();
|
||||||
|
form.reset();
|
||||||
|
creating.value = false;
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
list();
|
||||||
|
</script>
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-navigation-drawer v-model="drawerOpen" color="grey-lighten-5" floating>
|
<v-navigation-drawer v-model="drawerOpen" color="grey-lighten-5" floating>
|
||||||
<div class="flex flex-col h-full">
|
<div class="flex flex-col h-full">
|
||||||
<v-list>
|
<v-list class="border-b border-opacity-15 h-[64px]" style="border-bottom-width: thin">
|
||||||
<v-list-item :subtitle="username" :title="nickname">
|
<v-list-item :subtitle="username" :title="nickname">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<v-avatar icon="mdi-account-circle" :image="id.userinfo.data?.avatar" />
|
<v-avatar icon="mdi-account-circle" :image="id.userinfo.data?.avatar" />
|
||||||
@ -27,7 +27,9 @@
|
|||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
|
|
||||||
<v-list density="compact" class="flex-grow-1" nav> </v-list>
|
<div class="flex-grow-1">
|
||||||
|
<realm-list />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<v-alert type="info" variant="tonal" class="text-sm">
|
<v-alert type="info" variant="tonal" class="text-sm">
|
||||||
@ -95,6 +97,7 @@ import { useEditor } from "@/stores/editor"
|
|||||||
import { useUserinfo } from "@/stores/userinfo"
|
import { useUserinfo } from "@/stores/userinfo"
|
||||||
import { useWellKnown } from "@/stores/wellKnown"
|
import { useWellKnown } from "@/stores/wellKnown"
|
||||||
import PostAction from "@/components/publish/PostAction.vue"
|
import PostAction from "@/components/publish/PostAction.vue"
|
||||||
|
import RealmList from "@/components/realms/RealmList.vue";
|
||||||
|
|
||||||
const id = useUserinfo()
|
const id = useUserinfo()
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
Loading…
Reference in New Issue
Block a user