diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..306a70d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "sveltejs" + ] +} \ No newline at end of file diff --git a/src/routes/home/index.ts b/src/routes/home/index.ts index c6d5736..8ab7016 100644 --- a/src/routes/home/index.ts +++ b/src/routes/home/index.ts @@ -1,35 +1,13 @@ -import type { RequestHandler } from "@sveltejs/kit"; -import prisma from "$root/lib/prisma"; -import { timePosted } from "$root/lib/date"; +import type { RequestHandler } from '@sveltejs/kit' + +import { + createTweet, + getTweets, + removeTweet +} from '$root/utils/prisma' export const get: RequestHandler = async () => { - const data = await prisma.tweet.findMany({ - 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 - ) - - const tweets = data.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) - } - }) + const tweets = await getTweets() if (!tweets) { return { status: 400 } @@ -43,26 +21,16 @@ export const get: RequestHandler = async () => { } export const post: RequestHandler = async ({ request }) => { - const form = await request.formData() - const tweet = String(form.get('tweet')) - - if (tweet.length > 140) { - return { - status: 400, - body: 'Maximum Tweet length exceeded.', - headers: { location: '/home' } - } - } - - await prisma.tweet.create({ - data: { - posted: new Date(), - url: Math.random().toString(16).slice(2), - content: tweet, - likes: 0, - user: { connect: { id: 1 } } - } - }) + await createTweet(request) return {} -} \ No newline at end of file +} + +export const del: RequestHandler = async ({ request }) => { + await removeTweet(request) + + return { + status: 303, + headers: { location: '/home' } + } +} diff --git a/src/routes/home/like.ts b/src/routes/home/like.ts index 8287850..ae8462c 100644 --- a/src/routes/home/like.ts +++ b/src/routes/home/like.ts @@ -1,52 +1,14 @@ -import prisma from "$root/lib/prisma"; -import type { RequestHandler } from "@sveltejs/kit"; +import type { RequestHandler } from '@sveltejs/kit' + +import { likeTweet } from '$root/utils/prisma' export const post: RequestHandler = async ({ request }) => { - const form = await request.formData() - const id = +form.get('id') - - const liked = await prisma.liked.count({ - where: { tweetId: id } - }) - - if (liked === 1) { - await prisma.liked.delete({ where: { tweetId: id } }) - - const count = await prisma.tweet.findUnique({ - where: { id }, - select: { likes: true } - }) - - await prisma.tweet.update({ - where: { id }, - data: { likes: count.likes -= 1 } - }) - - return { - status: 303, - headers: { location: '/home' } - } - } - - await prisma.liked.create({ - data: { - tweetId: id, - user: { connect: { id: 1 } } - } - }) - - const count = await prisma.tweet.findUnique({ - where: { id }, - select: { likes: true } - }) - - await prisma.tweet.update({ - where: { id }, - data: { likes: (count.likes += 1) } - }) + await likeTweet(request) return { status: 303, - headers: { location: '/home' } + headers: { + location: '/home' + } } -} \ No newline at end of file +} diff --git a/src/routes/home/profile/[user].ts b/src/routes/home/profile/[user].ts index 9c68063..be73f5c 100644 --- a/src/routes/home/profile/[user].ts +++ b/src/routes/home/profile/[user].ts @@ -1,48 +1,12 @@ -import type { RequestHandler } from "@sveltejs/kit"; - -import prisma from "$root/lib/prisma"; -import { timePosted } from "$root/lib/date"; +import type { RequestHandler } from '@sveltejs/kit' +import { getUserProfile } from '$root/utils/prisma' 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) - } - }) + const { profile, tweets } = await getUserProfile(params) return { + headers: { 'Content-Type': 'application/json' }, status: 200, - body: { profile, tweets: userTweets } + body: { profile, tweets } } -} \ No newline at end of file +} diff --git a/src/routes/home/profile/[user]/status/[tweetId]/index.ts b/src/routes/home/profile/[user]/status/[tweetId]/index.ts index 15c6183..0e2a33d 100644 --- a/src/routes/home/profile/[user]/status/[tweetId]/index.ts +++ b/src/routes/home/profile/[user]/status/[tweetId]/index.ts @@ -1,36 +1,16 @@ -import { timePosted } from "$root/lib/date"; -import prisma from "$root/lib/prisma"; -import type { RequestHandler } from "@sveltejs/kit"; +import type { RequestHandler } from '@sveltejs/kit' + +import { getTweet } from '$root/utils/prisma' export const get: RequestHandler = async ({ params }) => { - const tweet = await prisma.tweet.findFirst({ - where: { url: params.tweetId }, - include: { user: true } - }) + const tweet = await getTweet(params) - const liked = await prisma.liked.findMany({ - where: { userId: 1 }, - select: { tweetId: true } - }) - - const likedTweets = Object.keys(liked).map( - key => liked[key].tweetId - ) - - const userTweet = { - 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) + if (!tweet) { + return { status: 400 } } return { status: 200, - body: { tweet: userTweet } + body: { tweet } } -} \ No newline at end of file +} diff --git a/src/utils/prisma.ts b/src/utils/prisma.ts new file mode 100644 index 0000000..79eef42 --- /dev/null +++ b/src/utils/prisma.ts @@ -0,0 +1,179 @@ +import prisma from '$root/lib/prisma' +import { timePosted } from '$root/lib/date' + +export async function getTweets() { + const tweets = await prisma.tweet.findMany({ + include: { user: true }, + orderBy: { posted: 'desc' } + }) + + const likedTweets = await getLikedTweets() + + return 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) + } + }) +} + +export async function getTweet( + params: Record +) { + const tweet = await prisma.tweet.findFirst({ + where: { url: params.tweetId }, + include: { user: true } + }) + + const likedTweets = await getLikedTweets() + + 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) + } +} + +export async function getLikedTweets() { + const liked = await prisma.liked.findMany({ + where: { userId: 1 }, + select: { tweetId: true } + }) + + const likedTweets = Object.keys(liked).map( + (key) => liked[key].tweetId + ) + + return likedTweets +} + +export async function createTweet(request: Request) { + const form = await request.formData() + const tweet = String(form.get('tweet')) + + if (tweet.length > 140) { + return { + status: 400, + body: 'Maximum Tweet length exceeded.', + headers: { location: '/home' } + } + } + + // you can get the user from the session + await prisma.tweet.create({ + data: { + posted: new Date(), + url: Math.random().toString(16).slice(2), + content: tweet, + likes: 0, + user: { connect: { id: 1 } } + } + }) +} + +export async function removeTweet(request: Request) { + const form = await request.formData() + const tweetId = +form.get('id') + await prisma.tweet.delete({ where: { id: tweetId } }) +} + +export async function likeTweet(request: Request) { + const form = await request.formData() + const id = +form.get('id') + + // verify if tweet is already liked + const liked = await prisma.liked.count({ + where: { tweetId: id } + }) + + if (liked === 1) { + // if tweet is already liked unlike it + await prisma.liked.delete({ where: { tweetId: id } }) + + // update the likes count + const count = await prisma.tweet.findUnique({ + where: { id }, + select: { likes: true } + }) + + await prisma.tweet.update({ + where: { id }, + data: { likes: (count.likes -= 1) } + }) + + return { + status: 303, + headers: { + location: '/home' + } + } + } + + // add liked record + await prisma.liked.create({ + data: { + tweetId: id, + user: { connect: { id: 1 } } + } + }) + + // get the current like count and update it + const count = await prisma.tweet.findUnique({ + where: { id }, + select: { likes: true } + }) + + await prisma.tweet.update({ + where: { id }, + data: { likes: (count.likes += 1) } + }) +} + +export async function getUserProfile( + params: Record +) { + 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 likedTweets = await getLikedTweets() + + 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 { profile, tweets: userTweets } +} diff --git a/svelte.config.js b/svelte.config.js index 5152a9d..08ba275 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -16,7 +16,8 @@ const config = { $root: path.resolve('./src') } } - } + }, + methodOverride: { allowed: ['DELETE'] } } };