Skip to content

Commit

Permalink
Fetch single post and more
Browse files Browse the repository at this point in the history
  • Loading branch information
MdSamsuzzohaShayon committed Nov 10, 2023
1 parent 921cf7f commit ae8e53f
Show file tree
Hide file tree
Showing 46 changed files with 3,086 additions and 74 deletions.
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@
- Blog on http://blog.webdevlab.org
- Create short tutorial
- Create developer team (career opportunity)
- Create most advanced User Authentication system (Cookie based)
- Create most advanced User Authentication system (Cookie based, refresh token)
- Forum on http://forum.webdevlab.org
- User role (Admin, Student, Viewer)
-
- Do nuxt js seo for all pages

### Requirements
- Quill text editor
- Use time function [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl)
- Design layout for admin
- Main menu for home

### Database Modeling (PostgresSQL)
- Articles Table:
Expand Down
3 changes: 3 additions & 0 deletions client/assets/css/tailwind.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
225 changes: 225 additions & 0 deletions client/components/admin/Admin.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
<!-- https://www.tailwindawesome.com/resources/tailwind-admin-template/demo -->
<template>
<!-- <div class="container mx-auto px-4">
<p>Article</p>
<p>Category</p>
<p>Authors</p>
<p>Comments</p>
<p>Tags</p>
<p>Settings</p>
</div> -->

<aside class="relative bg-gray-900 h-screen w-64 hidden sm:block shadow-xl">
<div class="p-6">
<a href="index.html" class="text-white text-3xl font-semibold uppercase hover:text-gray-300">Admin</a>
<button
class="w-full bg-white cta-btn font-semibold py-2 mt-5 rounded-br-lg rounded-bl-lg rounded-tr-lg shadow-lg hover:shadow-xl hover:bg-gray-300 flex items-center justify-center"
>
<i class="fas fa-plus mr-3"></i> New Report
</button>
</div>
<nav class="text-white text-base font-semibold pt-3">
<a href="index.html" class="flex items-center active-nav-link text-white py-4 pl-6 nav-item">
<i class="fas fa-tachometer-alt mr-3"></i>
Dashboard
</a>
<a href="blank.html" class="flex items-center text-white opacity-75 hover:opacity-100 py-4 pl-6 nav-item">
<i class="fas fa-sticky-note mr-3"></i>
Blank Page
</a>
<a href="tables.html" class="flex items-center text-white opacity-75 hover:opacity-100 py-4 pl-6 nav-item">
<i class="fas fa-table mr-3"></i>
Tables
</a>
<a href="forms.html" class="flex items-center text-white opacity-75 hover:opacity-100 py-4 pl-6 nav-item">
<i class="fas fa-align-left mr-3"></i>
Forms
</a>
<a href="tabs.html" class="flex items-center text-white opacity-75 hover:opacity-100 py-4 pl-6 nav-item">
<i class="fas fa-tablet-alt mr-3"></i>
Tabbed Content
</a>
<a href="calendar.html" class="flex items-center text-white opacity-75 hover:opacity-100 py-4 pl-6 nav-item">
<i class="fas fa-calendar mr-3"></i>
Calendar
</a>
</nav>
<a href="#" class="absolute w-full upgrade-btn bottom-0 active-nav-link text-white flex items-center justify-center py-4">
<i class="fas fa-arrow-circle-up mr-3"></i>
Upgrade to Pro!
</a>
</aside>

