Skip to content

Commit

Permalink
Co-authored-by: Andreas Müller <[email protected]>
Browse files Browse the repository at this point in the history
  • Loading branch information
MelissaAutumn committed May 8, 2024
1 parent 6124ec7 commit a5df424
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 1 deletion.
2 changes: 2 additions & 0 deletions backend/src/appointment/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ def server():
from .routes import google
from .routes import schedule
from .routes import invite
from .routes import subscriber
from .routes import zoom
from .routes import webhooks

Expand Down Expand Up @@ -189,6 +190,7 @@ async def catch_google_refresh_errors(request, exc):
app.include_router(google.router, prefix="/google")
app.include_router(schedule.router, prefix="/schedule")
app.include_router(invite.router, prefix="/invite")
app.include_router(subscriber.router, prefix="/subscriber")
app.include_router(webhooks.router, prefix="/webhooks")
if os.getenv("ZOOM_API_ENABLED"):
app.include_router(zoom.router, prefix="/zoom")
Expand Down
32 changes: 32 additions & 0 deletions backend/src/appointment/routes/subscriber.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@

from fastapi import APIRouter, Depends

from sqlalchemy.orm import Session

from ..database import repo, schemas, models
from ..database.models import Subscriber
from ..dependencies.auth import get_admin_subscriber
from ..dependencies.database import get_db

from ..exceptions import validation

router = APIRouter()


@router.get('/', response_model=list[schemas.Subscriber])
def get_all_subscriber(db: Session = Depends(get_db), admin: Subscriber = Depends(get_admin_subscriber)):
"""List all existing invites, needs admin permissions"""
return db.query(models.Subscriber).all()


@router.put("/disable/{email}")
def disable_subscriber(email: str, db: Session = Depends(get_db), admin: Subscriber = Depends(get_admin_subscriber)):
"""endpoint to disable a subscriber by email, needs admin permissions"""
raise NotImplementedError

subscriber = repo.subscriber.get_by_email(db, email)
if not subscriber:
raise validation.SubscriberNotFoundException()
# TODO: CAUTION! This actually deletes the subscriber. We might want to only disable them.
# This needs an active flag on the subscribers model.
return repo.subscriber.delete(db, subscriber)
9 changes: 8 additions & 1 deletion frontend/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ const AppointmentsView = defineAsyncComponent(() => import('@/views/Appointments
const SettingsView = defineAsyncComponent(() => import('@/views/SettingsView'));
const ProfileView = defineAsyncComponent(() => import('@/views/ProfileView'));
const LegalView = defineAsyncComponent(() => import('@/views/LegalView'));
const InvitePanelView = defineAsyncComponent(() => import('@/views/InvitePanelView'));
const SubscriberPanelView = defineAsyncComponent(() => import('@/views/SubscriberPanelView'));

/**
* Defined routes for Thunderbird Appointment
Expand Down Expand Up @@ -93,7 +95,12 @@ const routes = [
{
path: '/admin/invites',
name: 'admin-invite-panel',
component: () => import('@/views/InvitePanelView.vue'),
component: InvitePanelView,
},
{
path: '/admin/subscribers',
name: 'admin-subscriber-panel',
component: SubscriberPanelView,
},
];

Expand Down
125 changes: 125 additions & 0 deletions frontend/src/views/SubscriberPanelView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<template>
<!-- page title area -->
<div v-if="user.exists()" class="flex flex-col items-center justify-center gap-4">
<div class="flex flex-row justify-between items-center w-full">
<div>
<span class="font-bold">{{ filteredSubscribers.length }}</span> Subscribers
</div>
<list-pagination
:list-length="filteredSubscribers.length"
:page-size="pageSize"
@update="updatePage"
/>
</div>
<div class="data-table">
<table>
<thead>
<tr>
<th>ID</th>
<th>Username</th>
<th>Email</th>
<th>Invite code used</th>
<th>Time Created</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="subscriber in paginatedSubscribers" :key="subscriber.id">
<td>
<code>{{ subscriber.id }}</code>
</td>
<td>
<code>{{ subscriber.username }}</code>
</td>
<td>
{{ subscriber.email }}
</td>
<td>TODO</td>
<td class="whitespace-nowrap">{{ dj(subscriber.time_created).format('ll LTS') }}</td>
<td class="w-28 py-2">
<!-- TODO -->
<caution-button
disabled
:label="'Disable'"
class="text-sm px-4 h-8"
@click="disableSubscriber(subscriber.email)"
/>
</td>
</tr>
<tr v-if="filteredSubscribers.length === 0">
<td colspan="5">No subscribers could be found.</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="6">
</th>
</tr>
</tfoot>
</table>
</div>
</div>
</template>

<script setup>
import { computed, inject, onMounted, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useUserStore } from '@/stores/user-store';
import CautionButton from '@/elements/CautionButton.vue';
import ListPagination from '@/elements/ListPagination.vue';
// component constants
const user = useUserStore();
const call = inject('call');
const dj = inject('dayjs');
// component constants
const { t } = useI18n();
// pagination
const pageSize = 10;
const currentPage = ref(0);
const updatePage = (index) => {
currentPage.value = index;
}
// subscriber specific props
const subscribers = ref([]);
const filteredSubscribers = computed(() => {
let filtered = subscribers.value;
return filtered;
});
const paginatedSubscribers = computed(() => {
return filteredSubscribers.value.length
? filteredSubscribers.value.slice(currentPage.value*pageSize, (currentPage.value+1)*pageSize)
: [];
});
const getSubscribers = async () => {
const response = await call('subscriber/').get().json();
const { data } = response;
subscribers.value = data.value;
};
const disableSubscriber = async (email) => {
if (!email) {
return;
}
const response = await call(`subscriber/disable/${email}`).put().json();
const { data } = response;
if (data.value) {
await getSubscribers();
}
};
onMounted(async () => {
await getSubscribers();
});
</script>

0 comments on commit a5df424

Please sign in to comment.