mirror of
				https://github.com/r-freeman/portfolio.git
				synced 2025-11-03 23:31:11 +00:00 
			
		
		
		
	Added new page
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				Build And Publish / BuildAndPublish (push) Successful in 2m39s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	Build And Publish / BuildAndPublish (push) Successful in 2m39s
				
			This commit is contained in:
		
							parent
							
								
									5e8da79a82
								
							
						
					
					
						commit
						6c0100e9a3
					
				@ -4,7 +4,7 @@ import React from 'react';
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const metadata = {
 | 
					export const metadata = {
 | 
				
			||||||
    title: 'Reading - Ryan Freeman',
 | 
					    title: 'Reading - Ryan Freeman',
 | 
				
			||||||
    description: 'I have many leather-bound books, take a look at my book recommendations.'
 | 
					    description: 'Take a look at my curated reading list.'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Book = {
 | 
					type Book = {
 | 
				
			||||||
@ -69,7 +69,7 @@ export default async function Reading() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <SimpleLayout
 | 
					        <SimpleLayout
 | 
				
			||||||
            heading="What's on my bookshelf"
 | 
					            heading="Books I'm reading at the moment"
 | 
				
			||||||
            description={metadata.description}
 | 
					            description={metadata.description}
 | 
				
			||||||
            gradient="bg-gradient-to-r from-sky-400 to-blue-500">
 | 
					            gradient="bg-gradient-to-r from-sky-400 to-blue-500">
 | 
				
			||||||
            <ul
 | 
					            <ul
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										95
									
								
								app/services/page.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								app/services/page.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,95 @@
 | 
				
			|||||||
 | 
					import {SimpleLayout} from '@/components/layouts/SimpleLayout'
 | 
				
			||||||
 | 
					import {Card} from '@/components/ui/Card'
 | 
				
			||||||
 | 
					import React, {ElementType} from 'react'
 | 
				
			||||||
 | 
					import {CloudIcon} from '@/components/icons/CloudIcon'
 | 
				
			||||||
 | 
					import {DatabaseIcon} from '@/components/icons/DatabaseIcon'
 | 
				
			||||||
 | 
					import {AppIcon} from '@/components/icons/AppIcon'
 | 
				
			||||||
 | 
					import {CodeIcon} from '@/components/icons/CodeIcon'
 | 
				
			||||||
 | 
					import {ShieldIcon} from '@/components/icons/ShieldIcon'
 | 
				
			||||||
 | 
					import {EmailIcon} from '@/components/icons/EmailIcon'
 | 
				
			||||||
 | 
					import {RocketIcon} from '@/components/icons/RocketIcon'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const metadata = {
 | 
				
			||||||
 | 
					    title: 'Services - Ryan Freeman',
 | 
				
			||||||
 | 
					    description: 'Whether you need a WordPress website, React app, AWS support or odd coding jobs, I\'m here to help. As an experienced software engineer, I produce high-quality software that will deliver immediate value for you and your customers.'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Services = {
 | 
				
			||||||
 | 
					    title: string
 | 
				
			||||||
 | 
					    description: string
 | 
				
			||||||
 | 
					    icon: ElementType
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const iconStyles = `
 | 
				
			||||||
 | 
					    w-6
 | 
				
			||||||
 | 
					    h-6
 | 
				
			||||||
 | 
					    mr-2
 | 
				
			||||||
 | 
					    z-10
 | 
				
			||||||
 | 
					    transition
 | 
				
			||||||
 | 
					    stroke-zinc-500
 | 
				
			||||||
 | 
					    dark:stroke-zinc-400
 | 
				
			||||||
 | 
					    group-hover:dark:stroke-indigo-500
 | 
				
			||||||
 | 
					    group-hover:stroke-indigo-500
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default async function Services() {
 | 
				
			||||||
 | 
					    const services: Services[] = [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            title: 'AWS',
 | 
				
			||||||
 | 
					            description: 'As an AWS Certified Cloud Practitioner I can advise on and implement reliable, cost-effective cloud solutions for your business.',
 | 
				
			||||||
 | 
					            icon: () => <CloudIcon className={iconStyles}/>
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            title: 'Databases',
 | 
				
			||||||
 | 
					            description: 'Not all database technologies are the same, I\'ll help you choose the right database for your use case.',
 | 
				
			||||||
 | 
					            icon: () => <DatabaseIcon className={iconStyles}/>
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            title: 'WordPress',
 | 
				
			||||||
 | 
					            description: 'WordPress is the de-facto software for building SEO-friendly websites, together we can achieve top rankings in Google search results.',
 | 
				
			||||||
 | 
					            icon: () => <AppIcon className={iconStyles}/>
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            title: 'Frontend',
 | 
				
			||||||
 | 
					            description: 'Using React, I can deliver modern, responsive websites and applications that seamlessly adapt to any screen size.',
 | 
				
			||||||
 | 
					            icon: () => <CodeIcon className={iconStyles}/>
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            title: 'Backend',
 | 
				
			||||||
 | 
					            description: 'From building APIs to authentication and integrating third-party services, I develop robust backend systems for your business needs.',
 | 
				
			||||||
 | 
					            icon: () => <RocketIcon className={iconStyles}/>
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            title: 'Domain and hosting',
 | 
				
			||||||
 | 
					            description: 'Whether you’re launching a new website or migrating an existing one, I\'ll ensure your website is fast, secure and always online.',
 | 
				
			||||||
 | 
					            icon: () => <ShieldIcon className={iconStyles}/>
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            title: 'Email',
 | 
				
			||||||
 | 
					            description: 'I\'ll help you establish trust with your clients by using a custom domain for your email that reflects your brand.',
 | 
				
			||||||
 | 
					            icon: () => <EmailIcon className={iconStyles}/>
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <SimpleLayout
 | 
				
			||||||
 | 
					            heading="I offer a wide range of digital services to elevate and transform your business"
 | 
				
			||||||
 | 
					            description={metadata.description}
 | 
				
			||||||
 | 
					            gradient="bg-gradient-to-r from-pink-300 via-purple-300 to-indigo-400">
 | 
				
			||||||
 | 
					            <ul
 | 
				
			||||||
 | 
					                role="list"
 | 
				
			||||||
 | 
					                className="grid grid-cols-1 gap-x-12 gap-y-16 sm:grid-cols-2 lg:grid-cols-3"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					                {services.map(({title, description, icon: Icon}) => (
 | 
				
			||||||
 | 
					                    <Card as="li" key={title}>
 | 
				
			||||||
 | 
					                        <h2 className="flex items-center text-base font-semibold group-hover:text-indigo-500 text-zinc-800 dark:text-zinc-100">
 | 
				
			||||||
 | 
					                            <Icon/>
 | 
				
			||||||
 | 
					                            <Card.Link href="mailto:hello@ryanfreeman.dev" ariaLabel={title}>{title}</Card.Link>
 | 
				
			||||||
 | 
					                        </h2>
 | 
				
			||||||
 | 
					                        <Card.Description>{description}</Card.Description>
 | 
				
			||||||
 | 
					                    </Card>
 | 
				
			||||||
 | 
					                ))}
 | 
				
			||||||
 | 
					            </ul>
 | 
				
			||||||
 | 
					        </SimpleLayout>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -5,6 +5,7 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
 | 
				
			|||||||
    const urls = [
 | 
					    const urls = [
 | 
				
			||||||
        'https://ryanfreeman.dev/',
 | 
					        'https://ryanfreeman.dev/',
 | 
				
			||||||
        'https://ryanfreeman.dev/about',
 | 
					        'https://ryanfreeman.dev/about',
 | 
				
			||||||
 | 
					        'https://ryanfreeman.dev/services',
 | 
				
			||||||
        'https://ryanfreeman.dev/reading',
 | 
					        'https://ryanfreeman.dev/reading',
 | 
				
			||||||
        'https://ryanfreeman.dev/writing',
 | 
					        'https://ryanfreeman.dev/writing',
 | 
				
			||||||
        'https://ryanfreeman.dev/projects',
 | 
					        'https://ryanfreeman.dev/projects',
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
import React from 'react'
 | 
					import React from 'react'
 | 
				
			||||||
import {OuterContainer, InnerContainer} from './Container'
 | 
					import {InnerContainer, OuterContainer} from './Container'
 | 
				
			||||||
import {NavLink} from '@/components/ui/Navigation'
 | 
					import {NavLink} from '@/components/ui/Navigation'
 | 
				
			||||||
import {SpotifyPlayer} from '@/components/ui/SpotifyPlayer'
 | 
					import {SpotifyPlayer} from '@/components/ui/SpotifyPlayer'
 | 
				
			||||||
import {SocialLink} from '@/components/ui/SocialLink'
 | 
					import {SocialLink} from '@/components/ui/SocialLink'
 | 
				
			||||||
@ -12,12 +12,15 @@ export function Footer() {
 | 
				
			|||||||
            <OuterContainer>
 | 
					            <OuterContainer>
 | 
				
			||||||
                <div className="border-t border-zinc-100 pt-10 pb-16 dark:border-zinc-700/40">
 | 
					                <div className="border-t border-zinc-100 pt-10 pb-16 dark:border-zinc-700/40">
 | 
				
			||||||
                    <InnerContainer>
 | 
					                    <InnerContainer>
 | 
				
			||||||
 | 
					                        {process.env.NODE_ENV !== 'development' &&
 | 
				
			||||||
                            <SpotifyPlayer/>
 | 
					                            <SpotifyPlayer/>
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                        <div className="flex flex-col items-center justify-between gap-6 mt-12">
 | 
					                        <div className="flex flex-col items-center justify-between gap-6 mt-12">
 | 
				
			||||||
                            <div
 | 
					                            <div
 | 
				
			||||||
                                className="flex flex-wrap justify-center gap-6 text-sm font-medium text-zinc-800 dark:text-zinc-200">
 | 
					                                className="flex flex-wrap justify-center gap-6 text-sm font-medium text-zinc-800 dark:text-zinc-200">
 | 
				
			||||||
                                <NavLink href="/">Home</NavLink>
 | 
					                                <NavLink href="/">Home</NavLink>
 | 
				
			||||||
                                <NavLink href="/about">About</NavLink>
 | 
					                                <NavLink href="/about">About</NavLink>
 | 
				
			||||||
 | 
					                                <NavLink href="/services">Services</NavLink>
 | 
				
			||||||
                                <NavLink href="/reading">Reading</NavLink>
 | 
					                                <NavLink href="/reading">Reading</NavLink>
 | 
				
			||||||
                                <NavLink href="/writing">Writing</NavLink>
 | 
					                                <NavLink href="/writing">Writing</NavLink>
 | 
				
			||||||
                                <NavLink href="/projects">Projects</NavLink>
 | 
					                                <NavLink href="/projects">Projects</NavLink>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								components/icons/AppIcon.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								components/icons/AppIcon.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					import {Props} from '@/types'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function AppIcon(props: Props) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor"
 | 
				
			||||||
 | 
					             {...props}>
 | 
				
			||||||
 | 
					            <path strokeLinecap="round" strokeLinejoin="round"
 | 
				
			||||||
 | 
					                  d="m21 7.5-9-5.25L3 7.5m18 0-9 5.25m9-5.25v9l-9 5.25M3 7.5l9 5.25M3 7.5v9l9 5.25m0-9v9"/>
 | 
				
			||||||
 | 
					        </svg>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								components/icons/CloudIcon.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								components/icons/CloudIcon.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					import {Props} from '@/types'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function CloudIcon(props: Props) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor"
 | 
				
			||||||
 | 
					             {...props}>
 | 
				
			||||||
 | 
					            <path stroke-linecap="round" stroke-linejoin="round"
 | 
				
			||||||
 | 
					                  d="M2.25 15a4.5 4.5 0 0 0 4.5 4.5H18a3.75 3.75 0 0 0 1.332-7.257 3 3 0 0 0-3.758-3.848 5.25 5.25 0 0 0-10.233 2.33A4.502 4.502 0 0 0 2.25 15Z"/>
 | 
				
			||||||
 | 
					        </svg>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								components/icons/CodeIcon.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								components/icons/CodeIcon.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					import {Props} from '@/types'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function CodeIcon(props: Props) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor"
 | 
				
			||||||
 | 
					             {...props}>
 | 
				
			||||||
 | 
					            <path strokeLinecap="round" strokeLinejoin="round"
 | 
				
			||||||
 | 
					                  d="M17.25 6.75 22.5 12l-5.25 5.25m-10.5 0L1.5 12l5.25-5.25m7.5-3-4.5 16.5"/>
 | 
				
			||||||
 | 
					        </svg>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								components/icons/DatabaseIcon.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								components/icons/DatabaseIcon.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					import {Props} from '@/types'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function DatabaseIcon(props: Props) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor"
 | 
				
			||||||
 | 
					             {...props}>
 | 
				
			||||||
 | 
					            <path strokeLinecap="round" strokeLinejoin="round"
 | 
				
			||||||
 | 
					                  d="M20.25 6.375c0 2.278-3.694 4.125-8.25 4.125S3.75 8.653 3.75 6.375m16.5 0c0-2.278-3.694-4.125-8.25-4.125S3.75 4.097 3.75 6.375m16.5 0v11.25c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125V6.375m16.5 0v3.75m-16.5-3.75v3.75m16.5 0v3.75C20.25 16.153 16.556 18 12 18s-8.25-1.847-8.25-4.125v-3.75m16.5 0c0 2.278-3.694 4.125-8.25 4.125s-8.25-1.847-8.25-4.125"/>
 | 
				
			||||||
 | 
					        </svg>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								components/icons/EmailIcon.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								components/icons/EmailIcon.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					import {Props} from '@/types'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function EmailIcon(props: Props) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor"
 | 
				
			||||||
 | 
					             {...props}>
 | 
				
			||||||
 | 
					            <path strokeLinecap="round" strokeLinejoin="round"
 | 
				
			||||||
 | 
					                  d="M21.75 6.75v10.5a2.25 2.25 0 0 1-2.25 2.25h-15a2.25 2.25 0 0 1-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0 0 19.5 4.5h-15a2.25 2.25 0 0 0-2.25 2.25m19.5 0v.243a2.25 2.25 0 0 1-1.07 1.916l-7.5 4.615a2.25 2.25 0 0 1-2.36 0L3.32 8.91a2.25 2.25 0 0 1-1.07-1.916V6.75"/>
 | 
				
			||||||
 | 
					        </svg>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								components/icons/RocketIcon.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								components/icons/RocketIcon.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					import {Props} from '@/types'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function RocketIcon(props: Props) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor"
 | 
				
			||||||
 | 
					             {...props}>
 | 
				
			||||||
 | 
					            <path strokeLinecap="round" strokeLinejoin="round"
 | 
				
			||||||
 | 
					                  d="M15.59 14.37a6 6 0 0 1-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 0 0 6.16-12.12A14.98 14.98 0 0 0 9.631 8.41m5.96 5.96a14.926 14.926 0 0 1-5.841 2.58m-.119-8.54a6 6 0 0 0-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 0 0-2.58 5.84m2.699 2.7c-.103.021-.207.041-.311.06a15.09 15.09 0 0 1-2.448-2.448 14.9 14.9 0 0 1 .06-.312m-2.24 2.39a4.493 4.493 0 0 0-1.757 4.306 4.493 4.493 0 0 0 4.306-1.758M16.5 9a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Z"/>
 | 
				
			||||||
 | 
					        </svg>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								components/icons/ShieldIcon.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								components/icons/ShieldIcon.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					import {Props} from '@/types'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function ShieldIcon(props: Props) {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth="1.5" stroke="currentColor"
 | 
				
			||||||
 | 
					             {...props}>
 | 
				
			||||||
 | 
					            <path strokeLinecap="round" strokeLinejoin="round"
 | 
				
			||||||
 | 
					                  d="M9 12.75 11.25 15 15 9.75m-3-7.036A11.959 11.959 0 0 1 3.598 6 11.99 11.99 0 0 0 3 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285Z"/>
 | 
				
			||||||
 | 
					        </svg>
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -65,6 +65,7 @@ export function MobileNavigation(props: Props) {
 | 
				
			|||||||
                            <ul className="-my-2 divide-y divide-zinc-100 text-base text-zinc-800 dark:divide-zinc-100/5 dark:text-zinc-300">
 | 
					                            <ul className="-my-2 divide-y divide-zinc-100 text-base text-zinc-800 dark:divide-zinc-100/5 dark:text-zinc-300">
 | 
				
			||||||
                                <MobileNavItem href="/">Home</MobileNavItem>
 | 
					                                <MobileNavItem href="/">Home</MobileNavItem>
 | 
				
			||||||
                                <MobileNavItem href="/about">About</MobileNavItem>
 | 
					                                <MobileNavItem href="/about">About</MobileNavItem>
 | 
				
			||||||
 | 
					                                <MobileNavItem href="/services">Services</MobileNavItem>
 | 
				
			||||||
                                <MobileNavItem href="/reading">Reading</MobileNavItem>
 | 
					                                <MobileNavItem href="/reading">Reading</MobileNavItem>
 | 
				
			||||||
                                <MobileNavItem href="/writing">Writing</MobileNavItem>
 | 
					                                <MobileNavItem href="/writing">Writing</MobileNavItem>
 | 
				
			||||||
                                <MobileNavItem href="/projects">Projects</MobileNavItem>
 | 
					                                <MobileNavItem href="/projects">Projects</MobileNavItem>
 | 
				
			||||||
@ -109,6 +110,7 @@ export function DesktopNavigation(props: Props) {
 | 
				
			|||||||
            <ul className="flex rounded-full bg-white/90 px-3 text-sm font-medium text-zinc-800 shadow-lg shadow-zinc-800/5 ring-1 ring-zinc-900/5 backdrop-blur dark:bg-zinc-800/90 dark:text-zinc-200 dark:ring-white/10">
 | 
					            <ul className="flex rounded-full bg-white/90 px-3 text-sm font-medium text-zinc-800 shadow-lg shadow-zinc-800/5 ring-1 ring-zinc-900/5 backdrop-blur dark:bg-zinc-800/90 dark:text-zinc-200 dark:ring-white/10">
 | 
				
			||||||
                <NavItem href="/">Home</NavItem>
 | 
					                <NavItem href="/">Home</NavItem>
 | 
				
			||||||
                <NavItem href="/about">About</NavItem>
 | 
					                <NavItem href="/about">About</NavItem>
 | 
				
			||||||
 | 
					                <NavItem href="/services">Services</NavItem>
 | 
				
			||||||
                <NavItem href="/reading">Reading</NavItem>
 | 
					                <NavItem href="/reading">Reading</NavItem>
 | 
				
			||||||
                <NavItem href="/writing">Writing</NavItem>
 | 
					                <NavItem href="/writing">Writing</NavItem>
 | 
				
			||||||
                <NavItem href="/projects">Projects</NavItem>
 | 
					                <NavItem href="/projects">Projects</NavItem>
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
export function createSlug(title: string) {
 | 
					export function createSlug(title: string) {
 | 
				
			||||||
    return title.toLowerCase()
 | 
					    return title.toLowerCase()
 | 
				
			||||||
        .replace(/['?]+/g, '')
 | 
					        .replace(/['?:]+/g, '')
 | 
				
			||||||
        .replace(/[.,\s]+/g, '-')
 | 
					        .replace(/[.,\s]+/g, '-')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user