<div class="w-full flex flex-col h-screen overflow-y-hidden">
<!-- Desktop Header -->
<header class="w-full items-center bg-white py-2 px-6 hidden sm:flex">
<div class="w-1/2"></div>
<div x-data="{ isOpen: false }" class="relative w-1/2 flex justify-end">
<button
@click="isOpen = !isOpen"
class="realtive z-10 w-12 h-12 rounded-full overflow-hidden border-4 border-gray-400 hover:border-gray-300 focus:border-gray-300 focus:outline-none"
>
<img src="https://source.unsplash.com/uJ8LNVCBjFQ/400x400" />
</button>
<button x-show="isOpen" @click="isOpen = false" class="h-full w-full fixed inset-0 cursor-default"></button>
<div x-show="isOpen" class="absolute w-32 bg-white rounded-lg shadow-lg py-2 mt-16">
<a href="#" class="block px-4 py-2 account-link hover:text-white">Account</a>
<a href="#" class="block px-4 py-2 account-link hover:text-white">Support</a>
<a href="#" class="block px-4 py-2 account-link hover:text-white">Sign Out</a>
</div>
</div>
</header>

<!-- Mobile Header & Nav -->
<header x-data="{ isOpen: false }" class="w-full bg-gray-900 py-5 px-6 sm:hidden">
<div class="flex items-center justify-between">
<a href="index.html" class="text-white text-3xl font-semibold uppercase hover:text-gray-300">Admin</a>
<button @click="isOpen = !isOpen" class="text-white text-3xl focus:outline-none">
<i x-show="!isOpen" class="fas fa-bars"></i>
<i x-show="isOpen" class="fas fa-times"></i>
</button>
</div>

<!-- Dropdown Nav -->
<nav :class="isOpen ? 'flex' : 'hidden'" class="flex flex-col pt-4">
<a href="index.html" class="flex items-center active-nav-link text-white py-2 pl-4 nav-item">
<i class="fas fa-tachometer-alt mr-3"></i>
Dashboard
</a>
<a href="blank.html" class="flex items-center text-white opacity-75 hover:opacity-100 py-2 pl-4 nav-item">
<i class="fas fa-sticky-note mr-3"></i>
Blank Page
</a>
<a href="tables.html" class="flex items-center text-white opacity-75 hover:opacity-100 py-2 pl-4 nav-item">
<i class="fas fa-table mr-3"></i>
Tables
</a>
<a href="forms.html" class="flex items-center text-white opacity-75 hover:opacity-100 py-2 pl-4 nav-item">
<i class="fas fa-align-left mr-3"></i>
Forms
</a>
<a href="tabs.html" class="flex items-center text-white opacity-75 hover:opacity-100 py-2 pl-4 nav-item">
<i class="fas fa-tablet-alt mr-3"></i>
Tabbed Content
</a>
<a href="calendar.html" class="flex items-center text-white opacity-75 hover:opacity-100 py-2 pl-4 nav-item">
<i class="fas fa-calendar mr-3"></i>
Calendar
</a>
<a href="#" class="flex items-center text-white opacity-75 hover:opacity-100 py-2 pl-4 nav-item">
<i class="fas fa-cogs mr-3"></i>
Support
</a>
<a href="#" class="flex items-center text-white opacity-75 hover:opacity-100 py-2 pl-4 nav-item">
<i class="fas fa-user mr-3"></i>
My Account
</a>
<a href="#" class="flex items-center text-white opacity-75 hover:opacity-100 py-2 pl-4 nav-item">
<i class="fas fa-sign-out-alt mr-3"></i>
Sign Out
</a>
<button class="w-full bg-white cta-btn font-semibold py-2 mt-3 rounded-lg shadow-lg hover:shadow-xl hover:bg-gray-300 flex items-center justify-center">
<i class="fas fa-arrow-circle-up mr-3"></i> Upgrade to Pro!
</button>
</nav>
<!-- <button class="w-full bg-white cta-btn font-semibold py-2 mt-5 rounded-br-lg rounded-bl-lg rounded-tr-lg shadow-lg hover:shadow-xl hover:bg-gray-300 flex items-center justify-center">
<i class="fas fa-plus mr-3"></i> New Report
</button> -->
</header>

<div class="w-full overflow-x-hidden border-t flex flex-col">
<main class="w-full flex-grow p-6">
<h1 class="text-3xl text-black pb-6">Dashboard</h1>

