251 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Vue
		
	
	
	
			
		
		
	
	
			251 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Vue
		
	
	
	
| <template>
 | |
| 	<div
 | |
| 		v-if="user"
 | |
| 		class="user"
 | |
| 	>
 | |
| 		<div class="header">
 | |
| 			<h2 class="username">{{ user.username }}</h2>
 | |
| 		</div>
 | |
| 
 | |
| 		<section
 | |
| 			v-if="user.stashes?.length > 0"
 | |
| 			class="section"
 | |
| 		>
 | |
| 			<div class="section-header">
 | |
| 				<h3 class="section-heading">Stashes</h3>
 | |
| 
 | |
| 				<Icon
 | |
| 					icon="plus3"
 | |
| 					class="header-add"
 | |
| 					@click="showAddStash = true"
 | |
| 				/>
 | |
| 			</div>
 | |
| 
 | |
| 			<ul class="section-body stashes nolist">
 | |
| 				<li
 | |
| 					v-for="stash in user.stashes"
 | |
| 					:key="stash.id"
 | |
| 					class="stashes-stash"
 | |
| 				>
 | |
| 					<Stash
 | |
| 						:stash="stash"
 | |
| 						:is-me="isMe"
 | |
| 						@publish="() => fetchUser()"
 | |
| 						@remove="() => fetchUser()"
 | |
| 					/>
 | |
| 				</li>
 | |
| 
 | |
| 				<li
 | |
| 					v-if="isMe"
 | |
| 					class="stashes-stash stashes-add"
 | |
| 					@click="showAddStash = true"
 | |
| 				>
 | |
| 					<Icon icon="plus2" />
 | |
| 				</li>
 | |
| 			</ul>
 | |
| 
 | |
| 			<AddStash
 | |
| 				v-if="showAddStash"
 | |
| 				@close="closeAddStash"
 | |
| 			/>
 | |
| 		</section>
 | |
| 
 | |
| 		<section class="section">
 | |
| 			<div class="section-header">
 | |
| 				<h3 class="section-heading">Alerts</h3>
 | |
| 
 | |
| 				<Icon
 | |
| 					icon="plus3"
 | |
| 					class="header-add"
 | |
| 					@click="showAddAlert = true"
 | |
| 				/>
 | |
| 			</div>
 | |
| 
 | |
| 			<ul class="section-body alerts nolist">
 | |
| 				<li
 | |
| 					v-for="alert in user.alerts"
 | |
| 					:key="`alert-${alert.id}`"
 | |
| 					class="alert"
 | |
| 				>
 | |
| 					<Alert
 | |
| 						:alert="alert"
 | |
| 						:is-me="isMe"
 | |
| 						@remove="() => fetchUser()"
 | |
| 					/>
 | |
| 				</li>
 | |
| 
 | |
| 				<li
 | |
| 					class="alerts-add"
 | |
| 					@click="showAddAlert = true"
 | |
| 				>
 | |
| 					<Icon icon="plus2" />
 | |
| 				</li>
 | |
| 			</ul>
 | |
| 
 | |
| 			<AddAlert
 | |
| 				v-if="showAddAlert"
 | |
| 				@close="closeAddAlert"
 | |
| 			>Alert</AddAlert>
 | |
| 		</section>
 | |
| 	</div>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import Stash from './stash.vue';
 | |
| import Alert from './alert.vue';
 | |
| import AddStash from '../stashes/add.vue';
 | |
| import AddAlert from '../alerts/add.vue';
 | |
| 
 | |
| async function fetchUser() {
 | |
| 	this.user = await this.$store.dispatch('fetchUser', this.$route.params.username);
 | |
| 	this.isMe = this.user?.id === this.$store.state.auth.user?.id;
 | |
| 
 | |
| 	this.pageTitle = this.user?.username;
 | |
| }
 | |
| 
 | |
