Skip to content
Snippets Groups Projects
Commit b924b942 authored by Yusuf Akgül's avatar Yusuf Akgül :hatching_chick:
Browse files

Merge branch 'tweeting' into 'main'

Tweeting

See merge request !10
parents 5f0ba261 61ad08ec
No related branches found
No related tags found
1 merge request!10Tweeting
Pipeline #35042 passed
import LikeButton from "@/components/LikeButton";
import PostMessageForm from "@/components/post-messages"; import PostMessageForm from "@/components/post-messages";
import { prisma } from "@/prisma/db"; import { prisma } from "@/prisma/db";
import { Prisma} from "@prisma/client"
type likeType = Prisma.LikeUncheckedCreateInput
type messageType = Prisma.MessageUncheckedCreateInput
type messageItemProps = {
msg: messageType;
};
export default async function HomePage() { export default async function HomePage() {
let messages = null let messages = null
try { try {
messages = await prisma.message.findMany() messages = await prisma.message.findMany({
orderBy:{
sentAt: "desc"
}
})
} catch (error) { } catch (error) {
console.log("the database is not running, try: 'npx prisma migrate dev --name init' if you want to use the database") console.log("the database is not running, try: 'npx prisma migrate dev --name init' if you want to use the database")
} }
...@@ -14,16 +26,69 @@ export default async function HomePage() { ...@@ -14,16 +26,69 @@ export default async function HomePage() {
<h1>Home WIP</h1> <h1>Home WIP</h1>
<p>This will be where all messages show up.</p> <p>This will be where all messages show up.</p>
<p>Needs a reload after posting!!</p> <p>Needs a reload after posting!!</p>
{/* <PostMessageForm data={messages}></PostMessageForm> */}
<PostMessageForm data={messages}/>
{messages ? {messages ?
<> <>
{messages.map((msg) => ( {messages.map((msg) => (
<li key={msg.id}> author: {msg.author} message: {msg.content} sentAt: {msg.sentAt?.toString()} </li> <MessageItem msg={msg} key={msg.id} />
))} ))}
<PostMessageForm data={messages}></PostMessageForm>
</> </>
: :
<p>no messages / no database</p>} <p>no messages / no database</p>}
</div> </div>
) )
}
const MessageItem = ({ msg }: messageItemProps) => {
if(!msg.id){
return <div></div>
}
return (
<div className="flex border-b border-gray-200 py-4">
<div className="flex-shrink-0">
<div className="h-10 w-10 rounded-full bg-gray-300"></div> {/* Profile picture */}
</div>
<div className="ml-4 flex flex-col">
<div>
<div className="flex items-center">
<span className="font-bold mr-2">{msg.author}</span>
<span className="text-gray-500 text-sm">
{formatDate(new Date(msg.sentAt!))}
</span>
</div>
<div className="text-gray-800">{msg.content}</div>
</div>
<div className="mt-4">
<div className="flex items-center">
<div className="bg-gray-200 rounded-lg py-10 px-20 mr-2">
{/* potential Image */}
</div>
</div>
</div>
<LikeButton data={{
postId: msg.id,
author: msg.author
}}/>
<span className="text-gray-600">Like Count: {msg.likeCount} | <span className="text-gray-600">ReplyButton (Number of Replies)</span></span>
</div>
</div>
);
};
function formatDate(date: Date){
return date.toLocaleDateString("en-US", {
day: "numeric",
month: "short",
year: "numeric"
});
} }
\ No newline at end of file
import { prisma } from "@/prisma/db"
import { Prisma} from "@prisma/client"
type likeType = Prisma.LikeUncheckedCreateInput
/**
* Creates like if user has not liked this post.
* Deletes like if user has liked post already.
*
*/
export async function putLike(like: likeType): Promise<likeType | undefined> {
//check if like exists by this user and for this post
// if exists delete
//if not create
try{
const actualLike = await prisma.like.findFirst({
where: {
id: like.id,
postId: like.postId,
author: like.author
}
})
if(actualLike == null){
console.log("like is null")
throw Error("Message was not liked by this user")
}
await prisma.like.delete({
where: {
id: actualLike.id
}
})
const msg = await prisma.message.update({
where: {
id: like.postId
},
data:{
likeCount: {increment: -1}
}
})
return undefined;
} catch{
const createdLike = await prisma.like.create({
data:{
postId: like.postId,
author: like.author
}
})
const updatedMessage = await prisma.message.update({
where: {
id: like.postId
},
data:{
likeCount: {increment: 1}
}
})
return createdLike
}
}
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/prisma/db"
import { Prisma} from "@prisma/client"
import { putLike } from "./likeService";
type like = Prisma.LikeUncheckedCreateInput
export async function PUT(req: NextRequest) {
const data:like = await req.json()
console.log("router data: " + data, "status:")
try {
const msg = await putLike(data)
return NextResponse.json({ status: 200, message: 'Like handled' })
} catch (error) {
console.log("fail" + error);
return NextResponse.json(error, { status: 500 });
}
}
\ No newline at end of file
...@@ -19,4 +19,24 @@ export async function POST(req: NextRequest) { ...@@ -19,4 +19,24 @@ export async function POST(req: NextRequest) {
// res.status(400) // res.status(400)
} }
console.log("post") console.log("post")
}
export async function GET(req: NextRequest, res:NextResponse) {
const data = await req.json()
console.log("router data: " + data, "status:")
console.log(data)
try {
const messages = await prisma.message.findMany({
orderBy:{
sentAt: "desc"
}
})
return NextResponse.json({ status: 200, messages: messages })
} catch (error) {
console.log("fail" + error);
// res.status(400)
}
console.log("get")
} }
\ No newline at end of file
"use client"
import { Message } from "@prisma/client"
import { useRouter } from "next/navigation";
import { prisma } from "@/prisma/db";
import { Prisma} from "@prisma/client"
type likeType = Prisma.LikeUncheckedCreateInput
import { startTransition, useState } from "react"
export default function LikeButton(props: { data: likeType }) {
const router = useRouter();
async function postLike(e: any) {
e.preventDefault()
const msgLikeData = props.data;
const likeData = {} as likeType
likeData.author = msgLikeData.author
likeData.postId = msgLikeData.postId
const response = await fetch('http://localhost:3000/api/likes', {
method: 'PUT',
body: JSON.stringify(likeData)
})
startTransition(() => {
// Refresh the current route and fetch new data from the server without
// losing client-side browser or React state.
router.refresh();
});
return await response.json()
}
return (
<div>
<form onSubmit={postLike}>
<button type="submit" className="mt-2 bg-gray-300 text-gray-800 px-4 py-2 rounded float-right">
Like
</button>
</form>
</div>
)
}
\ No newline at end of file
"use client" "use client"
import { Message } from "@prisma/client" import { Message } from "@prisma/client"
import { useState } from "react" import { useRouter } from "next/navigation";
import { prisma } from "@/prisma/db";
import { Prisma} from "@prisma/client"
type messageType = Prisma.MessageUncheckedCreateInput
import { startTransition, useState } from "react"
export default function PostMessageForm(props: { data: Message[] | null }) { export default function PostMessageForm(props: { data: Message[] | null }) {
const [formData, setFormData] = useState({})
const [formData, setFormData] = useState<messageType>({content:""} as messageType);
// const [messagesState, setMessages] = useState(props.data) // const [messagesState, setMessages] = useState(props.data)
const router = useRouter();
async function postMessage(e: any) { async function postMessage(e: any) {
e.preventDefault() e.preventDefault()
// setMessages([...messagesState, formData]) // setMessages([...messagesState, formData])
console.log(formData) console.log(formData)
formData.author = "Default Author"
const response = await fetch('http://localhost:3000/api/messages', { const response = await fetch('http://localhost:3000/api/messages', {
method: 'POST', method: 'POST',
body: JSON.stringify(formData) body: JSON.stringify(formData)
}) })
startTransition(() => {
// Refresh the current route and fetch new data from the server without
// losing client-side browser or React state.
router.refresh();
});
return await response.json() return await response.json()
} }
const characterCount = formData.content.length;
const isOverLimit = characterCount > 1000;
const handleInputChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
const { value } = e.target;
setFormData({ content: value });
};
return ( return (
<div> <div>
<form onSubmit={postMessage}> <form onSubmit={postMessage}>
<input type="text" placeholder="content" name="content" onChange={e => setFormData({ ...formData, content: e.target.value })} /> <textarea
<button type="submit">Post Message</button> placeholder="Write something..."
name="content"
value={formData.content}
onChange={handleInputChange}
className="w-full p-2 border border-gray-600 rounded-xl resize-none"
rows={5}
maxLength={1000}
></textarea>
<div className="flex justify-end mt-2">
<span className={`${isOverLimit ? "text-red-500" : "text-gray-500"} text-sm`}>
{characterCount}/{1000}
</span>
</div>
<button type="submit" className="mt-2 bg-gray-300 text-gray-800 px-4 py-2 rounded float-right">
Post
</button>
</form> </form>
</div> </div>
) )
......
...@@ -16,6 +16,15 @@ model Message { ...@@ -16,6 +16,15 @@ model Message {
gameId String? gameId String?
title String? title String?
content String content String
likeCount Int? @default (0)
sentAt DateTime? @default(now()) sentAt DateTime? @default(now())
updatedAt DateTime? @updatedAt updatedAt DateTime? @updatedAt
} }
model Like {
id Int @id @default(autoincrement())
postId Int
author String?
gameId String?
likedAt DateTime? @default(now())
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment