Skip to content

Commit

Permalink
Merge pull request #66 from katherineqian/nebula
Browse files Browse the repository at this point in the history
Add functionality to create a poll.
  • Loading branch information
katherineqian authored Nov 8, 2024
2 parents 73d378a + d60ef67 commit bad3b51
Show file tree
Hide file tree
Showing 14 changed files with 252 additions and 98 deletions.
6 changes: 3 additions & 3 deletions src/components/Banner/BannerSection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
</div>
</div>

<!-- <Modal :is-open="isModalOpen" @close-modal="closeModal">
<!-- <ThemedModal :is-open="isModalOpen" @close-modal="closeModal">
<template v-slot:title>Delete Pseudonym</template>
<div class="text-xl">Are you sure you want to delete pseudonym?</div>
<div class="mt-3 text-lg">
Expand Down Expand Up @@ -114,7 +114,7 @@
Delete
</button>
</template>
</Modal> -->
</ThemedModal> -->
</div>
</template>

Expand All @@ -123,7 +123,7 @@ import { onMounted, watch, ref, computed, nextTick } from 'vue'
import useStore from '../../composables/global/useStore'
import { defineAsyncComponent } from '@vue/runtime-core'
import { TrashIcon, RefreshIcon, LoginIcon, DotsVerticalIcon } from '@heroicons/vue/outline'
import Modal from '../Shared/Modal.vue'
import ThemedModal from '../Shared/ThemedModal.vue'
import { useRoute } from 'vue-router'
const {
Expand Down
10 changes: 5 additions & 5 deletions src/components/Channels/CreateChannel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<option value="public">Public</option>
<option value="private">Private</option>
</select>
<Modal :is-open="isModalOpen" @close-modal="closeModal">
<ThemedModal :is-open="isModalOpen" @close-modal="closeModal">
<template #title>Create {{ channelTypeName }} Channel</template>
<span class="font-semibold">Channel name:</span>
<div>
Expand All @@ -20,7 +20,7 @@
placeholder="Enter channel name"
/>
</div>
<div class="mt-2">
<div class="mt-4">
<input
id="disableVoting"
v-model="disableVoting"
Expand Down Expand Up @@ -68,13 +68,13 @@
Create
</button>
</template>
</Modal>
</ThemedModal>
</template>

<script setup>
import { computed, ref } from '@vue/reactivity'
import useStore from '../../composables/global/useStore'
import Modal from '../Shared/Modal.vue'
import ThemedModal from '../Shared/ThemedModal.vue'
const { getLoggedInStatus, createChannel, getGuestStatus, loadUser } = useStore
const isModalOpen = ref(false)
Expand All @@ -89,7 +89,7 @@ const channelTypeName = computed(() => channelType.value[0].toUpperCase() + chan
const isEmailValid = computed(() => {
if (!email.value || email.value.trim().length === 0) return true
return /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email.value)
return /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/.test(email.value)
})
function closeModal() {
Expand Down
6 changes: 3 additions & 3 deletions src/components/Channels/DeleteChannel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<TrashIcon class="h-4 w-4" />
<span class="sr-only">Delete</span>
</button>
<Modal :is-open="isModalOpen" @close-modal="closeModal">
<ThemedModal :is-open="isModalOpen" @close-modal="closeModal">
<template #title>Delete Channel</template>
<div>
Are you sure you want to delete
Expand All @@ -24,13 +24,13 @@
Delete
</button>
</template>
</Modal>
</ThemedModal>
</template>

<script setup>
import { TrashIcon } from '@heroicons/vue/outline'
import { ref } from '@vue/reactivity'
import Modal from '../Shared/Modal.vue'
import ThemedModal from '../Shared/ThemedModal.vue'
defineProps({
show: {
Expand Down
6 changes: 3 additions & 3 deletions src/components/Channels/EditChannel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PencilIcon class="h-4 w-4" />
<span class="sr-only">Edit</span>
</button>
<Modal :is-open="isModalOpen" @close-modal="closeModal">
<ThemedModal :is-open="isModalOpen" @close-modal="closeModal">
<template #title>Edit Channel</template>
<span class="font-semibold">Channel name:</span>
<div>
Expand Down Expand Up @@ -60,14 +60,14 @@
Update
</button>
</template>
</Modal>
</ThemedModal>
</template>

<script setup>
import { PencilIcon } from '@heroicons/vue/outline'
import { computed, ref } from '@vue/reactivity'
import useStore from '../../composables/global/useStore'
import Modal from '../Shared/Modal.vue'
import ThemedModal from '../Shared/ThemedModal.vue'
const { updateChannel, getGuestStatus } = useStore
const isModalOpen = ref(false)
Expand Down
6 changes: 3 additions & 3 deletions src/components/Messages/PromptDirtyDraft.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<Modal :is-open="isModalOpen" @close-modal="closeModal">
<ThemedModal :is-open="isModalOpen" @close-modal="closeModal">
<template #title>Draft will be lost.</template>
<div class="font-semibold">
<p>Are you sure you want to leave?</p>
Expand All @@ -19,14 +19,14 @@
Yes
</button>
</template>
</Modal>
</ThemedModal>
</template>

<script setup>
import { TrashIcon } from '@heroicons/vue/outline'
import { ref } from '@vue/reactivity'
import { watch } from 'vue'
import Modal from '../Shared/Modal.vue'
import ThemedModal from '../Shared/ThemedModal.vue'
const props = defineProps({
show: {
Expand Down
74 changes: 74 additions & 0 deletions src/components/Polls/CreatePoll.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<template>
<p class="text-gray-600 mb-4">
Submit responses and vote on them anonymously. When a response gets enough votes, voters for that response reveal their
names.
</p>
<div class="mb-4">
<span class="font-semibold">Poll title:</span>
<div>
<input v-model="title" class="border rounded border-gray-500 w-full h-12 px-3" type="text" />
</div>
</div>
<div class="mb-4">
<span class="font-semibold">Description:</span>
<div>
<textarea v-model="description" rows="2" class="h-full border rounded border-gray-500 w-full p-3" type="text">
</textarea>
</div>
</div>
<div class="mb-4">
<p class="font-semibold">End date:</p>

<!-- Date picker -->
<div class="flex max-w-sm border rounded border-gray-500 w-full">
<input v-model="expirationDate" class="rounded w-full p-3" type="date" :min="today" />
</div>
</div>
<!-- Error message -->
<div class="text-harvard-red mt-2">{{ message }}</div>
</template>

<script setup>
import { ref } from '@vue/reactivity'
import useStore from '../../composables/global/useStore'
import { useRoute } from 'vue-router'
const { createPoll } = useStore
const title = ref('')
const description = ref('')
const message = ref('')
const route = useRoute()
const today = new Date().toISOString().split('T')[0]
const date = new Date()
date.setDate(date.getDate() + 5)
const defaultDate = date.toISOString().split('T')[0]
const expirationDate = ref(defaultDate)
defineExpose({
processCreate
})
const emit = defineEmits(['createSuccess'])
function processCreate() {
if (!hasTitle()) {
message.value = 'A title is required.'
return
}
const expirationDateValue = new Date(expirationDate.value)
createPoll({
title: title.value,
description: description.value,
expirationDate: expirationDateValue,
topicId: route.params.channelId
})
.then((x) => emit('createSuccess'))
.catch((err) => (message.value = err.response.data.message))
}
function hasTitle() {
return title.value.trim().length > 0
}
</script>
100 changes: 100 additions & 0 deletions src/components/Shared/CreateSpace.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<template>
<button
v-if="show"
class="flex gap-2 justify-start items-center bg-harvard-red text-white p-2 rounded-md shadow-md"
@click="openModal"
>
<PlusCircleIcon class="w-5 h-5" /> new space
</button>
<ThemedModal :is-open="isModalOpen" @close-modal="closeModal">
<template #title>New space</template>
<!-- Space type tabs -->
<ul class="flex flex-wrap text-center text-gray-500 border-b border-gray-200">
<li>
<button
class="flex gap-1 px-4 py-2 rounded-t-lg"
:class="tab === 1 ? 'text-harvard-red bg-gray-100 font-bold' : ''"
@click="openTab(1)"
>
<HashtagIcon class="w-5 h-5" />
Thread
</button>
</li>
<li>
<button
class="flex gap-1 px-4 py-2 rounded-t-lg"
:class="tab === 2 ? 'text-harvard-red bg-gray-100 font-bold' : ''"
@click="openTab(2)"
>
<UserGroupIcon class="w-5 h-5" />
Threshold Poll
</button>
</li>
</ul>
<!-- Tab content -->
<div v-show="tab === 1" class="py-3 mb-5">
<CreateThread ref="createThreadRef" @create-success="closeModal" />
</div>
<div v-show="tab === 2" class="py-3 mb-5">
<CreatePoll ref="createPollRef" @create-success="closeModal" />
</div>
<!-- Action buttons -->
<template #actions>
<button
class="rounded bg-gray-300 px-2 py-2 font-semibold shadow-sm hover:bg-gray-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-600"
@click="closeModal"
>
Cancel
</button>
<button
class="rounded bg-gray-600 px-2 py-2 font-semibold text-white shadow-sm hover:bg-gray-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gray-600"
@click="onSubmit"
>
Create
</button>
</template>
</ThemedModal>
</template>

<script setup>
import { ref } from '@vue/reactivity'
import ThemedModal from './ThemedModal.vue'
import CreateThread from '../Threads/CreateThread.vue'
import CreatePoll from '../Polls/CreatePoll.vue'
import { PlusCircleIcon, HashtagIcon, UserGroupIcon } from '@heroicons/vue/outline'
defineProps({
show: {
type: Boolean,
required: true
}
})
const isModalOpen = ref(false)
const tab = ref(1)
const createThreadRef = ref(null)
const createPollRef = ref(null)
function closeModal() {
document.querySelector('body').classList.remove('modal-open')
isModalOpen.value = false
}
function openModal() {
window.scrollTo({ top: 0, left: 0 })
isModalOpen.value = true
document.querySelector('body').classList.add('modal-open')
}
function openTab(tabNumber) {
tab.value = tabNumber
}
function onSubmit() {
if (tab.value === 1) {
createThreadRef.value.processCreate()
} else if (tab.value === 2) {
createPollRef.value.processCreate()
}
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<slot name="title">Modal Title</slot>
<XIcon class="mt-1 float-right h-6 w-6 inline-block cursor-pointer" title="Close" @click="closeModal" />
</div>
<div class="flex-grow py-3"><slot>Modal Body</slot></div>
<div class="flex-grow"><slot>Modal Body</slot></div>
<div class="flex justify-end my-3 gap-4">
<slot name="actions"><button @click="closeModal"></button></slot>
</div>
Expand All @@ -18,7 +18,7 @@
<script setup>
import { XIcon } from '@heroicons/vue/outline'
const props = defineProps({
defineProps({
isOpen: {
type: Boolean,
required: true
Expand Down
Loading

0 comments on commit bad3b51

Please sign in to comment.