| async function closeAddStash(addedStash) {
 | |
| 	this.showAddStash = false;
 | |
| 
 | |
| 	if (addedStash) {
 | |
| 		await this.fetchUser();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| async function closeAddAlert(addedAlert) {
 | |
| 	this.showAddAlert = false;
 | |
| 
 | |
| 	if (addedAlert) {
 | |
| 		await this.fetchUser();
 | |
| 	}
 | |
| }
 | |
| 
 | |
| async function mounted() {
 | |
| 	await this.fetchUser();
 | |
| }
 | |
| 
 | |
| export default {
 | |
| 	components: {
 | |
| 		AddAlert,
 | |
| 		AddStash,
 | |
| 		Alert,
 | |
| 		Stash,
 | |
| 	},
 | |
| 	data() {
 | |
| 		return {
 | |
| 			user: this.$route.params.username === this.$store.state.auth.user?.username
 | |
| 				? this.$store.state.auth.user
 | |
| 				: null,
 | |
| 			isMe: false,
 | |
| 			pageTitle: null,
 | |
| 			showAddStash: false,
 | |
| 			showAddAlert: false,
 | |
| 		};
 | |
| 	},
 | |
| 	mounted,
 | |
| 	methods: {
 | |
| 		closeAddAlert,
 | |
| 		closeAddStash,
 | |
| 		fetchUser,
 | |
| 	},
 | |
| };
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| @import 'breakpoints';
 | |
| 
 | |
| .header {
 | |
| 	display: flex;
 | |
| 	justify-content: space-between;
 | |
| 	background: var(--profile);
 | |
| }
 | |
| 
 | |
| .username {
 | |
| 	padding: .5rem 1rem;
 | |
| 	margin: 0;
 | |
| 	font-size: 1.5rem;
 | |
| 	color: var(--text-light);
 | |
| 	overflow: hidden;
 | |
| 	white-space: nowrap;
 | |
| 	text-overflow: ellipsis;
 | |
| }
 | |
| 
 | |
| .section {
 | |
| 	padding: 1rem 0;
 | |
| 	margin: 0 0 1rem 0;
 | |
| }
 | |
| 
 | |
| .stashes,
 | |
| .alerts {
 | |
| 	display: grid;
 | |
| 	grid-template-columns: 1fr 1fr;
 | |
| 	grid-auto-rows: 15fr;
 | |
| 	grid-gap: 1rem;
 | |
| }
 | |
| 
 | |
| .section-header {
 | |
| 	display: flex;
 | |
| 	justify-content: space-between;
 | |
| 	align-items: center;
 | |
| 	margin: 0 0 1rem 0;
 | |
| }
 | |
| 
 | |
| .section-body {
 | |
| 	padding: 0 1rem;
 | |
| }
 | |
| 
 | |
| .section-heading {
 | |
| 	color: var(--primary);
 | |
| 	padding: 0 1rem;
 | |
| 	margin: 0;
 | |
| 	font-size: 1.25rem;
 | |
| }
 | |
| 
 | |
| .header-add {
 | |
| 	height: auto;
 | |
| 	padding: .5rem 1rem;
 | |
| 	fill: var(--shadow);
 | |
| 
 | |
| 	&:hover {
 | |
| 		fill: var(--primary);
 | |
| 		cursor: pointer;
 | |
| 	}
 | |
| }
 | |
| 
 | |
| .stashes-stash {
 | |
| 	min-width: 0;
 | |
| }
 | |
| 
 | |
| .stashes-add,
 | |
| .alerts-add {
 | |
| 	height: 100%;
 | |
| 	display: flex;
 | |
| 	align-items: center;
 | |
| 	justify-content: center;
 | |
| 	box-sizing: border-box;
 | |
| 	padding: 1rem;
 | |
| 	background: var(--shadow-touch);
 | |
| 
 | |
| 	.icon {
 | |
| 		width: 1.5rem;
 | |
| 		height: 1.5rem;
 | |
| 		fill: var(--shadow-hint);
 | |
| 	}
 | |
| 
 | |
| 	&:hover {
 | |
| 		background: var(--shadow-hint);
 | |
| 		cursor: pointer;
 | |
| 
 | |
| 		.icon {
 | |
| 			fill: var(--shadow-weak);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| @media(max-width: $breakpoint-kilo) {
 | |
| 	.stashes,
 | |
| 	.alerts {
 | |
| 		grid-template-columns: 1fr;
 | |
| 	}
 | |
| }
 | |
| </style>
 |