<div class="flex flex-wrap mt-6">
<div class="w-full lg:w-1/2 pr-0 lg:pr-2">
<p class="text-xl pb-3 flex items-center"><i class="fas fa-plus mr-3"></i> Monthly Reports</p>
<div class="p-6 bg-white">
<canvas id="chartOne" width="400" height="200"></canvas>
</div>
</div>
<div class="w-full lg:w-1/2 pl-0 lg:pl-2 mt-12 lg:mt-0">
<p class="text-xl pb-3 flex items-center"><i class="fas fa-check mr-3"></i> Resolved Reports</p>
<div class="p-6 bg-white">
<canvas id="chartTwo" width="400" height="200"></canvas>
</div>
</div>
</div>

<div class="w-full mt-12">
<p class="text-xl pb-3 flex items-center"><i class="fas fa-list mr-3"></i> Latest Reports</p>
<div class="bg-white overflow-auto">
<table class="min-w-full bg-white">
<thead class="bg-gray-800 text-white">
<tr>
<th class="w-1/3 text-left py-3 px-4 uppercase font-semibold text-sm">Name</th>
<th class="w-1/3 text-left py-3 px-4 uppercase font-semibold text-sm">Last name</th>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm">Phone</th>
<th class="text-left py-3 px-4 uppercase font-semibold text-sm">Email</th>
</tr>
</thead>
<tbody class="text-gray-700">
<tr>
<td class="w-1/3 text-left py-3 px-4">Lian</td>
<td class="w-1/3 text-left py-3 px-4">Smith</td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="tel:622322662">622322662</a></td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="mailto:[email protected]">[email protected]</a></td>
</tr>
<tr class="bg-gray-200">
<td class="w-1/3 text-left py-3 px-4">Emma</td>
<td class="w-1/3 text-left py-3 px-4">Johnson</td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="tel:622322662">622322662</a></td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="mailto:[email protected]">[email protected]</a></td>
</tr>
<tr>
<td class="w-1/3 text-left py-3 px-4">Oliver</td>
<td class="w-1/3 text-left py-3 px-4">Williams</td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="tel:622322662">622322662</a></td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="mailto:[email protected]">[email protected]</a></td>
</tr>
<tr class="bg-gray-200">
<td class="w-1/3 text-left py-3 px-4">Isabella</td>
<td class="w-1/3 text-left py-3 px-4">Brown</td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="tel:622322662">622322662</a></td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="mailto:[email protected]">[email protected]</a></td>
</tr>
<tr>
<td class="w-1/3 text-left py-3 px-4">Lian</td>
<td class="w-1/3 text-left py-3 px-4">Smith</td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="tel:622322662">622322662</a></td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="mailto:[email protected]">[email protected]</a></td>
</tr>
<tr class="bg-gray-200">
<td class="w-1/3 text-left py-3 px-4">Emma</td>
<td class="w-1/3 text-left py-3 px-4">Johnson</td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="tel:622322662">622322662</a></td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="mailto:[email protected]">[email protected]</a></td>
</tr>
<tr>
<td class="w-1/3 text-left py-3 px-4">Oliver</td>
<td class="w-1/3 text-left py-3 px-4">Williams</td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="tel:622322662">622322662</a></td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="mailto:[email protected]">[email protected]</a></td>
</tr>
<tr class="bg-gray-200">
<td class="w-1/3 text-left py-3 px-4">Isabella</td>
<td class="w-1/3 text-left py-3 px-4">Brown</td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="tel:622322662">622322662</a></td>
<td class="text-left py-3 px-4"><a class="hover:text-blue-500" href="mailto:[email protected]">[email protected]</a></td>
</tr>
</tbody>
</table>
</div>
</div>
</main>

<footer class="w-full bg-white text-right p-4">Built by <a target="_blank" href="https://davidgrzyb.com" class="underline">David Grzyb</a>.</footer>
</div>
</div>
</template>

