This repository has been archived on 2025-10-20. You can view files and clone it, but cannot push or open issues or pull requests.
Files
esp-projekt/src/components/search_components/search_main.vue

221 lines
8.3 KiB
Vue

<script setup lang="ts">
import {ref, onMounted} from "vue";
import router from "../../router";
const allItems = ref<any[]>([]);
const feed = ref<any[]>([]);
const feed2 = ref<any[]>([]);
interface search_filter {
u: boolean;
p: boolean;
}
const search_filter_status = ref<search_filter>({
u: true,
p: true,
});
let searched = false;
const usr_search = ref<string | undefined>(undefined);
async function get_posts_user() {
try {
const post_response = await fetch('http://localhost:8000/api/posts');
const postsDATA = await post_response.json();
const user_response = await fetch('http://localhost:8000/api/users');
const usersDATA = await user_response.json();
usersDATA.forEach(user => {
allItems.value.push({...user, id: user.user_id, type: 'user'});
});
postsDATA.forEach(post => {
const author = usersDATA.find(user => user.user_id === post.user_id);
const postWithAuthorInfo = {
...post,
type: 'post',
username: author ? author.username : 'unknown',
displayname: author ? author.displayname : 'unknown',
};
allItems.value.push(postWithAuthorInfo);
});
feed.value = [...allItems.value];
feed2.value = [...allItems.value];
//console.log("Data Loaded:", allItems.value);
} catch (error) {
console.error("Error:", error);
}
}
onMounted(async () => {
get_posts_user();
});
function go_fs(){
searched = true;
feed.value = [];
feed2.value = [];
const combinedFilteredItems = allItems.value
.filter(item => (search_filter_status.value.u == true && item.type === "user") ||
(search_filter_status.value.p == true && item.type === "post"))
.map(item => {
if (item.type === 'post') {
const user = allItems.value.find(u => u.id === item.user_id && u.type === 'user');
return {
...item,
username: user ? user.username : 'unknown',
displayname: user ? user.displayname : 'unknown',
};
}
return item;
});
feed2.value = combinedFilteredItems;
const searchTerm = usr_search.value ? usr_search.value.toLowerCase() : '';
if (!searchTerm) {
feed.value = [...feed2.value];
return;
}
feed.value = feed2.value.filter(item => {
switch (item.type) {
case "user":
return (item.displayname && item.displayname.toLowerCase().includes(searchTerm)) || (item.username && item.username.toLowerCase().includes(searchTerm));
case "post":
return (item.post_text && item.post_text.toLowerCase().includes(searchTerm)) || (item.username && item.username.toLowerCase().includes(searchTerm) || item.displayname && item.displayname.toLowerCase().includes(searchTerm));
default:
return false;
}
});
}
async function addLike(post_id: string | number, user_id: number, index: number) {
try {
feed.value[index].likes++;
const response = await fetch(`http://localhost:8000/api/post/${post_id}/like`, {
method: 'POST',
headers: {'content-type': 'application/json'},
body: `{"userId":${user_id}}`,
});
if (!response.ok) {
const errorText = await response.text();
console.error('Server-Fehlertext:', errorText);
throw new Error(`HTTP error! status: ${response.status}, text: ${errorText}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error('Fehler beim Liken des Posts:', error);
throw error;
}
}
function gotoPost(post_id: string ) {
localStorage.setItem("viewedpost", post_id);
router.push(`/post/${post_id}`);
console.log("goto post: " + post_id);
}
function copyLink(post_id: string | number) {
const tocopy = `http://localhost:5173/post/${post_id}`;
navigator.clipboard.writeText(tocopy);
alert("Copied to clipboard");
}
function gotoProfile(user_id: string | number) {
router.push(`/profile/${user_id}`);
}
</script>
<template>
<div>
<div class="flex justify-center">
<div class="w-1/2">
<form @submit.prevent="go_fs" class="flex flex-col">
<input type="text" placeholder="Search..." class="w-full m-2 mt-6 p-4 bg-grau-dunkel focus:outline-none rounded-xl placeholder:text-center text-center" v-model="usr_search">
<div class="flex justify-center text-grau2">
<label class="m-2 accent-button-farbe"><input type="checkbox" class="mr-1" v-model="search_filter_status.u">User</label>
<label class="m-2 accent-button-farbe"><input type="checkbox" class="mr-1" v-model="search_filter_status.p">Post</label>
</div>
<button class="text-schwarz pl-1 mx-1 px-1 rounded-lg bg-button-farbe w-1/2 place-self-center">Filter /Search </button>
</form>
</div>
</div>
<div>
<div>
<a class="text-2xl flex justify-center mt-4 pt-2 p-3 border-b-grau2 border-b">Result(s):</a>
</div>
<div v-if="feed.length > 0 && searched == true" class="sm:overflow-y-auto sm:h-[650px] sm:scrollbar">
<div v-for="(bing, i) in feed" :key="bing.id">
<div v-if="bing.type === 'user'" class="pt-2 p-3 border-b-grau2 border-b">
<div class="flex">
<img v-if="bing.user_id != '99' " src="../../assets/default_pp.png" alt="" class="rounded-full w-16 h-16">
<img v-else src="../../assets/danielvici_pp.png" alt="" class="rounded-full w-16 h-16">
<div class="">
<a class="text-lg m-1">{{ bing.displayname }}</a>
<a class="text-base m-1 text-grau2">@{{ bing.username }}</a>
<div>
<a class=" text-sm m-3 text-weiss" v-if="bing.bio">{{ bing.bio }}</a>
<a class=" text-sm m-3 text-grau2 italic" v-else>User has no bio.</a>
</div>
<button @click="gotoProfile(bing.user_id)" class="text-schwarz pl-1 mx-1 px-1 rounded-lg bg-button-farbe"> Go to Profile</button>
</div>
</div>
</div>
<div v-else-if="bing.type === 'post'" class="flex p-3 border-b-grau2 border-b "> <!-- POSTS -->
<img v-if="bing.user_id != '99' " src="../../assets/default_pp.png" alt="" class="rounded-full w-16 h-16">
<img v-else src="../../assets/danielvici_pp.png" alt="" class="rounded-full w-16 h-16">
<div>
<div>
<label class="text-lg m-1 text-weiss">{{ bing.displayname }}</label>
<label class="text-base m-1 text-grau2">@{{ bing.username }}</label>
</div>
<div class="m-2">
<p class="text-sm m-1 text-weiss">{{ bing.post_text }}</p>
</div>
<div class="sm:flex pt-2">
<div class="flex">
<div class="flex">
<img src="../../assets/icons/comment.png" alt="" class="rounded-full align-middle">
<label class="text-sm m-1 text-weiss" v-if="bing.comments != undefined">{{ bing.comments }}</label>
<label class="text-sm m-1 text-weiss" v-else>Comments disabled</label>
</div>
<div class="flex items-center" @click="addLike(bing.posts_uuid, bing.user_id, i)">
<img alt="" src="../../assets/icons/herz.png" class="align-middle">
<label class="text-sm m-1 text-weiss">{{ bing.likes }}</label>
</div>
</div>
<br class="sm:hidden">
<div class="flex sm:tems-center mx-2"> <!-- View Post -->
<button @click="gotoPost(bing.posts_uuid)" class="text-schwarz mx-1 px-1 rounded-lg bg-button-farbe">View Post</button>
<button @click="copyLink(bing.posts_uuid)" class="text-schwarz pl-1 mx-1 px-1 rounded-lg bg-button-farbe">Share Post</button>
<button @click="gotoProfile(bing.user_id)" class="text-schwarz pl-1 mx-1 px-1 rounded-lg bg-button-farbe"> Go to Profile</button>
</div><!-- ENDE -->
</div>
</div>
</div>
</div>
</div>
<div v-else-if="searched == false" class="flex justify-center">
<a class="text-2xl text-logo-farbe-rot p-10 text-center">To see results you have to search</a>
</div>
<div v-else class="flex justify-center">
<a class="text-xl text-logo-farbe-rot p-10 text-center">No Results Found</a>
</div>
</div>
</div>
</template>
<style scoped>
</style>