Add profile page.

This commit is contained in:
Bradley Shellnut 2022-04-06 16:28:13 -07:00
parent 3ba06b230b
commit 5e44e9516e
2 changed files with 172 additions and 0 deletions

View file

@ -0,0 +1,124 @@
<script lang="ts">
import type { User } from '@prisma/client'
import Tweet from '$root/components/tweet.svelte'
import type { TweetType } from '$root/types'
export let profile: User
export let tweets: TweetType[]
</script>
<svelte:head>
<title>{profile.name} ({profile.handle})</title>
</svelte:head>
<div class="profile">
<img
class="banner"
src="/profile/{profile.name}/banner.webp"
alt="Profile Banner"
>
<img
class="avatar"
src={profile.avatar}
alt={profile.name}
>
</div>
<div class="content">
<div class="user">
<span class="name">{profile.name}</span>
<span class="handle">{profile.handle}</span>
</div>
<div class="about">
<span class="about">{profile.about}</span>
</div>
</div>
<nav>
<a href="/" class="active">Tweets</a>
<a href="/">Tweets & replies</a>
<a href="/">Media</a>
<a href="/">Likes</a>
</nav>
{#each tweets as tweet (tweet.id)}
<Tweet {tweet} />
{/each}
<style>
.profile {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: 200px 60px;
}
.banner {
grid-column: 1 / -1;
grid-row: 1 / 2;
}
.avatar {
grid-column: 1 / 2;
grid-row: 1 / -1;
place-self: center;
align-self: flex-end;
width: 120px;
height: 120px;
margin: 0 var(--spacing-16);
border-radius: 50%;
border: 4px solid var(--color-bg-primary);
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
.content {
display: grid;
gap: var(--spacing-16);
margin-top: var(--spacing-16);
padding: 0 var(--spacing-16);
}
.user {
display: grid;
}
.name {
font-size: var(--font-24);
font-weight: 700;
text-transform: capitalize;
}
.handle {
color: var(--color-text-muted);
}
nav {
display: flex;
justify-content: center;
margin-top: var(--spacing-32);
border-bottom: 1px solid var(--color-border-primary);
}
a {
padding: var(--spacing-16) var(--spacing-32);
font-size: var(--font-16);
color: var(--color-text-muted);
border-bottom: 4px solid transparent;
transition: all 0.2s;
}
a:hover {
background-color: var(--color-link-hover);
border-bottom: 4px solid var(--color-brand);
}
.active {
font-weight: 700;
border-bottom: 4px solid var(--color-brand);
}
</style>

View file

@ -0,0 +1,48 @@
import type { RequestHandler } from "@sveltejs/kit";
import prisma from "$root/lib/prisma";
import { timePosted } from "$root/lib/date";
export const get: RequestHandler = async ({ params }) => {
const profile = await prisma.user.findFirst({
where: { name: params.user }
})
const tweets = await prisma.tweet.findMany({
where: { user: { id: 1 } },
include: { user: true },
orderBy: { posted: 'desc' }
})
const liked = await prisma.liked.findMany({
where: { userId: 1 },
select: { tweetId: true }
})
const likedTweets = Object.keys(liked).map(
key => liked[key].tweetId
)
if (!profile || !tweets || tweets.length === 0) {
return { status: 404 }
}
const userTweets = tweets.map(tweet => {
return {
id: tweet.id,
content: tweet.content,
likes: tweet.likes,
posted: timePosted(tweet.posted),
url: tweet.url,
avatar: tweet.user.avatar,
handle: tweet.user.handle,
name: tweet.user.name,
liked: likedTweets.includes(tweet.id)
}
})
return {
status: 200,
body: { profile, tweets: userTweets }
}
}