posts ansehen, posts im detial, scrollbar entfernt

scrollbar:  - nurnoch in bestimmten elementen
This commit is contained in:
danielvici123
2025-03-23 21:20:43 +01:00
parent c2d5cc6a73
commit 834149ffb9
12 changed files with 403 additions and 112 deletions

View File

@@ -1,3 +1,3 @@
<template>
<template >
<router-view />
</template>

View File

@@ -1,3 +1,5 @@
@plugin 'tailwind-scrollbar';
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@@ -9,7 +9,7 @@ import Trending from "./home_components/trending.vue";
<template>
<div id="main" class="flex">
<div id="left" class="border border-b-grau w-72">
<div id="left" class="w-72">
<navigationbar></navigationbar>
</div>
<div class="w-100p">

View File

@@ -1,67 +1,72 @@
<script setup lang="ts">
import {onMounted, ref} from "vue";
import router from "../../router";
// import {valueOf} from "tailwindcss";
/* PRÜFEN OB USER EINGELOGGT IST
#########################################
* function checkLoginStatus() {
const isLoggedIn = localStorage.getItem('isLoggedIn');
if (isLoggedIn === 'true') {
console.log("User is logged in");
} else {
console.log("User is not logged in");
router.push('/login');
}
// PLACEHOLDER
const upc = ref([]); // user post computed
let post_nr = "";
let current_user = "";
let pust_create_text = "";
/*
*/
async function createFeed() {
try {
// posts und user holen und schauen ob sie richtig sidn
const post_response = await fetch('http://localhost:8000/api/posts', { method: 'GET' });
const postsDATA = await post_response.json();
const user_response = await fetch('http://localhost:8000/api/users', { method: 'GET' });
const usersDATA = await user_response.json();
// posts und user kombinieren
const combinedPosts = postsDATA.map(post => {
const user = usersDATA.find(user => user.user_id === post.user_id);
return {
post_id: post.posts_uuid,
post_text: post.post_text,
likes: post.likes,
comments: post.comments,
displayname: user ? user.displayname : 'Unknown',
username: user ? user.username : 'unknown_user'
};
});
//upc.value = combinedPosts;
upc.value = combinedPosts.sort(() => Math.random() - 0.5);
} catch (e) {
console.error("An error has occurred. Please try again later.");
console.error(e);
}
console.log(upc.value);
}
onMounted(() => {
checkLoginStatus();
});
* */
// PLACEHOLDER
const post = ref([
{id: 1,
profile_picture: "../../assets/default_pp.png",
author_display_name: "Linux Enjoyer",author_username: "lunix",
content:"I love Linux. My Favorite Linux Distro is ARCH LINUX.",
comments_count: 1, likes: 5},
{id: 2,
profile_picture: "../../assets/default_pp.png",
author_display_name: "XBOX",author_username: "Xbox",
content: "Call of Duty: Black Ops 6 is OUT NOW.",
comments_count: 500000, likes: 100000},
{id: 3,
profile_picture: "../../assets/default_pp.png",
author_display_name: "JETBrains",author_username: "Jetbrains",
content: "BLI BLA BLUB. Jetbrains is the best IDE." ,
comments_count: 5000, likes: 1000},
{id: 4,
profile_picture: "../../assets/default_pp.png",
author_display_name: "GITHUB", author_username: "GitHub",
content: "GitHub Copilot got an massive update. Check out the new features.",
comments_count: 1500000, likes: 500000},
{id: 5,
profile_picture: "../../assets/danielvici_pp.png",
author_display_name: "danielvici123", author_username: "danielvici",
content: "I created this WebApp with VUE3 and TailwindCSS. It was a lot of fun.",
comments_count: undefined, likes: 532844},
{id: 6,
profile_picture: "../../assets/default_pp.png",
author_display_name: "Microsoft", author_username: "Microsoft",
content: "Windows 11 24H2 is out now. Learn more here: https://www.microsoft.com",
comments_count: 500000, likes: 100000},
{id: 7,
profile_picture: "../../assets/default_pp.png",
author_display_name: "Apple", author_username: "Apple",
content: "The new iPhone 16 is out now. Everything you need to know: https://www.apple.com",
comments_count: 500000, likes: 100000},
])
function addLike(index: number) {
post.value[index].likes += 1;
console.log("New Like Amount: ", post.value[index].likes);
onMounted(async () => {
await createFeed();
});
async function addLike(index: number) {
post_nr = index.toString()
const response = await fetch(`http://localhost:8000/api/post/${post_nr}/like`, {
method: 'POST',
headers: {'Content-Type': 'application/json',},
});
if (!response.ok) {
alert('Failed to like post');
} else{
console.log("New Like Amount: ", upc.value[index].likes);
}
}
function post_publish_func(text:string) {
function post_create_func(text:string) {
console.log("Post: ", text);
if (text === undefined || text === "") {
console.log("Post is empty");
@@ -69,10 +74,13 @@ onMounted(() => {
return;
} else {
console.log("Post is not empty");
post.value.push({id: post.value.length + 1, profile_picture: "../../assets/danielvici_pp.png", author_display_name: "ADMIN", author_username: "esp_admin", content: text, comments_count: undefined, likes: 0});
}
}
function gotoPost(post_id: number) {
localStorage.setItem("viewedpost", post_id.toString());
router.push(`/post/${post_id}`);
}
</script>
<template>
@@ -84,32 +92,32 @@ onMounted(() => {
<img src="../../assets/danielvici_pp.png" alt="" class="p-2 rounded-full w-16 h-16">
<form>
<!-- post_publish ist richtig aber wird falsch angezeigt. File Input geht nicht-->
<textarea v-model="post_publish" name="post_text" class="bg-hintergrund-farbe rounded-lg m-2 p-1 focus:outline-none text-grau2 w-200p resize-none" rows="3" placeholder="Write something..."></textarea>
<textarea v-model="pust_create_text" name="post_text" class="bg-hintergrund-farbe rounded-lg m-2 p-1 focus:outline-none text-grau2 w-200p resize-none" rows="3" placeholder="Write something..."></textarea>
<div class="">
<input class="text-weiss" type="file" accept=".png, .jpg, .jpeg">
<button id="post_publish" name="post_publishss" class="text-weiss p-1 m-2 rounded-lg py-3 px-5 bg-button-farbe" @click.prevent="post_publish_func(post_publish)" type="button">Post</button>
<button id="post_publish" name="post_publishss" class="text-weiss p-1 m-2 rounded-lg py-3 px-5 bg-button-farbe" @click.prevent="post_create_func(pust_create_text)" type="button">Post</button>
</div>
</form>
</div>
</div>
<div> <!-- CONTENT -->
<div class="overflow-y-auto h-[650px] scrollbar"> <!-- CONTENT -->
<ul>
<li v-for="(postitem, indexus) in post" :key="post" class="border-2 border-b-grau2 p-3 flex">
<li v-for="(postitem, indexus) in upc" :key="upc" class="border-2 border-b-grau2 p-3 flex">
<!-- POST -->
<img src="../../assets/default_pp.png" alt="" class="rounded-full w-16 h-16">
<div>
<div> <!-- POST HEADER -->
<label class="text-lg font-bold m-1 text-weiss">{{postitem.author_display_name}}</label>
<label class="text-base m-1 text-grau2">@{{ postitem.author_username }}</label>
<label class="text-lg font-bold m-1 text-weiss">{{postitem.displayname}}</label>
<label class="text-base m-1 text-grau2">@{{ postitem.username }}</label>
</div>
<div class="m-2"> <!-- POST CONTENT -->
<p class="text-sm m-1 text-weiss">{{ postitem.content }}</p>
<p class="text-sm m-1 text-weiss">{{ postitem.post_text }}</p>
</div>
<div class="flex"> <!-- POST FOOTER -->
<div class="flex"> <!-- Comments -->
<img src="../../assets/icons/comment.png" alt="" class="rounded-full align-middle">
<label class="text-sm m-1 text-weiss" v-if="postitem.comments_count != undefined">{{ postitem.comments_count }}</label>
<label class="text-sm m-1 text-weiss" v-if="postitem.comments != undefined">{{ postitem.comments }}</label>
<label class="text-sm m-1 text-weiss" v-else>Comments disabled</label>
</div>
@@ -119,7 +127,7 @@ onMounted(() => {
</div>
<div class="flex items-center mx-2"> <!-- View Post -->
<router-link :to="{ name: 'PostDetail', params: { id: postitem.id } }" class="text-weiss">View Post</router-link>
<button @click="gotoPost(postitem.post_id)" class="text-weiss">View Post</button>
</div><!-- ENDE -->
</div>
</div>

View File

@@ -10,7 +10,7 @@ onMounted(() => {
if (localStorage.getItem('username')) {
input_username_mail.value = localStorage.getItem('username') || "";
input_user_password.value = localStorage.getItem('password') || "";
rememberMe.value = true;
rememberMe.value = false;
}
});
@@ -30,10 +30,8 @@ async function login(event: Event) {
});
if (response.status === 200) {
if (rememberMe.value) {
localStorage.setItem('username', username.value);
}
localStorage.setItem('isLoggedIn', 'true');
localStorage.setItem('username', username.value);
alert("You will be now redirected");
router.push('/');
} else {
@@ -57,7 +55,7 @@ async function login(event: Event) {
<input class="m-4 w-full max-w-xs bg-grau-dunkel p-4 text-weiss placeholder-grau2 focus:outline-none rounded-lg" v-model="input_username_mail" type="text" placeholder="Username or E-Mail"><br>
<input class="m-4 w-full max-w-xs bg-grau-dunkel p-4 text-weiss placeholder-grau2 focus:outline-none rounded-lg" v-model="input_user_password" type="password" placeholder="Password"><br>
<button class="m-4 bg-button-farbe w-full max-w-xs p-4 text-schwarz rounded-lg">Login</button>
<p class="text-weiss"><input type="checkbox"> Remeber me</p>
<p class="text-weiss"><input type="checkbox" v-model="rememberMe"> Remeber me</p>
</form>
</div>
<div>

View File

@@ -1,44 +1,164 @@
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { useRoute } from 'vue-router';
import Navigationbar from "./home_components/navigationbar.vue";
import Contacts from "./home_components/contacts.vue";
import Legal from "./home_components/legal.vue";
import Navigationbar from './home_components/navigationbar.vue';
import Contacts from './home_components/contacts.vue';
import Legal from './home_components/legal.vue';
import router from '../router';
import {consoleLog} from "vite-plugin-checker/dist/logger";
const route = useRoute();
const post = ref(null);
interface Post {
post_uuid: number;
user_id: number;
author_username: string;
post_text: string;
likes: number;
comments_count: number;
comments: any[];
created_at: string;
}
interface User {
user_id: number;
username: string;
displayname: string;
}
interface Comment {
comment_uuid: number;
user_id: number;
post_id: number;
comment_text: string;
created_at: string;
displayname: string;
username: string;
}
const post = ref<Post | null>(null);
const user = ref<User | null>(null);
const comments = ref<Comment[] | null>(null);
onMounted(async () => {
const postId = route.params.id;
try {
const response = await fetch(`/api/posts/${postId}`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const data = await response.json();
post.value = data;
} catch (error) {
console.error('Error fetching post:', error);
const post_id = localStorage.getItem('viewedpost');
console.log(post_id);
if (post_id === null) {
alert('No post selected. You will be redirected to the feed.');
await router.push('/');
return;
}
getPost(parseInt(post_id));
getComment(parseInt(post_id));
});
async function getPost(post_id: number) {
try {
const post_response = await fetch(`http://localhost:8000/api/post/${post_id}`, { method: 'GET' });
const fetchedPost: Post = await post_response.json();
const user_response = await fetch('http://localhost:8000/api/users', { method: 'GET' });
const usersDATA = await user_response.json();
const postAuthor = usersDATA.find(user => user.user_id === fetchedPost.user_id);
if (postAuthor) {
console.log("The post was written by:", postAuthor);
} else {
console.error("Author not found.");
}
user.value = postAuthor;
post.value = fetchedPost;
console.log(post.value);
} catch (e) {
console.error(e);
}
}
async function getComment(post_id: number) {
try {
const comments_response = await fetch(`http://localhost:8000/api/post/${post_id}/comments`, { method: 'GET' });
const fetchedComments: Comment[] = await comments_response.json();
const user_response = await fetch(`http://localhost:8000/api/users`, { method: 'GET' });
const usersDATA: User[] = await user_response.json();
comments.value = fetchedComments.map(comment => ({
...comment,
author: usersDATA.find(user => user.user_id === comment.user_id) || null
}));
console.log(comments.value);
} catch (e) {
console.error(e);
}
}
</script>
<template>
<div id="main" class="bg-hintergrund-farbe flex">
<div id="left" class="border border-b-grau w-72">
<div id="left" class="w-72">
<navigationbar></navigationbar>
</div>
<div>
<div v-if="post">
<h2>{{ post.author_display_name }}</h2>
<p>@{{ post.author_username }}</p>
<p>{{ post.content }}</p>
<p>Likes: {{ post.likes }}</p>
<p v-if="post.comments_count !== undefined">Comments: {{ post.comments_count }}</p>
<p v-else>Comments disabled</p>
<div class="text-weiss w-100p border-x border-x-grau2" v-if="post">
<div> <!-- HEADER -->
<h2 class="align-middle p-6 text-3xl text-weiss border-b-grau2 border-b">Post</h2>
</div>
<div v-else>
<p class="text-5xl text-weiss">Loading post...</p>
<div class="flex px-2 py-4 border-b-grau2 border-b">
<img src="../assets/default_pp.png" alt="" class="rounded-full w-16 h-16">
<div>
<div> <!-- POST HEADER -->
<label class="text-lg font-bold m-1 text-weiss">{{user.displayname}}</label>
<label class="text-base m-1 text-grau2">@{{ user.username }} | </label>
<label class="text-base text-grau2"> Posted at {{ post.created_at }}</label>
</div>
<div class="m-2"> <!-- POST CONTENT -->
<p class="text-sm m-1 text-weiss">{{ post.post_text }}</p>
</div>
<div class="flex"> <!-- POST FOOTER -->
<div class="flex"> <!-- Comments -->
<img src="../assets/icons/comment.png" alt="" class="rounded-full align-middle">
<label class="text-sm m-1 text-weiss" v-if="post.comments != undefined">{{ post.comments }}</label>
<label class="text-sm m-1 text-weiss" v-else>Comments disabled</label>
</div>
<div class="flex items-center" @click="addLike(post.post_uuid)"> <!-- Likes -->
<img alt="" src="../assets/icons/herz.png" class="align-middle">
<label class="text-sm m-1 text-weiss">{{ post.likes }}</label>
</div>
</div>
</div>
</div>
<div> <!-- COMMENTS VIEW and WRITE -->
<div>
<h2 class="align-middle p-6 text-xl text-weiss border-b-grau2 border-b">Comments</h2>
</div>
<div> <!-- WRITE COMMENTS -->
</div>
<div> <!-- VIEW COMMENTS -->
<div> <!-- VIEW COMMENTS -->
<div v-if="comments && comments.length > 0">
<div v-for="c in comments" :key="c.comment_uuid" class="p-4 border-b border-gray-700">
<p class="text-sm text-weiss">{{ c.author?.displayname || 'Unknown' }}: {{ c.comment_text }}</p>
</div>
</div>
<div v-else class="p-4 text-gray-400">No comments yet.</div>
</div>
</div>
</div>
</div>
<div class="w-1/4">
@@ -49,4 +169,5 @@ onMounted(async () => {
</template>
<style scoped>
</style>
</style>

View File

@@ -1,6 +1,6 @@
// File: `src/router/index.ts`
import { createRouter, createWebHistory } from "vue-router";
import Home from "../components/Home.vue";
import Home from "../../src/components/Home.vue";
import Login from "../components/Login.vue";
import wip from "../components/wip.vue";
import settings from "../components/settings.vue";