Skip to content

Commit b6de19d

Browse files
authored
add some files from main theme
1 parent a8a2757 commit b6de19d

20 files changed

+1001
-0
lines changed

src/layouts/BaseLayout.astro

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
import BaseHead from '../components/BaseHead.astro'
3+
import Navbar from '../components/Navbar.astro'
4+
import Footer from '../components/Footer.astro'
5+
import { SITE_TITLE, SITE_DESCRIPTION } from '../consts'
6+
7+
interface Props {
8+
title?: string
9+
description?: string
10+
}
11+
12+
const { title, description } = Astro.props
13+
14+
import '@fontsource-variable/inter'
15+
import '@fontsource-variable/jetbrains-mono'
16+
---
17+
18+
<!doctype html>
19+
<html lang="en">
20+
<head>
21+
<BaseHead
22+
title={title || SITE_TITLE}
23+
description={description || SITE_DESCRIPTION}
24+
/>
25+
</head>
26+
<body
27+
class="text-foreground bg-background font-light dark:text-foreground-dark dark:bg-background-dark transition-colors"
28+
>
29+
<Navbar title={SITE_TITLE} />
30+
<slot />
31+
<Footer />
32+
</body>
33+
</html>

src/layouts/BlogPostLayout.astro

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
import type { CollectionEntry } from 'astro:content'
3+
import FormattedDate from '../components/FormattedDate.astro'
4+
import type { MarkdownHeading, ImageMetadata } from 'astro'
5+
import TableOfContents from '../components/TableOfContents.astro'
6+
import dayjs from 'dayjs'
7+
import utc from 'dayjs/plugin/utc'
8+
9+
dayjs.extend(utc)
10+
11+
type Props = CollectionEntry<'blog'>['data'] & {
12+
headings: MarkdownHeading[]
13+
slug: string
14+
remarkPluginFrontmatter: Record<string, string>
15+
}
16+
17+
const {
18+
title,
19+
description,
20+
pubDate,
21+
updatedDate,
22+
coverImageCredit,
23+
headings,
24+
slug,
25+
remarkPluginFrontmatter,
26+
} = Astro.props
27+
28+
import BaseLayout from './BaseLayout.astro'
29+
import { Image } from 'astro:assets'
30+
import { Icon } from 'astro-icon/components'
31+
32+
const blogImages = import.meta.glob<{ default: ImageMetadata }>(
33+
'/src/assets/blogimages/**/*.{jpeg,jpg,png,gif}'
34+
)
35+
36+
const coverImagePath = `/src/assets/blogimages/${slug}/cover.jpg`
37+
38+
const lastModified = dayjs(remarkPluginFrontmatter.lastModified)
39+
.utc()
40+
.format('D MMM YYYY')
41+
---
42+
43+
<BaseLayout title={title} description={description}>
44+
<main>
45+
<article>
46+
<div
47+
class="app-container flex flex-col lg:flex-row-reverse justify-between gap-8 py-24 relative"
48+
>
49+
<div class="md:w-1/4 relative">
50+
<div class="sticky top-0 md:top-28 hidden lg:block">
51+
<TableOfContents headings={headings} />
52+
</div>
53+
</div>
54+
<div class="grow w-full md:max-w-[75ch]">
55+
<div>
56+
<h1 class="text-4xl sm:text-5xl leading-snug pt-12 font-bold">
57+
{title}
58+
</h1>
59+
<div class="text-lg flex items-center gap-4 flex-wrap py-8">
60+
<!-- Publish date -->
61+
<span>
62+
<Icon
63+
name="mdi:calendar-month-outline"
64+
class="inline-block text-primary dark:text-primary-dark"
65+
/>
66+
<FormattedDate date={pubDate} />
67+
</span>
68+
69+
<!-- Updated date -->
70+
{
71+
updatedDate && (
72+
<span>
73+
<Icon
74+
name="mdi:calendar-refresh-outline"
75+
class="inline-block text-primary dark:text-primary-dark"
76+
/>
77+
Last updated on <FormattedDate date={updatedDate} />
78+
</span>
79+
)
80+
}
81+
82+
<!-- Read time -->
83+
<span>
84+
<Icon
85+
name="mdi:clock-time-four-outline"
86+
class="inline-block text-primary dark:text-primary-dark"
87+
/>
88+
{remarkPluginFrontmatter.minutesRead}
89+
</span>
90+
</div>
91+
92+
{
93+
blogImages[coverImagePath] && (
94+
<>
95+
<Image
96+
src={blogImages[coverImagePath]()}
97+
alt={title}
98+
class="rounded-lg"
99+
/>
100+
{coverImageCredit && (
101+
<p class="mt-2 mb-8 opacity-80 italic text-sm">
102+
Image Credit: {coverImageCredit}
103+
</p>
104+
)}
105+
</>
106+
)
107+
}
108+
</div>
109+
<div
110+
class="prose prose-neutral prose-lg md:prose-xl dark:prose-invert prose-img:rounded-xl prose-figure:text-center prose-img:mx-auto"
111+
>
112+
<slot />
113+
</div>
114+
115+
<!-- Suggest edit -->
116+
<div class="flex justify-between mt-16 gap-4 flex-wrap italic">
117+
<a
118+
href={`https://github.com/yashjawale/yashjawale.github.io/edit/main/src/content/blog/${slug}.md`}
119+
target="_blank"
120+
rel="noopener noreferrer"
121+
class="hover:underline underline-offset-4 opacity-70 hover:opacity-100"
122+
><Icon name="mdi:pencil-outline" class="inline-block" />
123+
Suggest an edit
124+
</a>
125+
<p class="opacity-70">
126+
Last modified: {lastModified}
127+
</p>
128+
</div>
129+
</div>
130+
</div>
131+
</article>
132+
</main>
133+
</BaseLayout>
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
import { SITE_BASE } from '@/consts'
3+
import '../styles/global.css'
4+
5+
interface Props {
6+
title: string
7+
description: string
8+
image?: string
9+
}
10+
11+
const canonicalURL = new URL(Astro.url.pathname, Astro.site)
12+
13+
const { title, description, image = `${SITE_BASE}/saral-og.jpg` } = Astro.props
14+
---
15+
16+
<!-- Prevent search indexing for theme demo page --><!-- REMOVE FOR YOUR SITE -->
17+
<meta name="robots" content="noindex" />
18+
19+
<!-- Global Metadata -->
20+
<meta charset="utf-8" />
21+
<meta name="viewport" content="width=device-width,initial-scale=1" />
22+
<meta name="generator" content={Astro.generator} />
23+
24+
<!-- Favicons -->
25+
<link
26+
rel="icon"
27+
type="image/png"
28+
href={`${SITE_BASE}/favicon-96x96.png`}
29+
sizes="96x96"
30+
/>
31+
<link rel="icon" type="image/svg+xml" href={`${SITE_BASE}/favicon.svg`} />
32+
<link rel="shortcut icon" href={`${SITE_BASE}/favicon.ico`} />
33+
<link
34+
rel="apple-touch-icon"
35+
sizes="180x180"
36+
href={`${SITE_BASE}/apple-touch-icon.png`}
37+
/>
38+
<meta name="apple-mobile-web-app-title" content="Saral Theme" />
39+
<link rel="manifest" href={`${SITE_BASE}/site.webmanifest`} />
40+
41+
<!-- Canonical URL -->
42+
<link rel="canonical" href={canonicalURL} />
43+
44+
<!-- Primary Meta Tags -->
45+
<title>{title}</title>
46+
<meta name="title" content={title} />
47+
<meta name="description" content={description} />
48+
49+
<!-- Open Graph / Facebook -->
50+
<meta property="og:type" content="website" />
51+
<meta property="og:url" content={Astro.url} />
52+
<meta property="og:title" content={title} />
53+
<meta property="og:description" content={description} />
54+
<meta property="og:image" content={new URL(image, Astro.url)} />
55+
56+
<!-- Twitter -->
57+
<meta property="twitter:card" content="summary_large_image" />
58+
<meta property="twitter:url" content={Astro.url} />
59+
<meta property="twitter:title" content={title} />
60+
<meta property="twitter:description" content={description} />
61+
<meta property="twitter:image" content={new URL(image, Astro.url)} />
62+
63+
<!-- RSS Auto-discovery -->
64+
<link
65+
rel="alternate"
66+
type="application/rss+xml"
67+
title="Saral Theme RSS Feed"
68+
href={new URL('rss.xml', Astro.site)}
69+
/>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
import { SITE_BASE } from '@/consts'
3+
import FormattedDate from './FormattedDate.astro'
4+
import type { ImageMetadata } from 'astro'
5+
import { Image } from 'astro:assets'
6+
7+
const { post } = Astro.props
8+
9+
const blogImages = import.meta.glob<{ default: ImageMetadata }>(
10+
'/src/assets/blogimages/**/*.{jpeg,jpg,png,gif}'
11+
)
12+
13+
const coverImagePath = `/src/assets/blogimages/${post.slug}/cover.jpg`
14+
---
15+
16+
<a
17+
href={`${SITE_BASE}/blog/${post.slug}/`}
18+
class="flex flex-col gap-4 pb-8 h-full group transition-colors"
19+
>
20+
{
21+
blogImages[coverImagePath] && (
22+
<Image
23+
src={blogImages[coverImagePath]()}
24+
alt={post.data.title}
25+
class="object-cover rounded-xl aspect-video"
26+
/>
27+
)
28+
}
29+
<h4
30+
class="text-2xl font-semibold group-hover:text-primary dark:group-hover:text-primary-dark group-hover:underline transition-colors"
31+
>
32+
{post.data.title}
33+
</h4>
34+
<p class="line-clamp-3 opacity-80">
35+
{post.data.description}
36+
</p>
37+
<p class="uppercase text-sm mt-auto tracking-tight">
38+
<FormattedDate date={post.data.pubDate} />
39+
</p>
40+
</a>

