Add events tab to user details page
This commit is contained in:
		
							parent
							
								
									9ac5053a0e
								
							
						
					
					
						commit
						753cef9413
					
				|  | @ -35,7 +35,7 @@ export const meta = { | |||
| 			message: 'Invalid Parameter', | ||||
| 			code: 'INVALID_PARAM', | ||||
| 			id: 'e70903d3-0aa2-44d5-a955-4de5723c603d', | ||||
| 		} | ||||
| 		}, | ||||
| 	}, | ||||
| } as const; | ||||
| 
 | ||||
|  | @ -50,7 +50,7 @@ export const paramDef = { | |||
| 			nullable: true, | ||||
| 			description: 'The local host is represented with `null`.', | ||||
| 		}, | ||||
| 		users: { type: 'array', nullable: true, items: { type: 'object', format: 'misskey:id' } }, | ||||
| 		users: { type: 'array', nullable: true, items: { type: 'string', format: 'misskey:id' } }, | ||||
| 		sinceDate: { type: 'integer', nullable: true }, | ||||
| 		untilDate: { type: 'integer', nullable: true }, | ||||
| 		filters: { | ||||
|  | @ -109,15 +109,19 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { | |||
| 			} | ||||
| 
 | ||||
| 			if (ps.sinceDate && ps.untilDate && ps.sinceDate > ps.untilDate) throw new ApiError(meta.errors.invalidParam); | ||||
| 			const sinceDate = ps.sinceDate ? new Date(ps.sinceDate) : new Date(); | ||||
| 			query.andWhere('event.start > :sinceDate', { sinceDate: sinceDate }) | ||||
| 				.andWhere('(event.end IS NULL OR event.end > :sinceDate)', { sinceDate: sinceDate }); | ||||
| 
 | ||||
| 			if (ps.sinceDate || ps.sortBy !== 'createdAt') { | ||||
| 				const sinceDate = ps.sinceDate ? new Date(ps.sinceDate) : new Date(); | ||||
| 				query.andWhere('event.start > :sinceDate', { sinceDate: sinceDate }) | ||||
| 					.andWhere('(event.end IS NULL OR event.end > :sinceDate)', { sinceDate: sinceDate }); | ||||
| 			} | ||||
| 
 | ||||
| 			if (ps.untilDate) { | ||||
| 				query.andWhere('event.start < :untilDate', { untilDate: new Date(ps.untilDate) }); | ||||
| 			} | ||||
| 
 | ||||
| 			if (ps.sortBy === 'createdAt') { | ||||
| 				query.orderBy('note.createdAt', 'ASC'); | ||||
| 				query.orderBy('note.createdAt', 'DESC'); | ||||
| 			} else { | ||||
| 				query.orderBy('event.start', 'ASC'); | ||||
| 			} | ||||
|  |  | |||
|  | @ -3,8 +3,8 @@ | |||
| <div>Start: {{ note.event!.start }}</div> | ||||
| <div v-if="!!note.event!.end">End: {{ note.event!.end }}</div> | ||||
| <ul> | ||||
| 	<li v-for="k in Object.keys(note.event!.metadata)"> | ||||
| 	{{ k }}: {{ note.event!.metadata[k] }} | ||||
| 	<li v-for="k in Object.keys(note.event!.metadata)" :key="k"> | ||||
| 		{{ k }}: {{ note.event!.metadata[k] }} | ||||
| 	</li> | ||||
| </ul> | ||||
| </template> | ||||
|  |  | |||
|  | @ -0,0 +1,50 @@ | |||
| <template> | ||||
| <MkSpacer :content-max="800" style="padding-top: 0"> | ||||
| 	<MkStickyContainer> | ||||
| 		<template #header> | ||||
| 			<MkTab v-model="include" :class="$style.tab"> | ||||
| 				<option :value="null">{{ i18n.ts.events || 'Events' }}</option> | ||||
| 				<option value="upcoming">{{ i18n.ts.upcomingEvents || 'Upcoming' }}</option> | ||||
| 			</MkTab> | ||||
| 		</template> | ||||
| 		<MkNotes :no-gap="true" :pagination="pagination" :class="$style.tl"/> | ||||
| 	</MkStickyContainer> | ||||
| </MkSpacer> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts" setup> | ||||
| import { ref, computed } from 'vue'; | ||||
| import * as misskey from 'misskey-js'; | ||||
| import MkNotes from '@/components/MkNotes.vue'; | ||||
| import MkTab from '@/components/MkTab.vue'; | ||||
| import { i18n } from '@/i18n'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
| 	user: misskey.entities.UserDetailed; | ||||
| }>(); | ||||
| 
 | ||||
| const include = ref<string | null>(null); | ||||
| 
 | ||||
| const pagination = { | ||||
| 	endpoint: 'notes/events/search' as const, | ||||
| 	limit: 10, | ||||
| 	params: computed(() => ({ | ||||
| 		users: [props.user.id], | ||||
| 		sortBy: include.value === 'upcoming' ? 'startDate' : 'createdAt', | ||||
| 	})), | ||||
| }; | ||||
| </script> | ||||
| 
 | ||||
| <style lang="scss" module> | ||||
| .tab { | ||||
| 	margin: calc(var(--margin) / 2) 0; | ||||
| 	padding: calc(var(--margin) / 2) 0; | ||||
| 	background: var(--bg); | ||||
| } | ||||
| 
 | ||||
| .tl { | ||||
| 	background: var(--bg); | ||||
|     border-radius: var(--radius); | ||||
|     overflow: clip; | ||||
| } | ||||
| </style> | ||||
|  | @ -5,7 +5,8 @@ | |||
| 		<Transition name="fade" mode="out-in"> | ||||
| 			<div v-if="user"> | ||||
| 				<XHome v-if="tab === 'home'" :user="user"/> | ||||
| 				<XTimeline v-else-if="tab === 'notes'" :user="user" /> | ||||
| 				<XTimeline v-else-if="tab === 'notes'" :user="user"/> | ||||
| 				<XEvent v-else-if="tab === 'events'" :user="user"/> | ||||
| 				<XActivity v-else-if="tab === 'activity'" :user="user"/> | ||||
| 				<XAchievements v-else-if="tab === 'achievements'" :user="user"/> | ||||
| 				<XReactions v-else-if="tab === 'reactions'" :user="user"/> | ||||
|  | @ -32,6 +33,7 @@ import { $i } from '@/account'; | |||
| 
 | ||||
| const XHome = defineAsyncComponent(() => import('./home.vue')); | ||||
| const XTimeline = defineAsyncComponent(() => import('./index.timeline.vue')); | ||||
| const XEvent = defineAsyncComponent(() => import('./events.vue')); | ||||
| const XActivity = defineAsyncComponent(() => import('./activity.vue')); | ||||
| const XAchievements = defineAsyncComponent(() => import('./achievements.vue')); | ||||
| const XReactions = defineAsyncComponent(() => import('./reactions.vue')); | ||||
|  | @ -74,6 +76,10 @@ const headerTabs = $computed(() => user ? [{ | |||
| 	key: 'notes', | ||||
| 	title: i18n.ts.notes, | ||||
| 	icon: 'ti ti-pencil', | ||||
| }, { | ||||
| 	key: 'events', | ||||
| 	title: 'Events', //i18n.ts.events, | ||||
| 	icon: 'ti ti-calendar', | ||||
| }, { | ||||
| 	key: 'activity', | ||||
| 	title: i18n.ts.activity, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue