feat: support nav and pages in cms

This commit is contained in:
Cory Dransfeldt 2024-07-14 19:21:04 -07:00
parent e1b0dc5243
commit f5adf0ba06
No known key found for this signature in database
35 changed files with 235 additions and 444 deletions

View file

@ -37,7 +37,7 @@ const fetchAlbumReleases = async () => {
timestamp: DateTime.fromISO(album['release_date']).toSeconds(),
type: 'album-release'
}
)).sort((a, b) => a.timestamp - b.timestamp)
)).sort((a, b) => a['timestamp'] - b['timestamp'])
}
export default async function () {

View file

@ -14,5 +14,5 @@ export default async function () {
},
}).catch()
const pages = await res
return pages.results.filter((p) => p.page.includes('posts'))
return pages['results'].filter((p) => p['page'].includes('posts'))
}

View file

@ -37,7 +37,7 @@ async function fetchAllBooks() {
}
for (const book of data) {
book.tags = await fetchTagsForBook(book.id)
book.tags = await fetchTagsForBook(book['id'])
}
books = books.concat(data)

View file

@ -30,9 +30,9 @@ const fetchGenresWithArtists = async () => {
}
data.forEach(genre => {
genre.artists = genre.artists.map(artist => ({
genre['artists'] = genre['artists'].map(artist => ({
...artist,
country: parseCountryField(artist.country)
country: parseCountryField(artist['country'])
}))
})

View file

@ -40,8 +40,8 @@ const fetchAllLinks = async () => {
if (data.length < PAGE_SIZE) fetchMore = false
for (const link of data) {
link.tags = await fetchTagsForLink(link.id)
link.type = 'link'
link['tags'] = await fetchTagsForLink(link.id)
link['type'] = 'link'
}
links = links.concat(data)

View file

@ -1,30 +1,50 @@
export default async function () {
return {
menu: [
{ name: 'Posts', url: '/posts', icon: 'article'},
{ name: 'Music', url: '/music', icon: 'headphones' },
{ name: 'Watching', url: '/watching', icon: 'device-tv' },
{ name: 'Books', url: '/books', icon: 'books' },
{ name: 'Links', icon: 'link' },
{ name: 'About', url: '/about', icon: 'info-circle' },
{ name: 'Search', icon: 'search' },
{ name: 'Feeds', icon: 'rss' },
{ name: 'Mastodon', icon: 'brand-mastodon' },
],
footer: [
{ name: 'Uses' },
{ name: 'Colophon' },
{ name: 'Blogroll' },
{ name: 'Save' },
],
social: [
{ name: 'Email', url: '/contact', icon: 'at' },
{ name: 'GitHub', url: 'https://github.com/cdransf', icon: 'brand-github' },
{ name: 'npm', url: 'https://www.npmjs.com/~cdransf', icon: 'brand-npm'},
{ name: 'Mastodon', url: 'https://social.lol/@cory', icon: 'brand-mastodon' },
{ name: 'Coffee', url: 'https://buymeacoffee.com/cory', icon: 'coffee' },
{ name: 'Now', url: '/now', icon: 'clock-hour-3' },
{ name: 'Webrings', url: '/webrings', icon: 'heart-handshake' },
],
import { createClient } from '@supabase/supabase-js'
const SUPABASE_URL = process.env.SUPABASE_URL
const SUPABASE_KEY = process.env.SUPABASE_KEY
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY)
const fetchAllNavigation = async () => {
const { data, error } = await supabase
.from('navigation')
.select(`
*,
pages(title, permalink)
`)
if (error) {
console.error('Error fetching navigation data:', error)
return null
}
const menu = {}
data.forEach(item => {
const menuItem = item.pages ? {
title: item.pages.title,
permalink: item.pages.permalink,
icon: item.icon,
position: item.position
} : {
title: item.title,
permalink: item.permalink,
icon: item.icon,
position: item.position
}
if (!menu[item.menu_location]) {
menu[item.menu_location] = [menuItem]
} else {
menu[item.menu_location].push(menuItem)
}
})
Object.keys(menu).forEach(location => {
menu[location].sort((a, b) => a.position - b.position)
})
return menu
}
export default async function () {
return await fetchAllNavigation()
}

82
src/_data/pages.js Normal file
View file

@ -0,0 +1,82 @@
import { createClient } from '@supabase/supabase-js'
const SUPABASE_URL = process.env.SUPABASE_URL
const SUPABASE_KEY = process.env.SUPABASE_KEY
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY)
const PAGE_SIZE = 50
const fetchBlockData = async (collection, itemId) => {
const { data, error } = await supabase
.from(collection)
.select(collection === 'hero' ? '*, image(filename_disk)' : '*')
.eq('id', itemId)
.single()
if (error) {
console.error(`Error fetching data from ${collection} for item ${itemId}:`, error)
return null
}
return data
}
const fetchBlocksForPage = async (pageId) => {
const { data, error } = await supabase
.from('pages_blocks')
.select('collection, item')
.eq('pages_id', pageId)
if (error) {
console.error(`Error fetching blocks for page ${pageId}:`, error)
return []
}
const blocks = await Promise.all(data.map(async block => {
const blockData = await fetchBlockData(block.collection, block.item)
return {
type: block['collection'],
...blockData
}
}))
return blocks
}
const fetchAllPages = async () => {
let pages = []
let page = 0
let fetchMore = true
while (fetchMore) {
const { data, error } = await supabase
.from('pages')
.select(`
*,
open_graph_image(filename_disk)
`)
.range(page * PAGE_SIZE, (page + 1) * PAGE_SIZE - 1)
if (error) {
console.error('Error fetching pages:', error)
return pages
}
if (data.length < PAGE_SIZE) fetchMore = false
for (const page of data) {
page['blocks'] = await fetchBlocksForPage(page['id'])
if (page['open_graph_image']) page['open_graph_image'] = page['open_graph_image']['filename_disk']
pages.push(page)
}
page++
}
return pages
}
export default async function () {
return await fetchAllPages()
}

View file

@ -26,7 +26,7 @@ const fetchAllRobots = async () => {
if (data.length < PAGE_SIZE) break
}
return robots.map(robot => robot.user_agent)
return robots.map(robot => robot['user_agent'])
}
export default async function () {

View file

@ -8,5 +8,5 @@ export default async function () {
}).catch()
const status = await res
return status.response['statuses'][0]
return status['response']['statuses'][0]
}

View file

@ -47,20 +47,20 @@ const fetchAllShows = async () => {
const prepareShowData = (show) => {
return {
...show,
image: show.art?.filename_disk ? `/${show.art.filename_disk}` : '',
backdrop: show.backdrop?.filename_disk ? `/${show.backdrop.filename_disk}` : ''
image: show['art']?.['filename_disk'] ? `/${show['art']['filename_disk']}` : '',
backdrop: show['backdrop']?.['filename_disk'] ? `/${show['backdrop']['filename_disk']}` : ''
}
}
const prepareEpisodeData = (show) => {
return show.episodes.map(episode => ({
return show['episodes'].map(episode => ({
...episode,
show_title: show.title,
show_tmdb_id: show.tmdb_id,
collected: show.collected,
favorite: show.favorite,
image: show.image,
backdrop: show.backdrop
show_title: show['title'],
show_tmdb_id: show['tmdb_id'],
collected: show['collected'],
favorite: show['favorite'],
image: show['image'],
backdrop: show['backdrop']
}))
}
@ -76,15 +76,15 @@ export default async function () {
const showEpisodesMap = {}
episodes.forEach(episode => {
const showTitle = episode.show_title
const showTmdbId = episode.show_tmdb_id
const episodeNumber = episode.episode_number
const seasonNumber = episode.season_number
const lastWatchedAt = episode.last_watched_at
const collected = episode.collected
const favorite = episode.favorite
const image = episode.image
const backdrop = episode.backdrop
const showTitle = episode['show_title']
const showTmdbId = episode['show_tmdb_id']
const episodeNumber = episode['episode_number']
const seasonNumber = episode['season_number']
const lastWatchedAt = episode['last_watched_at']
const collected = episode['collected']
const favorite = episode['favorite']
const image = episode['image']
const backdrop = episode['backdrop']
if (!showEpisodesMap[showTmdbId]) {
showEpisodesMap[showTmdbId] = {
@ -115,16 +115,16 @@ export default async function () {
})
})
const sortedShows = Object.values(showEpisodesMap).sort((a, b) => new Date(b.episodes[0].lastWatchedAt) - new Date(a.episodes[0].lastWatchedAt))
const sortedShows = Object.values(showEpisodesMap).sort((a, b) => new Date(b.episodes[0]['lastWatchedAt']) - new Date(a.episodes[0]['lastWatchedAt']))
const episodeData = []
sortedShows.forEach(show => {
const startingEpisode = show.episodes[show.episodes.length - 1].episode
const startingSeason = show.episodes[show.episodes.length - 1].season
const endingEpisode = show.episodes[0].episode
const endingSeason = show.episodes[0].season
const startingEpisode = show['episodes'][show['episodes'].length - 1]['episode']
const startingSeason = show['episodes'][show['episodes'].length - 1]['season']
const endingEpisode = show['episodes'][0].episode
const endingSeason = show['episodes'][0].season
if (show.episodes.length > 1) {
if (show['episodes'].length > 1) {
episodeData.push({
name: show.title,
url: `/watching/shows/${show.tmdbId}`,
@ -141,11 +141,11 @@ export default async function () {
backdrop: show.backdrop
})
} else {
const singleEpisode = show.episodes[0]
singleEpisode.collected = show.collected
singleEpisode.favorite = show.favorite
singleEpisode.image = show.image
singleEpisode.backdrop = show.backdrop
const singleEpisode = show['episodes'][0]
singleEpisode.collected = show['collected']
singleEpisode.favorite = show['favorite']
singleEpisode.image = show['image']
singleEpisode.backdrop = show['backdrop']
episodeData.push(singleEpisode)
}
})
@ -153,12 +153,12 @@ export default async function () {
return episodeData
}
const favoriteShows = shows.filter(show => show.favorite)
const favoriteShows = shows.filter(show => show['favorite'])
return {
shows,
watchHistory: formatEpisodeData(episodes),
recentlyWatched: formatEpisodeData(episodes.slice(0, 225)),
favorites: formatEpisodeData(favoriteShows.flatMap(prepareEpisodeData)).sort((a, b) => a.name.localeCompare(b.name))
favorites: formatEpisodeData(favoriteShows.flatMap(prepareEpisodeData)).sort((a, b) => a['name'].localeCompare(b['name']))
}
}