src/layouts/components/Card.astro

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
const { title } = Astro.props
3+
const { class: className } = Astro.props
4+
---
5+
6+
<div class:list={['rounded-lg p-6 py-12 pt-16 md:p-14', className]}>
7+
<h2 class="font-title text-[42px] leading-tight pb-5 z-10">{title}</h2>
8+
<div class="flex flex-col gap-4">
9+
<slot />
10+
</div>
11+
</div>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
import { SocialLinks, WebsiteLinks } from '../consts'
3+
import LogoSVG from '../assets/logo.svg'
4+
import { Icon } from 'astro-icon/components'
5+
6+
const today = new Date()
7+
---
8+
9+
<footer>
10+
<div
11+
class="app-container grid md:grid-cols-3 gap-12 py-16 border-t-2 border-foreground/50 dark:border-foreground-dark/50"
12+
>
13+
<div>
14+
<a href="/" class="block w-fit" aria-label="Home">
15+
<LogoSVG height={36} width={36} />
16+
</a>
17+
</div>
18+
<div>
19+
<h3 class="font-semibold text-2xl">Links</h3>
20+
<div class="flex flex-wrap gap-4 mt-4">
21+
{
22+
WebsiteLinks.filter((link) => link.name !== 'Home').map((link) => (
23+
<a
24+
class="text-lg"
25+
href={link.url}
26+
target="_blank"
27+
rel="noopener noreferrer"
28+
>
29+
{link.name}
30+
</a>
31+
))
32+
}
33+
<a
34+
href="rss.xml"
35+
target="_blank"
36+
rel="noopener noreferrer"
37+
class="text-lg"
38+
aria-label="RSS Feed"
39+
>
40+
<Icon name="mdi:rss" class="w-6 h-6" />
41+
</a>
42+
</div>
43+
</div>
44+
<div>
45+
<h3 class="font-semibold text-2xl">Socials</h3>
46+
<div class="flex flex-wrap gap-4 mt-4">
47+
{
48+
SocialLinks.map((link) => (
49+
<a
50+
class="text-lg"
51+
href={link.url}
52+
target="_blank"
53+
rel="noopener noreferrer"
54+
>
55+
{link.name}
56+
</a>
57+
))
58+
}
59+
</div>
60+
</div>
61+
</div>
62+
<div class="app-container flex justify-between items-center pb-6 text-center">
63+
<p class="text-left md:text-center w-full">
64+
&copy; {today.getFullYear()} Source code available on <a
65+
class="underline"
66+
href="https://github.com/yashjawale/saral-theme-astro"
67+
target="_blank">GitHub</a
68+
>
69+
</p>
70+
</div>
71+
</footer>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
interface Props {
3+
date: Date
4+
}
5+
6+
const { date } = Astro.props
7+
import dayjs from 'dayjs'
8+
---
9+
10+
<time datetime={date.toISOString()}>
11+
{dayjs(date).format('D MMM YYYY')}
12+
</time>

0 commit comments

Comments
 (0)