Clean up links page, footer
This commit is contained in:
@@ -17,24 +17,6 @@ type LayoutProps = {
|
|||||||
|
|
||||||
export default function RootLayout({ children, protectedPage }: LayoutProps) {
|
export default function RootLayout({ children, protectedPage }: LayoutProps) {
|
||||||
const {status} = useSession()
|
const {status} = useSession()
|
||||||
const snowflakeElements = []
|
|
||||||
|
|
||||||
for (let i = 0; i < 50; i++) {
|
|
||||||
snowflakeElements.push(
|
|
||||||
<div
|
|
||||||
className="snowflake text-white"
|
|
||||||
style={
|
|
||||||
{
|
|
||||||
left: `${Math.random() * 100}%`,
|
|
||||||
animationDuration: `${Math.random() *5 + 5}s`,
|
|
||||||
fontSize: `${Math.random() * 1.5 + 0.5}em`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
❅
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (protectedPage) {
|
if (protectedPage) {
|
||||||
if (status === "loading") {
|
if (status === "loading") {
|
||||||
@@ -54,7 +36,6 @@ export default function RootLayout({ children, protectedPage }: LayoutProps) {
|
|||||||
return (
|
return (
|
||||||
<main className="min-h-screen bg-black">
|
<main className="min-h-screen bg-black">
|
||||||
<Head />
|
<Head />
|
||||||
{snowflakeElements}
|
|
||||||
<Header />
|
<Header />
|
||||||
{children}
|
{children}
|
||||||
<Footer />
|
<Footer />
|
||||||
@@ -65,7 +46,6 @@ export default function RootLayout({ children, protectedPage }: LayoutProps) {
|
|||||||
return (
|
return (
|
||||||
<main className="min-h-screen bg-black">
|
<main className="min-h-screen bg-black">
|
||||||
<Head />
|
<Head />
|
||||||
{snowflakeElements}
|
|
||||||
<Header />
|
<Header />
|
||||||
{children}
|
{children}
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|||||||
@@ -10,13 +10,15 @@ type SocialCardProps = {
|
|||||||
|
|
||||||
export default function SocialMediaCard(props: SocialCardProps) {
|
export default function SocialMediaCard(props: SocialCardProps) {
|
||||||
return (
|
return (
|
||||||
<div className="bg-gray-500 rounded-lg text-center max-w-sm p-4 mx-auto">
|
<div>
|
||||||
<Link href={props.url}>
|
|
||||||
{props.name}
|
|
||||||
</Link>
|
|
||||||
{
|
{
|
||||||
props.showDelete && <Trash onClick={props.deleteCallback} color="plain" className="pl-2 hover:cursor-pointer" />
|
props.showDelete && <Trash onClick={props.deleteCallback} color="white" className="pl-2 hover:cursor-pointer" />
|
||||||
}
|
}
|
||||||
|
<Link href={props.url} target="_blank">
|
||||||
|
<div className="bg-white py-5 w-full text-left">
|
||||||
|
<h2 className="px-4 text-lg font-bold">{props.name}</h2>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,29 +1,18 @@
|
|||||||
import { Twitter, LinkedinOption } from "grommet-icons"
|
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
export default function Footer() {
|
export default function Footer() {
|
||||||
|
const date = new Date()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="absolute bottom-0 left-0 w-full bg-gray-900 p-2 text-white">
|
<div className="absolute bottom-0 left-0 w-full bg-zinc-900 p-2 text-white">
|
||||||
<p className="text-center">
|
<p className="text-center">
|
||||||
<Link href="mailto:alex@alexavfrantz.com" className="hover:text-gray-500 hover:underline hover:cursor-pointer">
|
<Link href="mailto:alex@alexavfrantz.com" className="hover:text-gray-500 hover:underline hover:cursor-pointer">
|
||||||
alex@alexavfrantz.com
|
alex@alexavfrantz.com
|
||||||
</Link>
|
</Link>
|
||||||
</p>
|
</p>
|
||||||
<p className="text-center">
|
<p className="text-center">
|
||||||
All music, game, TV and movie covers are owned by their respective authors.<br/>Currently playing info provided by Last.fm
|
© Alex Frantz, {date.getFullYear()}
|
||||||
</p>
|
|
||||||
<p className="text-center">
|
|
||||||
© Alex Frantz, 2023
|
|
||||||
</p>
|
|
||||||
<p className="text-center space-x-2">
|
|
||||||
<Link href="https://twitter.com/avvex__" target="_blank" rel="noreferrer">
|
|
||||||
<Twitter color='plain' size="30" />
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link href="https://linkedin.com/in/thatalex" target="_blank" rel="noreferrer">
|
|
||||||
<LinkedinOption size="30" />
|
|
||||||
</Link>
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ export default function Header() {
|
|||||||
<p className="text-2xl font-bold">alex</p>
|
<p className="text-2xl font-bold">alex</p>
|
||||||
<div className="inline-block pb-2">
|
<div className="inline-block pb-2">
|
||||||
<HeaderItem content="home" linkTo="/" />
|
<HeaderItem content="home" linkTo="/" />
|
||||||
<HeaderItem content="reviews" linkTo="/reviews" />
|
|
||||||
<HeaderItem content="links" linkTo="/links" />
|
<HeaderItem content="links" linkTo="/links" />
|
||||||
<HeaderItem content="blog" linkTo="/blog" />
|
<HeaderItem content="blog" linkTo="/blog" />
|
||||||
{ status === "authenticated" &&
|
{ status === "authenticated" &&
|
||||||
|
|||||||
@@ -77,25 +77,6 @@ export default function CreatePage() {
|
|||||||
return (
|
return (
|
||||||
<RootLayout protectedPage={true}>
|
<RootLayout protectedPage={true}>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="w-96 p-2 mx-auto bg-gray-500 text-center">
|
|
||||||
<h1 className="font-bold text-2xl">Create Review Post</h1>
|
|
||||||
|
|
||||||
<div className="pt-2 pb-2">
|
|
||||||
<hr />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<form onSubmit={onPostSubmit}>
|
|
||||||
<InputOption inputName="title" label="Title" />
|
|
||||||
<InputOption inputName="image" label="Image URL" />
|
|
||||||
<InputOption inputName="type" label="Content Type (book, movie, tv, game)" />
|
|
||||||
<InputOption inputName="review" label="Review" isTextArea={true} />
|
|
||||||
|
|
||||||
<button className="bg-gray-800 text-white rounded-lg p-2" type="submit">Submit</button>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<p>{message}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="w-96 p-2 mx-auto bg-gray-500 text-center">
|
<div className="w-96 p-2 mx-auto bg-gray-500 text-center">
|
||||||
<h1 className="font-bold text-2xl">Create Link</h1>
|
<h1 className="font-bold text-2xl">Create Link</h1>
|
||||||
|
|
||||||
|
|||||||
+45
-18
@@ -1,37 +1,64 @@
|
|||||||
import SocialCard from '@/components/SocialCard'
|
import SocialCard from '@/components/SocialCard'
|
||||||
import RootLayout from '@/components/RootLayout';
|
|
||||||
import { api } from "@/utils/api";
|
import { api } from "@/utils/api";
|
||||||
import { useSession } from 'next-auth/react';
|
import { useSession } from 'next-auth/react';
|
||||||
import React from 'react';
|
import { useRouter } from 'next/router';
|
||||||
|
import Image from 'next/image';
|
||||||
|
import Link from 'next/link';
|
||||||
|
import React, {useState, useEffect} from 'react';
|
||||||
|
|
||||||
export default function Links() {
|
export default function Links() {
|
||||||
|
const router = useRouter();
|
||||||
const {status} = useSession();
|
const {status} = useSession();
|
||||||
|
const [links, setLinks] = useState<React.JSX.Element[] | null>(null);
|
||||||
|
|
||||||
// trpc hooks
|
// trpc hooks
|
||||||
const { data: linkData } = api.links.getAll.useQuery()
|
const { data: linkData } = api.links.getAll.useQuery()
|
||||||
const deleteMutation = api.links.delete.useMutation()
|
const deleteMutation = api.links.delete.useMutation()
|
||||||
|
|
||||||
return (
|
useEffect(() => {
|
||||||
<RootLayout>
|
if (!links && linkData) {
|
||||||
<div className="space-y-2">
|
const allLinks = [];
|
||||||
{
|
|
||||||
linkData && linkData.length > 0 ? linkData.map((v) => {
|
for (const link of linkData) {
|
||||||
return <SocialCard
|
allLinks.push(
|
||||||
url={v.url}
|
<SocialCard
|
||||||
name={v.name}
|
name={link.name}
|
||||||
key={v.name}
|
key={link.id}
|
||||||
showDelete={status === "authenticated"}
|
url={link.url}
|
||||||
|
showDelete={status == "authenticated"}
|
||||||
deleteCallback={() => {
|
deleteCallback={() => {
|
||||||
deleteMutation.mutate(v.id)
|
deleteMutation.mutate(link.id);
|
||||||
|
router.reload()
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
}) :
|
)
|
||||||
<div className="text-center text-white">
|
}
|
||||||
<h1>Uh oh!</h1>
|
|
||||||
<p>There's nothing here :(</p>
|
setLinks(allLinks)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<main className="bg-black flex flex-col justify-center items-center min-h-screen">
|
||||||
|
<Link href="/">
|
||||||
|
<h1 className="text-white text-sm underline hover:text-gray-500 pb-2"><- Back Home</h1>
|
||||||
|
</Link>
|
||||||
|
<div className="bg-zinc-900 p-10 rounded-sm">
|
||||||
|
<div className="pb-2 flex flex-col justify-center items-center">
|
||||||
|
<Image className="rounded-lg" width="90" height="90" alt="Profile Picture" src="https://storage.thatalex.dev/content/pfp.png" />
|
||||||
|
<div className="text-white text-center pt-2">
|
||||||
|
<h1>Alex</h1>
|
||||||
|
<p>I'm Alex, a QA Engineer by day and developer by night</p>
|
||||||
|
<hr className="h-px my-2 bg-gray-200 border-0 dark:bg-gray-700" />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-2">
|
||||||
|
{
|
||||||
|
links && links.length > 0 ? links : <h1 className="text-center text-white font-bold">Uh oh, there are no links here!</h1>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</RootLayout>
|
</div>
|
||||||
|
</main>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
import RootLayout from '@/components/RootLayout';
|
|
||||||
|
|
||||||
// next modules
|
|
||||||
import Router, {useRouter} from 'next/router';
|
|
||||||
import Link from 'next/link';
|
|
||||||
import {useSession} from 'next-auth/react';
|
|
||||||
import Image from 'next/image';
|
|
||||||
|
|
||||||
// api
|
|
||||||
import {api} from '@/utils/api'
|
|
||||||
|
|
||||||
// icons
|
|
||||||
import { Trash } from 'grommet-icons';
|
|
||||||
|
|
||||||
export default function ReviewPage() {
|
|
||||||
const router = useRouter()
|
|
||||||
const name = router.query.name as string
|
|
||||||
const { status } = useSession()
|
|
||||||
|
|
||||||
// trpc stuff
|
|
||||||
const {data: bookData} = api.post.getOne.useQuery(name)
|
|
||||||
const deletionMutation = api.post.delete.useMutation()
|
|
||||||
|
|
||||||
function deleteItem() {
|
|
||||||
if (bookData) {
|
|
||||||
deletionMutation.mutate(bookData.id)
|
|
||||||
Router.replace("/").catch(() => {
|
|
||||||
console.error("Failed to reroute user!")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bookData) {
|
|
||||||
return (
|
|
||||||
<RootLayout>
|
|
||||||
<div className="mx-auto w-1/2 text-center flex justify-center">
|
|
||||||
<Image src={bookData.image} width="150" height="150" alt={`${bookData.name} ${bookData.type} cover`} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mx-auto w-1/2 text-center text-white">
|
|
||||||
<h1 className="text-2xl font-bold">{bookData.name} { status == "authenticated" ? <Trash onClick={deleteItem} className="hover:cursor-pointer" /> : ""}</h1>
|
|
||||||
|
|
||||||
<div className="pt-2 pb-2">
|
|
||||||
<hr />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{bookData.reviewContents}
|
|
||||||
</div>
|
|
||||||
</RootLayout>
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<RootLayout>
|
|
||||||
<div className="text-center text-2xl font-bold">
|
|
||||||
<p>Well, that's not good..</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="text-center">
|
|
||||||
<p>You've reached a page that doesn't exist. Lets fix that.</p>
|
|
||||||
<Link href="/" className="hover:underline hover:cursor-pointer hover:text-gray-500">
|
|
||||||
Head Home
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</RootLayout>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
import RootLayout from "@/components/RootLayout"
|
|
||||||
import ReviewCard from "@/components/ReviewCard"
|
|
||||||
import React, {useState, useEffect} from 'react';
|
|
||||||
import { api } from "@/utils/api";
|
|
||||||
|
|
||||||
type GenericItemType = {
|
|
||||||
name: string,
|
|
||||||
image: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Reviews() {
|
|
||||||
const {data: itemData} = api.post.getAll.useQuery()
|
|
||||||
const [list, setList] = useState<null | JSX.Element[]>(null)
|
|
||||||
const [type, setType] = useState("Book")
|
|
||||||
|
|
||||||
function onCatClick() {
|
|
||||||
// probably gonna rework this eventually if needed
|
|
||||||
switch(type) {
|
|
||||||
case 'Book':
|
|
||||||
setType("Movie")
|
|
||||||
break;
|
|
||||||
case 'Movie':
|
|
||||||
setType("TV")
|
|
||||||
break;
|
|
||||||
case 'TV':
|
|
||||||
setType("Game")
|
|
||||||
break;
|
|
||||||
case 'Game':
|
|
||||||
setType("Book")
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sanitizeTitleForLink(title: string) {
|
|
||||||
return title.replaceAll(" ", "-").toLowerCase()
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (itemData) {
|
|
||||||
const filteredArray = itemData.filter(v => v.type == type.toLowerCase())
|
|
||||||
|
|
||||||
if (filteredArray.length <= 0) {
|
|
||||||
setList(null)
|
|
||||||
} else {
|
|
||||||
setList(
|
|
||||||
filteredArray.map((v: GenericItemType, k) => {
|
|
||||||
return <ReviewCard
|
|
||||||
key={k}
|
|
||||||
title={v.name}
|
|
||||||
url={`/reviews/${sanitizeTitleForLink(v.name)}`}
|
|
||||||
image={v.image}
|
|
||||||
showText={false}
|
|
||||||
/>
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [itemData, type])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RootLayout>
|
|
||||||
<div className="w-1/2 mx-auto text-white">
|
|
||||||
<p className="text-center font-bold text-2xl hover:cursor-pointer hover:underline pb-2 select-none" onClick={onCatClick}>
|
|
||||||
{type}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div className="flex flex-wrap justify-center">
|
|
||||||
{
|
|
||||||
list ? list
|
|
||||||
: <div className="text-center">
|
|
||||||
<h1>Nothing here!</h1>
|
|
||||||
<p>Try again later :(</p>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</RootLayout>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user