Skip to content

Commit

Permalink
Move blog logic to a composable
Browse files Browse the repository at this point in the history
  • Loading branch information
DemogorGod committed Oct 5, 2023
1 parent 97ec5d3 commit cfab2ac
Show file tree
Hide file tree
Showing 6 changed files with 267 additions and 159 deletions.
11 changes: 10 additions & 1 deletion apps/landing/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
<script lang="ts" setup></script>
<script lang="ts" setup>
// Initalize blogs here for least amount of fetch calls
import useBlogs from '@/composables/blogs.ts'
const {
activeBlog,
allBlogs,
loadingBlogs,
} = useBlogs()
</script>

<template>
<div>
Expand Down
67 changes: 67 additions & 0 deletions apps/landing/src/composables/blogs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { onMounted, onUnmounted, readonly, ref } from 'vue'
import snarkdown from 'snarkdown'

const initializeComposable = ref(false)

type blog = {
title: string;
content: string;
timestamp: string;
type: string;
id: string;
};

const allBlogs = ref([] as blog[])
const loadingBlogs = ref(true)

export default function useBlogs() {
async function getContentOfBlog(itemId: string) {
const response = await fetch(`http://localhost:3003/api/hackmd/${itemId}`)
const json = await response.json()
const md = snarkdown(json.content)

return md
}

onMounted(async () => {
if (!initializeComposable.value) {
loadingBlogs.value = true
try {
const response = await fetch('http://localhost:3003/api/hackmd')
const jsonList = await response.json()
const blogList = []

for (let i = 0; i < jsonList.length; i++) {
const title = jsonList[i].title
const content = await getContentOfBlog(jsonList[i].id)
const timestamp = jsonList[i].publishedAt
const id = jsonList[i].id
blogList.push({
title: title,
content: content,
timestamp: timestamp,
type: 'Blog',
id: id,
})
}

allBlogs.value = blogList
loadingBlogs.value = false
} catch (error) {
console.error('Error trying to fetch:', error)
loadingBlogs.value = false
}

initializeComposable.value = true
}
})

onUnmounted(() => {
initializeComposable.value = false
})

return {
allBlogs: readonly(allBlogs),
loadingBlogs: readonly(loadingBlogs),
}
}
6 changes: 6 additions & 0 deletions apps/landing/src/composables/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { createWebHistory, createRouter } from 'vue-router'
import Landing from '@/pages/landing/Landing.vue'
import Changelog from '@/pages/changelog/Changelog.vue'
import Blog from '@/pages/blog/Blog.vue'
import SingleBlog from '@/pages/blog/components/SingleBlog.vue'
const routes = [
{
path: '/',
Expand All @@ -13,6 +14,11 @@ const routes = [
name: Blog,
component: Blog,
},
{
path: '/blog/:id',
component: SingleBlog,
children: [{ path: '', name: SingleBlog, component: SingleBlog }],
},
{
path: '/changelog',
name: Changelog,
Expand Down
222 changes: 67 additions & 155 deletions apps/landing/src/pages/blog/Blog.vue
Original file line number Diff line number Diff line change
@@ -1,56 +1,13 @@
<script setup>
import { onMounted, ref, computed, watch } from 'vue'
import snarkdown from 'snarkdown'
import VueFeather from 'vue-feather'
import useBlogs from '@/composables/blogs.ts'
const loading = ref(true)
const activeHTMLBlog = ref(null)
const htmlBlogList = ref([])
async function getContentOfBlog(itemId) {
const response = await fetch(`http://localhost:3003/api/hackmd/${itemId}`)
const json = await response.json()
const md = snarkdown(json.content)
return md
}
const activeHTMLBlogContent = ref('')
watch(activeHTMLBlog, async () => {
if (!activeHTMLBlog.value) return ''
const content = await getContentOfBlog(activeHTMLBlog.value)
activeHTMLBlogContent.value = content
})
onMounted(async () => {
try {
const response = await fetch('http://localhost:3003/api/hackmd')
const jsonList = await response.json()
let blogList = []
for (let i = 0; i < jsonList.length; i++) {
let title = jsonList[i].title
let id = jsonList[i].id
blogList.push(
{
title: title,
id: id
}
)
}
htmlBlogList.value = blogList
activeHTMLBlog.value = blogList[0].id
loading.value = false
} catch (error) {
console.error('Error trying to fetch:', error)
}
})
const {
activeBlog,
allBlogs,
loadingBlogs,
} = useBlogs()
</script>

Expand Down Expand Up @@ -86,33 +43,50 @@ onMounted(async () => {
</a>
</div>
</nav>
<section class="flex items-start justify-between max-w-[960px] mx-auto mt-[60px] h-[600px] relative overflow-auto">
<section class="max-w-[960px] mx-auto mt-[60px] min-h-[650px] relative overflow-auto">
<div
v-if="loading"
v-if="loadingBlogs"
class="absolute top-0 left-0 w-full h-full z-[2] rounded-[3px] overflow-hidden"
>
<div class="skeleton_box" />
</div>
<div class=" pr-10 w-[200px] h-full border-r sticky top-0 left-0">
<h3>
Anncouncements
</h3>
<div class="flex flex-col items-start content-start gap-5 mt-20">
<button
v-for="blog in htmlBlogList"
:key="blog"
class="text-9 cursor-pointer text-left w-full"
:class="blog.id === activeHTMLBlog ? 'bg-blue-100' : ' bg-none'"
@click="activeHTMLBlog = blog.id"
>
{{ blog.title }}
</button>
<router-link
v-for="blog in allBlogs"
:key="blog"
:to="`/blog/${blog.id}`"
class="blog_card flex flex-col"
>
<div class="flex items-center gap-10 text-6 text-gray-400">
<span>
{{ blog.type }} •
</span>
<span>
{{ new Date(blog.timestamp).toDateString() }}
</span>
</div>
</div>
<div
class="blog_content w-full h-full overflow-auto"
v-html="activeHTMLBlogContent"
/>

<div class="text-1">
{{ blog.title }}
</div>


<div class="h-full w-full overflow-hidden pt-5">
<div
class="overview_blog_content"
v-html="blog.content"
/>
</div>

<div class="h-[100px] flex items-end text-8 highlight ">
<div class="flex items-center">
Read More
<vue-feather
type="arrow-right"
class="h-[0.92rem]"
/>
</div>
</div>
</router-link>
</section>

<section class="footer">
Expand Down Expand Up @@ -151,94 +125,32 @@ onMounted(async () => {


<style lang="scss">
.blog_content {
height: 100%;
max-width: 960px;
margin: auto;
padding-left: 10px;
display: flex;
flex-direction: column;
justify-content: start;
align-items: start;
gap: 10px;
ul {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
gap: 10px;
padding: 0;
margin: 0;
margin-top: 20px;
margin-left: 20px;
}
h1 {
font-size: 2.488rem;
font-weight: 400;
letter-spacing: -1.2px;
line-height: 1.38;
color: hsl(210, 12%, 12.5%);
}
h2 {
font-size: 1.728rem;
font-weight: 400;
letter-spacing: -0.41px;
line-height: 1.38;
color: hsl(210, 12%, 12.5%);
}
h3 {
font-size: 1.44rem;
font-weight: 400;
letter-spacing: -0.21px;
line-height: 1.38;
color: hsl(210, 12%, 12.5%);
}
h4 {
font-size: 1.2rem;
font-weight: 400;
line-height: 1.38;
color: hsl(210, 12%, 12.5%);
}
h5 {
font-size: 1rem;
font-weight: 400;
line-height: 1.38;
color: hsl(210, 12%, 12.5%);
}
.blog_card {
background-color: rgb(242, 242, 245);
border: 1px solid hsl(236, 10.6%, 87.9%);
width: 100%;
height: 320px;
overflow: hidden;
cursor: pointer;
border-radius: 8px;
padding: 30px 30px 30px 30px;
}
h6 {
font-size: 0.92rem;
font-weight: 400;
line-height: 1.38;
color: hsl(210, 12%, 12.5%);
}
.blog_card:hover {
box-shadow: inset 0px 1px 0px rgba(0, 0, 0, 0.1),
inset 0px -1px 0px 1px rgba(0, 0, 0, 0.1);
}
p {
font-size: 1rem;
font-weight: 400;
letter-spacing: -0.04px;
line-height: 1.38;
max-width: 520px;
word-wrap: break-word;
}
.overview_blog_content {
span {
font-size: 1rem;
font-weight: 400;
h1,
ul,
il,
img {
display: none;
width: 0;
height: 0;
}
}
.blog_nav {
margin: 60px auto;
display: flex;
flex-direction: column;
justify-content: start;
align-items: start;
}
</style>
Loading

0 comments on commit cfab2ac

Please sign in to comment.