Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

28 create dialog for channel and thread creation #3

Merged
merged 10 commits into from
Dec 13, 2021
13 changes: 10 additions & 3 deletions src/components/Banner/BannerSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,26 @@
</div>
<component
:is="
getLoggedInStatus()
getLoggedInStatus
? defineAsyncComponent(() => import('./LoggedInBanner.vue'))
: defineAsyncComponent(() => import('./GuestBanner.vue'))
"
:user-token="getUserToken"
@login="registerOneTime"
></component>
</div>
</template>

<script setup>
import { useRouter } from "vue-router";
import useStore from "../../composables/global/useStore";
import { computed } from "@vue/reactivity";
import { defineAsyncComponent } from "@vue/runtime-core";

const { getLoggedInStatus, getUserToken, getPseudonym } = useStore;
const router = useRouter();
const { getLoggedInStatus, getUserToken, getPseudonym, registerOnce } =
useStore;

function registerOneTime() {
registerOnce();
}
</script>
9 changes: 1 addition & 8 deletions src/components/Banner/GuestBanner.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div class="mx-auto w-11/12 lg:w-3/5">
<div class="lg:w-1/2 lg:inline-block p-3 text-lg">
<button class="btn" @click="login">
<button class="btn" @click="$emit('login')">
Use this pseudonym for one session
</button>
</div>
Expand All @@ -19,13 +19,6 @@
</template>

<script setup>
const props = defineProps({
userToken: {
type: String,
required: true,
},
});

const emit = defineEmits(["login"]);
</script>