<script setup lang="ts">
const state = reactive({ isOpen: false });
const { isOpen } = state;
</script>
37 changes: 37 additions & 0 deletions client/components/article/Article.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<!-- <NuxtLink to="/posts/postid">
<div
v-bind:class="{`max-w-sm mx-auto group hover:no-underline focus:no-underline dark:bg-gray-900 ${props.first ? 'block gap-3 sm:max-w-full lg:grid lg:grid-cols-12' : ''}`}"
>
<img
role="presentation"
src="https://source.unsplash.com/random/480x360"
alt=""
class="object-cover w-full h-64 rounded sm:h-96 lg:col-span-7 dark:bg-gray-500"
/>
<div class="p-6 space-y-2 lg:col-span-5">
<h3 class="text-2xl font-semibold sm:text-4xl group-hover:underline group-focus:underline">Noster tincidunt reprimique ad pro</h3>
<span class="text-xs dark:text-gray-400">February 19, 2021</span>
<p>Ei delenit sensibus liberavisse pri. Quod suscipit no nam. Est in graece fuisset, eos affert putent doctus id.</p>
</div>
</div>
</NuxtLink> -->
<NuxtLink rel="noopener noreferrer" v-bind:to="'http://localhost:3000/' + article.link" class="max-w-sm mx-auto group hover:no-underline focus:no-underline dark:bg-gray-900">
<img class="object-cover w-full rounded h-44 dark:bg-gray-500" src="https://source.unsplash.com/random/480x360?1" />
<div class="p-6 space-y-2">
<h3 class="text-2xl font-semibold group-hover:underline group-focus:underline">{{ article.title }}</h3>
<span class="text-xs dark:text-gray-400">{{ article.createdAt }}</span>
<p>
{{ article.content }}
</p>
</div>
</NuxtLink>
</template>

<script setup lang="ts">
// import { IArticleProps } from "../../types";
const props = defineProps(["first", "article"]);
// console.log(props.article);
// {FRONTEND_URL} +
</script>
61 changes: 61 additions & 0 deletions client/components/article/ArticleExpand.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<template>
<main className="continer mx-auto px-4">
<div class="relative w-full h-80">
<div class="static h-full">
<img
src="https://images.unsplash.com/photo-1493770348161-369560ae357d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2100&q=80"
alt="thumbnail"
class="w-full h-full object-cover object-center"
/>
</div>
<div class="absolute bottom-2 left-2">
<h1 className="text-4xl font-semibold text-gray-100 leading-tight">
{{ data.articleByLink.title }}
</h1>
<img class="img-wrapper w-12 h-12 rounded-full border-4 border-gray-200" src="https://randomuser.me/api/portraits/men/97.jpg" alt="author" />
<p className="font-semibold text-gray-200 text-sm">{{ data.articleByLink.author.name }}</p>
<p className="font-semibold text-gray-400 text-xs">{{ data.articleByLink.createdAt }}</p>
</div>
</div>
<p className="mt-10">
Breakfast agreeable incommode departure it an. By ignorant at on wondered relation. Enough at tastes really so cousin am of. Extensive therefore supported
by extremity of contented. Is pursuit compact demesne invited elderly be. View him she roof tell her case has sigh. Moreover is possible he admitted
sociable concerns. By in cold no less been sent hard hill.
</p>
<p>{{ data.articleByLink.content }}</p>
</main>
</template>

<script lang="ts" setup>
import type { IArticle } from "../../types/Article";
const props = defineProps(["postLink"]);
const query = gql`
query ArticleByLink($link: String) {
articleByLink(link: $link) {
content
createdAt
id
link
title
author {
name
id
}
category {
id
name
}
}
}
`;
type ArticlesResult = {
articleByLink: IArticle;
};
const variables = { link: props.postLink };
const { data } = await useAsyncQuery<ArticlesResult>(query, variables);
console.log(data);
</script>
Loading

0 comments on commit ae8e53f

Please sign in to comment.