Expand Down
6 changes: 0 additions & 6 deletions src/components/Banner/LoggedInBanner.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@
import { useRouter } from "vue-router";
import store from "../../composables/global/useStore";
import { RefreshIcon } from "@heroicons/vue/outline";
const props = defineProps({
userToken: {
type: String,
required: true,
},
});
const router = useRouter();
const { logout } = store;
async function signout() {
Expand Down
7 changes: 0 additions & 7 deletions src/components/ButtonComponent.vue

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<transition-group name="flip-list" tag="div">
<template v-for="item in items" :key="item.title">
<template v-for="item in items" :key="item.name">
<ChannelListItem :item="item" />
</template>
</transition-group>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<template>
<router-link :to="channelLink" :class="getChannelClass(item)">
<div class="col-span-8 text-lg">{{ item.title }}</div>
<div class="col-span-8 text-lg">{{ item.name }}</div>
<div class="col-span-2 font-semibold justify-self-end">
{{ item.thread_count }} threads
{{ item.threadCount }} threads
</div>
<div class="col-span-2 font-semibold justify-self-end">
{{ item.comment_count }}
{{ item.messageCount }}
<ChatAltIcon class="h-5 w-5 inline-block" />
</div>
</router-link>
Expand All @@ -29,13 +29,14 @@ export default {
getChannelClass(item) {
var className =
"grid grid-cols-12 gap-6 p-2 text-gray-700 hover:text-red-500 hover:bg-gray-100 cursor-pointer";
if (item.title == this.$route.params.channel) className += " bg-gray-100";
if (item.name == this.$route.params.channelId)
className += " bg-gray-100";
return className;
},
},
computed: {
channelLink() {
return "/channels/" + this.item.title;
return `/channels/${this.item.id}/`;
},
channel() {
return this.$route.params.channel;
Expand Down
84 changes: 84 additions & 0 deletions src/components/Channels/CreateChannel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<template>
<select
v-model="channelType"
@change="openModal"
class="border-2 border-gray-400 p-1"
v-if="getLoggedInStatus"
>
<option disabled selected value="">Create new channel</option>
<option value="public">Public</option>
<option value="private">Private</option>
</select>
<Modal :is-open="isModalOpen">
<template v-slot:title>Create {{ channelTypeName }} Channel</template>
Channel name:
<div>
<input
v-model="channelName"
class="rounded border-2 border-gray-500 w-full h-12 px-3 text-xl my-1"
type="text"
/>
</div>
<div class="text-red-500">{{ message }}</div>
<template v-slot:actions>
<button class="btn success" @click="processCreate">Create</button>
<button class="btn error" @click="closeModal">Cancel</button>
</template>
</Modal>
</template>

<script setup>
import { computed, ref } from "@vue/reactivity";
import useStore from "../../composables/global/useStore";
import Modal from "../Shared/Modal.vue";
const { getLoggedInStatus, createChannel } = useStore;

const isModalOpen = ref(false);
const channelType = ref("");
const channelName = ref("");
const message = ref("");

const channelTypeName = computed(
() => channelType.value[0].toUpperCase() + channelType.value.slice(1)
);

function closeModal() {
document.querySelector("body").classList.remove("modal-open");
isModalOpen.value = false;
}

function openModal() {
channelName.value = "";
window.scrollTo({ top: 0, left: 0 });
isModalOpen.value = true;
document.querySelector("body").classList.add("modal-open");
}

function processCreate() {
if (isFormValid()) {
createChannel({ name: channelName.value })
.then((x) => closeModal())
.catch((err) => (message.value = err.response.data.message));
} else {
message.value = "Name is required";
}
}

function isFormValid() {
return channelName.value.trim().length > 0;
}
</script>

<style scoped>
.btn {
@apply w-20 my-2 bg-white border-2 border-gray-500 text-lg h-10 leading-3 hover:text-white cursor-pointer;
}

.btn.success {
@apply hover:bg-green-500;
}

.btn.error {
@apply hover:bg-red-500;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,34 @@
</div>
<ChannelList v-show="sortedItems.length > 0" :items="sortedItems" />
<div class="text-red-600" v-show="sortedItems.length === 0">
No channles available
No channels available
</div>
</div>
</template>

<script setup>
import ChannelList from "./ChannelList.vue";
import useChannels from "../composables/useChannels";
import userSorting from "../composables/userSorting";
import useChannels from "../../composables/useChannels";
import userSorting from "../../composables/userSorting";

const sortByItems = [
{
name: "Default",
value: "default",
value: "defaultSortAverage",
},
{
name: "Recent",
value: "recent",
value: "latestMessageCreatedAt",
},
{
name: "Activity",
value: "activity",
value: "messageCount",
},
{
name: "Starred",
value: "starred",
value: "follows",
},
];
const { channels } = useChannels();
const { channels } = await useChannels();
const { sortedItems, sortBy } = userSorting(channels);
</script>
12 changes: 0 additions & 12 deletions src/components/CreateChannel.vue

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
</div>
</template>
<script setup>
import store from "../composables/global/useStore";
import store from "../../composables/global/useStore";
const { getMajorError } = store;
</script>
42 changes: 42 additions & 0 deletions src/components/Shared/Modal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<template>
<teleport to="body">
<div v-if="isOpen" class="modal">
<div class="modal-content">
<div class="my-3 text-xl"><slot name="title">Modal Title</slot></div>
<div class="flex-grow py-3"><slot>Modal Body</slot></div>
<div class="flex justify-end my-3 gap-4">
<slot name="actions"><button @click="closeModal"></button></slot>
</div>
</div>
</div>
</teleport>
</template>

<script setup>
const props = defineProps({
isOpen: {
type: Boolean,
required: true,
},
});

const emit = defineEmits(["close-modal"]);

function closeModal() {
emit("close-modal");
}
</script>

<style>
body.modal-open {
@apply overflow-y-hidden;
}

.modal {
@apply absolute inset-0 flex items-center justify-center bg-gray-700 bg-opacity-50;
}

.modal-content {
@apply px-6 py-2 bg-white divide-y divide-gray-500 h-72 max-h-80 w-2/5 flex flex-col justify-evenly;
}
</style>
78 changes: 78 additions & 0 deletions src/components/Threads/CreateThread.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<template>
<button
@click="openModal"
class="w-full text-center float-left inline-block border-2 border-gray-500 text-lg px-10 h-10 mt-4 leading-9 hover:bg-gray-100"
>
Create new thread
</button>
<Modal :is-open="isModalOpen">
<template v-slot:title>Create new thread</template>
Thread name:
<div>
<input
v-model="threadName"
class="rounded border-2 border-gray-500 w-full h-12 px-3 text-xl my-1"
type="text"
/>
</div>
<div class="text-red-500">{{ message }}</div>
<template v-slot:actions>
<button class="btn success" @click="processCreate">Create</button>
<button class="btn error" @click="closeModal">Cancel</button>
</template>
</Modal>
</template>

<script setup>
import { ref } from "@vue/reactivity";
import useStore from "../../composables/global/useStore";
import Modal from "../Shared/Modal.vue";
import { useRoute } from "vue-router";
const { createThread } = useStore;
const isModalOpen = ref(false);
const threadName = ref("");
const message = ref("");
const route = useRoute();
function closeModal() {
document.querySelector("body").classList.remove("modal-open");
isModalOpen.value = false;
}

function openModal() {
threadName.value = "";
window.scrollTo({ top: 0, left: 0 });
isModalOpen.value = true;
document.querySelector("body").classList.add("modal-open");
}

function processCreate() {
if (isFormValid()) {
createThread({
name: threadName.value,
topicId: route.params.channelId,
})
.then((x) => closeModal())
.catch((err) => (message.value = err.response.data.message));
} else {
message.value = "Name is required";
}
}

function isFormValid() {
return threadName.value.trim().length > 0;
}
</script>

<style scoped>
.btn {
@apply w-20 my-2 bg-white border-2 border-gray-500 text-lg h-10 leading-3 hover:text-white cursor-pointer;
}

.btn.success {
@apply hover:bg-green-500;
}

.btn.error {
@apply hover:bg-red-500;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
style="min-height: 400px"
>
<div class="grid">
<span class="px-2 py-1 text-xl font-bold">All Threads:</span>
<template v-for="item in items" :key="item.id">
<ThreadListItem :item="item" />
</template>
Expand Down
Loading