Compare commits

..

2 commits

Author SHA1 Message Date
a73afacf6c
Major redesign and rewrite
All checks were successful
/ astro-check (push) Successful in 13s
/ checking (push) Successful in 12s
/ check-tag (push) Successful in 2s
/ build-site (push) Successful in 2m6s
/ create-release (push) Successful in 7s
2024-07-19 22:52:35 +02:00
0dca43eb19
Major redesign and rewrite 2024-07-19 22:52:15 +02:00
41 changed files with 3864 additions and 4890 deletions

5
.astro/settings.json Normal file
View file

@ -0,0 +1,5 @@
{
"_variables": {
"lastUpdateCheck": 1721418667135
}
}

199
.astro/types.d.ts vendored Normal file
View file

@ -0,0 +1,199 @@
declare module 'astro:content' {
interface Render {
'.mdx': Promise<{
Content: import('astro').MarkdownInstance<{}>['Content'];
headings: import('astro').MarkdownHeading[];
remarkPluginFrontmatter: Record<string, any>;
}>;
}
}
declare module 'astro:content' {
interface Render {
'.md': Promise<{
Content: import('astro').MarkdownInstance<{}>['Content'];
headings: import('astro').MarkdownHeading[];
remarkPluginFrontmatter: Record<string, any>;
}>;
}
}
declare module 'astro:content' {
type Flatten<T> = T extends { [K: string]: infer U } ? U : never;
export type CollectionKey = keyof AnyEntryMap;
export type CollectionEntry<C extends CollectionKey> = Flatten<AnyEntryMap[C]>;
export type ContentCollectionKey = keyof ContentEntryMap;
export type DataCollectionKey = keyof DataEntryMap;
type AllValuesOf<T> = T extends any ? T[keyof T] : never;
type ValidContentEntrySlug<C extends keyof ContentEntryMap> = AllValuesOf<
ContentEntryMap[C]
>['slug'];
export function getEntryBySlug<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
collection: C,
// Note that this has to accept a regular string too, for SSR
entrySlug: E
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getDataEntryById<C extends keyof DataEntryMap, E extends keyof DataEntryMap[C]>(
collection: C,
entryId: E
): Promise<CollectionEntry<C>>;
export function getCollection<C extends keyof AnyEntryMap, E extends CollectionEntry<C>>(
collection: C,
filter?: (entry: CollectionEntry<C>) => entry is E
): Promise<E[]>;
export function getCollection<C extends keyof AnyEntryMap>(
collection: C,
filter?: (entry: CollectionEntry<C>) => unknown
): Promise<CollectionEntry<C>[]>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(entry: {
collection: C;
slug: E;
}): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
>(entry: {
collection: C;
id: E;
}): E extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof ContentEntryMap,
E extends ValidContentEntrySlug<C> | (string & {}),
>(
collection: C,
slug: E
): E extends ValidContentEntrySlug<C>
? Promise<CollectionEntry<C>>
: Promise<CollectionEntry<C> | undefined>;
export function getEntry<
C extends keyof DataEntryMap,
E extends keyof DataEntryMap[C] | (string & {}),
>(
collection: C,
id: E
): E extends keyof DataEntryMap[C]
? Promise<DataEntryMap[C][E]>
: Promise<CollectionEntry<C> | undefined>;
/** Resolve an array of entry references from the same collection */
export function getEntries<C extends keyof ContentEntryMap>(
entries: {
collection: C;
slug: ValidContentEntrySlug<C>;
}[]
): Promise<CollectionEntry<C>[]>;
export function getEntries<C extends keyof DataEntryMap>(
entries: {
collection: C;
id: keyof DataEntryMap[C];
}[]
): Promise<CollectionEntry<C>[]>;
export function reference<C extends keyof AnyEntryMap>(
collection: C
): import('astro/zod').ZodEffects<
import('astro/zod').ZodString,
C extends keyof ContentEntryMap
? {
collection: C;
slug: ValidContentEntrySlug<C>;
}
: {
collection: C;
id: keyof DataEntryMap[C];
}
>;
// Allow generic `string` to avoid excessive type errors in the config
// if `dev` is not running to update as you edit.
// Invalid collection names will be caught at build time.
export function reference<C extends string>(
collection: C
): import('astro/zod').ZodEffects<import('astro/zod').ZodString, never>;
type ReturnTypeOrOriginal<T> = T extends (...args: any[]) => infer R ? R : T;
type InferEntrySchema<C extends keyof AnyEntryMap> = import('astro/zod').infer<
ReturnTypeOrOriginal<Required<ContentConfig['collections'][C]>['schema']>
>;
type ContentEntryMap = {
"blog": {
"astro-usage.md": {
id: "astro-usage.md";
slug: "astro-usage";
body: string;
collection: "blog";
data: InferEntrySchema<"blog">
} & { render(): Render[".md"] };
"cernunnos-with-requiem.mdx": {
id: "cernunnos-with-requiem.mdx";
slug: "cernunnos-with-requiem";
body: string;
collection: "blog";
data: InferEntrySchema<"blog">
} & { render(): Render[".mdx"] };
"deploying-this-round-2.md": {
id: "deploying-this-round-2.md";
slug: "deploying-this-round-2";
body: string;
collection: "blog";
data: InferEntrySchema<"blog">
} & { render(): Render[".md"] };
"deploying-this.md": {
id: "deploying-this.md";
slug: "deploying-this";
body: string;
collection: "blog";
data: InferEntrySchema<"blog">
} & { render(): Render[".md"] };
"fgo-ta.md": {
id: "fgo-ta.md";
slug: "fgo-ta";
body: string;
collection: "blog";
data: InferEntrySchema<"blog">
} & { render(): Render[".md"] };
"hello-world.md": {
id: "hello-world.md";
slug: "hello-world";
body: string;
collection: "blog";
data: InferEntrySchema<"blog">
} & { render(): Render[".md"] };
"instant-death.mdx": {
id: "instant-death.mdx";
slug: "instant-death";
body: string;
collection: "blog";
data: InferEntrySchema<"blog">
} & { render(): Render[".mdx"] };
};
};
type DataEntryMap = {
};
type AnyEntryMap = ContentEntryMap & DataEntryMap;
export type ContentConfig = typeof import("./../src/content/config.js");
}

View file

@ -4,38 +4,54 @@ on:
- '[0-9]+\.[0-9]+\.[0-9]+-pre\.[0-9]+' - '[0-9]+\.[0-9]+\.[0-9]+-pre\.[0-9]+'
jobs: jobs:
checking: check-tag:
runs-on: docker runs-on: docker
container: node:lts steps:
- name: Checking Out Repository Code
uses: https://code.forgejo.org/actions/checkout@v3
- name: Check if Version in package.json matches Tag
run: |
VERSION=$(cat package.json | grep "version" | sed 's/.*://' | tr -d , | tr -d \" | tr -d " " )
if test $VERSION != "${{ github.ref_name }}"; then
echo "Expected Version is: '${{ github.ref_name }}' actual Version is: '$VERSION'";
exit 1
else
echo "Version is: '$VERSION'";
fi
checking:
needs: [ check-tag ]
runs-on: docker
container: forgejo.neshweb.net/ci-docker-images/node-alpine-git:latest
steps: steps:
- name: Checkout source code - name: Checkout source code
uses: https://code.forgejo.org/actions/checkout@v3 uses: https://code.forgejo.org/actions/checkout@v3
- name: Install packages - name: Install packages
run: npm install run: npm i
- name: Run astro check (linting + static analysis) - name: Run astro check (linting + static analysis)
run: npm run astro check run: npm run astro check
build-site: build-site:
needs: [checking] needs: [ checking ]
if: success() if: success()
runs-on: dind runs-on: dind
steps: steps:
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub - name: Log into Docker Package Registry
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: forgejo.neshweb.net registry: forgejo.neshweb.net
username: ${{ secrets.FORGEJO_USERNAME }} username: ${{ secrets.FORGEJO_USERNAME }}
password: ${{ secrets.FORGEJO_TOKEN }} password: ${{ secrets.FORGEJO_TOKEN }}
- name: Push to Package Registry - name: Build and push to Docker Package Registry
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
push: true push: true
tags: forgejo.neshweb.net/firq/firq-dev-website:${{ github.ref_name }}, forgejo.neshweb.net/firq/firq-dev-website:preview tags: forgejo.neshweb.net/firq/firq-dev-website:${{ github.ref_name }}, forgejo.neshweb.net/firq/firq-dev-website:preview
publish: create-release:
needs: [build-site] needs: [ build-site ]
if: success() if: success()
runs-on: docker runs-on: docker
steps: steps:

View file

@ -4,38 +4,54 @@ on:
- '[0-9]+\.[0-9]+\.[0-9]+' - '[0-9]+\.[0-9]+\.[0-9]+'
jobs: jobs:
checking: check-tag:
runs-on: docker runs-on: docker
container: node:lts steps:
- name: Checking Out Repository Code
uses: https://code.forgejo.org/actions/checkout@v3
- name: Check if Version in package.json matches Tag
run: |
VERSION=$(cat package.json | grep "version" | sed 's/.*://' | tr -d , | tr -d \" | tr -d " " )
if test $VERSION != "${{ github.ref_name }}"; then
echo "Expected Version is: '${{ github.ref_name }}' actual Version is: '$VERSION'";
exit 1
else
echo "Version is: '$VERSION'";
fi
checking:
needs: [ check-tag ]
runs-on: docker
container: forgejo.neshweb.net/ci-docker-images/node-alpine-git:latest
steps: steps:
- name: Checkout source code - name: Checkout source code
uses: https://code.forgejo.org/actions/checkout@v3 uses: https://code.forgejo.org/actions/checkout@v3
- name: Install packages - name: Install packages
run: npm install run: npm i
- name: Run astro check (linting + static analysis) - name: Run astro check (linting + static analysis)
run: npm run astro check run: npm run astro check
build-site: build-site:
needs: [checking] needs: [ checking ]
if: success() if: success()
runs-on: dind runs-on: dind
steps: steps:
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub - name: Log into Docker Package Registry
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
registry: forgejo.neshweb.net registry: forgejo.neshweb.net
username: ${{ secrets.FORGEJO_USERNAME }} username: ${{ secrets.FORGEJO_USERNAME }}
password: ${{ secrets.FORGEJO_TOKEN }} password: ${{ secrets.FORGEJO_TOKEN }}
- name: Push to Package Registry - name: Build and push to Docker Package Registry
uses: docker/build-push-action@v5 uses: docker/build-push-action@v5
with: with:
push: true push: true
tags: forgejo.neshweb.net/firq/firq-dev-website:${{ github.ref_name }}, forgejo.neshweb.net/firq/firq-dev-website:latest tags: forgejo.neshweb.net/firq/firq-dev-website:${{ github.ref_name }}, forgejo.neshweb.net/firq/firq-dev-website:latest
release: create-release:
needs: [build-site] needs: [ build-site ]
if: success() if: success()
runs-on: docker runs-on: docker
steps: steps:

View file

@ -1,16 +1,16 @@
on: on:
push: push:
branches: branches:
- "**" - '**'
jobs: jobs:
checking: astro-check:
runs-on: docker runs-on: docker
container: node:lts container: forgejo.neshweb.net/ci-docker-images/node-alpine-git:latest
steps: steps:
- name: Checkout source code - name: Checkout source code
uses: https://code.forgejo.org/actions/checkout@v3 uses: https://code.forgejo.org/actions/checkout@v3
- name: Install packages - name: Install packages
run: npm install run: npm i
- name: Run astro check (linting + static analysis) - name: Run astro check (linting + static analysis)
run: npm run astro check run: npm run astro check

View file

@ -11,7 +11,7 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: https://code.forgejo.org/actions/checkout@v3 uses: https://code.forgejo.org/actions/checkout@v3
- name: Run unlighthouse - name: Run unlighthouse
run: unlighthouse-ci --site "https://preview.firq.dev/" run: unlighthouse-ci --site "https://preview.firq.dev/" --disable-dynamic-sampling
- name: Prepare artifacts - name: Prepare artifacts
run: cp serve.json unlighthouse-reports run: cp serve.json unlighthouse-reports
- name: Upload reports - name: Upload reports

7714
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
{ {
"name": "@firq/fgosite", "name": "@firq/fgosite",
"type": "module", "type": "module",
"version": "0.1.28-pre.4", "version": "0.2.0-pre.1",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "astro dev", "dev": "astro dev",
@ -11,15 +11,17 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astro-community/astro-embed-youtube": "^0.4.3", "@astro-community/astro-embed-youtube": "^0.5.2",
"@astrojs/check": "^0.3.3", "@astrojs/check": "^0.8.1",
"@astrojs/mdx": "^2.0.3", "@astrojs/mdx": "^3.1.3",
"@astrojs/sitemap": "^3.0.3", "@astrojs/sitemap": "^3.1.6",
"astro": "^4.2.1", "@fontsource/work-sans": "^5.0.18",
"autoprefixer": "^10.4.16", "astro": "^4.11.5",
"iconoir": "^7.2.0", "astro-meta-tags": "^0.3.0",
"postcss-preset-env": "^9.3.0", "autoprefixer": "^10.4.19",
"typescript": "^5.3.3" "iconoir": "^7.7.0",
"postcss-preset-env": "^9.6.0",
"typescript": "^5.5.3"
}, },
"browserslist": [ "browserslist": [
"last 2 versions", "last 2 versions",

View file

@ -1,8 +1,9 @@
--- ---
export interface Props { export interface Props {
url: string | undefined url: string
slug: string
title: string title: string
pubdate: string pubdate: Date
description: string description: string
author: string author: string
} }
@ -12,11 +13,11 @@ const options_date: Intl.DateTimeFormatOptions = {
month: 'long', month: 'long',
day: '2-digit', day: '2-digit',
} }
const { author, description, pubdate, url, title } = Astro.props const { author, description, pubdate, url, title, slug } = Astro.props
const date = new Date(pubdate).toLocaleDateString('en-GB', options_date) const date = new Date(pubdate).toLocaleDateString('en-GB', options_date)
--- ---
<a href={url} rel="noopener noreferrer"> <a href={`${url}/${slug}`} rel="noopener noreferrer">
<div class="circle"></div> <div class="circle"></div>
<article> <article>
<h2>{title}</h2> <h2>{title}</h2>
@ -29,38 +30,14 @@ const date = new Date(pubdate).toLocaleDateString('en-GB', options_date)
.circle { .circle {
display: none; display: none;
} }
@media (min-width: 900px) {
.circle {
margin: 1rem 1rem 1rem 0rem;
position: relative;
display: flex;
visibility: visible;
height: 1.5rem;
width: 1.5rem;
border-radius: 40%;
background-color: var(--c-darkpurple);
transition: transform var(--speed) var(--ease);
}
a:hover > .circle {
height: 1.75rem;
width: 1.75rem;
translate: -0.125rem;
margin-right: 0.825rem;
}
article {
margin-left: 0.5rem;
}
}
a { a {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
display: flex; display: flex;
text-decoration: none; text-decoration: none;
height: auto; height: fit-content;
margin: 0.5rem; margin: 0px 0.5rem;
width: 100%; width: 100%;
} }
p { p {
@ -88,8 +65,8 @@ const date = new Date(pubdate).toLocaleDateString('en-GB', options_date)
flex: 1; flex: 1;
flex-wrap: wrap; flex-wrap: wrap;
flex-direction: column; flex-direction: column;
align-items: flex-start; align-items: center;
align-content: flex-start; align-content: center;
justify-content: center; justify-content: center;
background-color: var(--c-darkergray); background-color: var(--c-darkergray);
padding: 10px; padding: 10px;
@ -98,7 +75,47 @@ const date = new Date(pubdate).toLocaleDateString('en-GB', options_date)
min-height: 100%; min-height: 100%;
border-radius: 1.25rem; border-radius: 1.25rem;
} }
a:hover > article { a:hover > article {
transform: scaleY(102.5%) scaleX(101%); transform: scaleY(102.5%) scaleX(101%);
transition: transform var(--speed) var(--ease);
}
@media (min-width: 900px) {
.circle {
margin: 1rem 0.5rem 1rem 0.5rem;
position: relative;
display: flex;
visibility: visible;
height: 1rem;
width: 1rem;
background-color: var(--c-darkpurple);
border-style: solid;
border-width: 0.25rem;
border-color: var(--c-lightgray);
border-radius: 40%;
transition: transform var(--speed) var(--ease);
}
a:hover > .circle {
height: 1.25rem;
width: 1.25rem;
translate: -0.125rem;
margin-right: 4px;
}
a:hover article {
border-color: var(--c-darkpurple);
transform: none;
}
article {
border-style: solid;
border-width: 2px;
border-color: var(--c-darkergray);
align-items: flex-start;
align-content: flex-start;
margin-left: 0.5rem;
}
} }
</style> </style>

View file

@ -1,8 +1,8 @@
--- ---
import { Image } from 'astro:assets' import { Image } from 'astro:assets'
import mlb_ce from '../assets/ce/mlb.webp' import mlb_ce from '../../assets/ce/mlb.webp'
import type { GlobImage } from '../types/generic' import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../utils/tools' import { plsLoadImage } from '../../utils/tools'
export interface Props { export interface Props {
name: string name: string

View file

@ -1,7 +1,7 @@
--- ---
import { Image } from 'astro:assets' import { Image } from 'astro:assets'
import type { GlobImage } from '../types/generic' import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../utils/tools' import { plsLoadImage } from '../../utils/tools'
export interface Props { export interface Props {
site: string site: string

View file

@ -1,7 +1,7 @@
--- ---
import { Image } from 'astro:assets' import { Image } from 'astro:assets'
import type { GlobImage } from '../types/generic' import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../utils/tools' import { plsLoadImage } from '../../utils/tools'
export interface Props { export interface Props {
name: string name: string

View file

@ -1,7 +1,7 @@
--- ---
import { Image } from 'astro:assets'; import { Image } from 'astro:assets';
import type { GlobImage } from '../types/generic' import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../utils/tools' import { plsLoadImage } from '../../utils/tools'
export interface Props { export interface Props {
name: string name: string

View file

@ -1,7 +1,7 @@
--- ---
import { Image } from 'astro:assets' import { Image } from 'astro:assets'
import type { GlobImage } from '../types/generic' import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../utils/tools' import { plsLoadImage } from '../../utils/tools'
export interface Props { export interface Props {
date: string date: string

View file

@ -1,7 +1,7 @@
--- ---
import { Image } from 'astro:assets' import { Image } from 'astro:assets'
import type { GlobImage } from '../types/generic' import type { GlobImage } from '../../types/generic'
import { plsLoadImage } from '../utils/tools' import { plsLoadImage } from '../../utils/tools'
export interface Props { export interface Props {
title: string title: string

View file

@ -1,4 +1,9 @@
--- ---
export interface Props {
fadeout?: boolean
}
const { fadeout } = Astro.props
const display = fadeout ? "": "display: none"
--- ---
<div> <div>
@ -6,22 +11,33 @@
I am currently working on a site to catalogue past and future TAs.<br/> I am currently working on a site to catalogue past and future TAs.<br/>
Check it out at <a href="https://fgo-ta.com">fgo-ta.com</a> Check it out at <a href="https://fgo-ta.com">fgo-ta.com</a>
</span> </span>
<div class="fade" style={display}></div>
</div> </div>
<style> <style>
div { div {
display: flex; display: flex;
width: 100%; width: 100%;
height: 5em; flex-wrap: nowrap;
background-color: var(--c-gray); flex-flow: column;
background-color: var(--c-darkergray);
text-align: center; text-align: center;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: white; color: white;
font-size: 1.5em; font-size: 1.5em;
padding: 2rem 0rem 0rem 0rem;
} }
a { a {
color: var(--c-darkpurple); text-align: center;
text-decoration: none; text-decoration: none;
color: var(--c-darkpurple);
}
.fade {
margin-top: 3rem;
background: linear-gradient(to bottom, transparent, var(--c-lightgray));
height: 2.5rem;
width: 100%;
} }
</style> </style>

View file

@ -1,21 +1,27 @@
--- ---
import { Image } from 'astro:assets'; import { Image } from 'astro:assets'
import logo from '../assets/logo.svg' import logo from '../../assets/logo.svg'
import hamburger from 'iconoir/icons/menu.svg' import hamburger from 'iconoir/icons/menu.svg'
const hamburger_src_url = `url("${hamburger.src}")`; const hamburger_src_url = `url("${hamburger.src}")`
--- ---
<header> <header>
<a href="/" rel="noopener noreferrer" aria-label="Home" role="link"> <a href="/" rel="noopener noreferrer" aria-label="Home" role="button">
<Image src={logo} alt=""/> <Image src={logo} alt="" loading="eager"/>
<span class="visually-hidden">Firq Logo</span> <span class="visually-hidden">Logo</span>
</a> </a>
<ul class="desktop"> <ul class="desktop">
<slot name="desktop"/> <slot name="desktop" />
</ul> </ul>
<button class="mobile" aria-label="Navigation Button" tabindex="0" onclick="this.focus()" role="button"> <button
class="mobile"
aria-label="Navigation Button"
tabindex="0"
onclick="this.focus()"
role="button"
>
<ul> <ul>
<slot name="mobile"/> <slot name="mobile" />
</ul> </ul>
<div class="placeholder"></div> <div class="placeholder"></div>
<div class="hamburger-menu" role="navigation"></div> <div class="hamburger-menu" role="navigation"></div>
@ -27,12 +33,13 @@ const hamburger_src_url = `url("${hamburger.src}")`;
z-index: 1000; z-index: 1000;
position: sticky; position: sticky;
top: 0px; top: 0px;
background-color: var(--c-darkgray); background-color: var(--c-darkergray);
display: flex; display: flex;
height: auto; height: auto;
width: 100%; width: 100%;
align-items: flex-start; align-items: flex-start;
line-height: 1.5em; line-height: 1.5em;
border-bottom: 2px solid var(--c-darkpurple) ;
} }
header > a { header > a {
margin-left: 16px; margin-left: 16px;
@ -61,7 +68,7 @@ const hamburger_src_url = `url("${hamburger.src}")`;
line-height: 1.5em; line-height: 1.5em;
} }
.mobile > ul { .mobile > ul {
background-color: var(--c-darkgray); background-color: var(--c-darkergray);
align-items: center; align-items: center;
flex-wrap: wrap; flex-wrap: wrap;
flex-direction: column; flex-direction: column;
@ -78,7 +85,7 @@ const hamburger_src_url = `url("${hamburger.src}")`;
.mobile { .mobile {
display: flex; display: flex;
background-color: var(--c-darkgray); background-color: var(--c-darkergray);
border: 0px; border: 0px;
width: 100%; width: 100%;
height: 64px; height: 64px;
@ -108,13 +115,14 @@ const hamburger_src_url = `url("${hamburger.src}")`;
.hamburger-menu { .hamburger-menu {
mask: var(--hamburger_src_url) no-repeat center; mask: var(--hamburger_src_url) no-repeat center;
mask-size: cover;
background-color: white; background-color: white;
width: 2rem; width: 2.25rem;
height: 2rem; height: 2.25rem;
position: static; position: static;
align-self: flex-start; align-self: flex-start;
margin-right: 1rem; margin-right: 1rem;
margin-top: 1rem; margin-top: 0.825rem;
} }
@media (min-width: 1140px) { @media (min-width: 1140px) {

View file

@ -1,7 +1,7 @@
--- ---
export interface Props { export interface Props {
currentPage?: string currentPage?: string
navtype: "mobile" | "desktop" navtype: 'mobile' | 'desktop'
link: string link: string
text: string text: string
icon: ImageMetadata icon: ImageMetadata
@ -18,10 +18,10 @@ if (currentPage === slug) {
currPage = 'current' currPage = 'current'
} }
const icon_src_url = `url("${icon.src}")`; const icon_src_url = `url("${icon.src}")`
const fulllink = `/${slug}` const fulllink = `/${slug}`
let extraattributes = navtype === "mobile" ? { tabindex: "0"} : {} let extraattributes = navtype === 'mobile' ? { tabindex: '0' } : {}
--- ---
<li> <li>
@ -30,7 +30,7 @@ let extraattributes = navtype === "mobile" ? { tabindex: "0"} : {}
rel="noopener noreferrer" rel="noopener noreferrer"
aria-label={text} aria-label={text}
class={currPage} class={currPage}
role="navigation" role="button"
{...extraattributes} {...extraattributes}
> >
<div class="icon"></div> <div class="icon"></div>
@ -60,11 +60,11 @@ let extraattributes = navtype === "mobile" ? { tabindex: "0"} : {}
} }
li > a:hover { li > a:hover {
color: var(--c-purplepink); color: var(--c-purplepink) !important;
} }
li > a:hover > .icon { li > a:hover > .icon {
background-color: var(--c-purplepink); background-color: var(--c-purplepink) !important;
} }
.current { .current {

View file

@ -0,0 +1,109 @@
---
import '@fontsource/work-sans/800.css'
import '@fontsource/work-sans/600.css'
export interface Props {
maintext: string
subtext: string
fadeout?: boolean
baseurl?: string
returnbutton?: boolean
}
const { maintext, subtext, fadeout, baseurl, returnbutton } = Astro.props
const displayFadeout = fadeout ? "": "display: none"
const displayBackButton = returnbutton ? "": "display: none"
---
<div class="wrap">
<div class="head">{maintext}</div>
<div class="sub">{subtext}</div>
<a href=`/${baseurl}` style={displayBackButton}>&lt;&lt; Back to {baseurl}</a>
<div class="fade" style={displayFadeout}></div>
</div>
<style>
a {
font-weight: 600;
font-family: 'Work Sans', 'Helvetica Neue', Helvetica, Helvetica, Arial, sans-serif;
color: white;
margin: 1rem 0px 0px;
padding: 0.5rem 0.75rem;
text-decoration: none;
background-color: var(--c-lightgray);
border-radius: 10px;
border-style: solid;
border-width: 2px;
border-color: var(--c-lightgray);
text-transform: capitalize;
}
a:hover {
border-color: var(--c-darkpurple);
}
.wrap {
position: relative;
width: 100%;
display: flex;
text-align: center;
align-items: center;
flex-wrap: wrap;
flex-direction: column;
color: var(--c-lighter);
background-color: var(--c-darkergray);
}
.fade {
margin-top: 2rem;
background: linear-gradient(to bottom, transparent, var(--c-lightgray));
height: 2.5rem;
width: 100%;
}
.head {
hyphens: auto;
padding-top: 2rem;
font-size: 2rem;
font-weight: 800;
font-family: 'Work Sans', 'Helvetica Neue', Helvetica, Helvetica, Arial,
sans-serif;
}
.sub {
font-size: 0.75rem;
font-weight: 600;
font-family: 'Work Sans', 'Helvetica Neue', Helvetica, Helvetica, Arial,
sans-serif;
margin-top: 0.5em;
}
.head {
color: var(--c-darkpurple);
}
@supports (background-clip: text) {
.head {
background: linear-gradient(125deg, var(--c-darkpurple), var(--c-purplepink), var(--c-reddish) );
background-clip: text;
color: transparent;
}
}
@media (min-width: 620px) {
.head {
hyphens: none;
font-size: 3rem;
}
.sub {
font-size: 0.75rem;
}
}
@media (min-width: 1000px) {
.head {
font-size: 4rem;
}
.sub {
font-size: 1rem;
}
}
</style>

View file

@ -0,0 +1,75 @@
---
import '@fontsource/work-sans/800.css'
---
<div class="wrap">
<div class="head">Hi, I'm <span class="fancy">Firq</span></div>
<div class="sub">Nice to meet you</div>
<div class="fade"></div>
</div>
<style>
.wrap {
position: relative;
width: 100%;
display: flex;
text-align: center;
align-items: center;
flex-wrap: wrap;
flex-direction: column;
color: var(--c-lighter);
background-color: var(--c-darkergray);
}
.fade {
margin-top: 1.5rem;
background: linear-gradient(to bottom, transparent, var(--c-lightgray));
height: 2.5rem;
width: 100%;
}
.head {
padding-top: 2rem;
font-size: 3rem;
font-weight: 800;
font-family: 'Work Sans', 'Helvetica Neue', Helvetica, Helvetica, Arial,
sans-serif;
}
.sub {
font-size: 1rem;
font-weight: 800;
font-family: 'Work Sans', 'Helvetica Neue', Helvetica, Helvetica, Arial,
sans-serif;
}
.fancy {
color: var(--c-darkpurple);
}
@supports (background-clip: text) {
.fancy {
background: linear-gradient(125deg, var(--c-darkpurple), var(--c-purplepink), var(--c-reddish) );
background-clip: text;
color: transparent;
}
}
@media (min-width: 620px) {
.head {
font-size: 4rem;
}
.sub {
font-size: 1.25rem;
}
}
@media (min-width: 1000px) {
.head {
font-size: 6rem;
}
.sub {
font-size: 1.5rem;
}
}
</style>

16
src/content/config.ts Normal file
View file

@ -0,0 +1,16 @@
import { z, defineCollection } from 'astro:content'
const blogCollection = defineCollection({
type: 'content', // v2.5.0 and later
schema: z.object({
title: z.string(),
tags: z.array(z.string()),
pubDate: z.date(),
description: z.string(),
author: z.string(),
}),
})
export const collections = {
blog: blogCollection,
}

1
src/env.d.ts vendored
View file

@ -1 +1,2 @@
/// <reference path="../.astro/types.d.ts" />
/// <reference types="astro/client" /> /// <reference types="astro/client" />

View file

@ -1,6 +1,6 @@
--- ---
import Navbar from '../components/navbar.astro' import Navbar from '../components/navbar/navbar.astro'
import NavbarEntry from '../components/navbarEntry.astro' import NavbarEntry from '../components/navbar/navbarEntry.astro'
import navdata from '../../static/data/_navdata.json' import navdata from '../../static/data/_navdata.json'
import embed from '../assets/embed.png' import embed from '../assets/embed.png'
@ -77,12 +77,22 @@ const mapped_navdata = navdata.map((item) => ({
<Navbar> <Navbar>
{ {
mapped_navdata.map((item) => ( mapped_navdata.map((item) => (
<NavbarEntry currentPage={currentpage} navtype="desktop" {...item} slot="desktop"/> <NavbarEntry
currentPage={currentpage}
navtype="desktop"
{...item}
slot="desktop"
/>
)) ))
} }
{ {
mapped_navdata.map((item) => ( mapped_navdata.map((item) => (
<NavbarEntry currentPage={currentpage} navtype="mobile" {...item} slot="mobile"/> <NavbarEntry
currentPage={currentpage}
navtype="mobile"
{...item}
slot="mobile"
/>
)) ))
} }
</Navbar> </Navbar>
@ -98,10 +108,12 @@ const mapped_navdata = navdata.map((item) => ({
--c-darkgray: #1e1e1e; --c-darkgray: #1e1e1e;
--c-duskgray: #242424; --c-duskgray: #242424;
--c-gray: #2e2e2e; --c-gray: #2e2e2e;
--c-lighter: #eee;
--c-lightgray: #3e3e3e; --c-lightgray: #3e3e3e;
--c-darkpurple: #b86cff; --c-darkpurple: #b86cff;
--c-purplepink: #c105ff; --c-purplepink: #c105ff;
--c-darkergray: #1b1b1b; --c-darkergray: #1b1b1b;
--c-reddish: #ff0077;
} }
body { body {
background: var(--c-lightgray); background: var(--c-lightgray);
@ -117,5 +129,5 @@ const mapped_navdata = navdata.map((item) => ({
padding: 0; padding: 0;
position: absolute; position: absolute;
width: 1px; width: 1px;
} }
</style> </style>

View file

@ -1,74 +0,0 @@
---
export interface Props {
title: string
}
const { title } = Astro.props
---
<section class="base">
<h1>{title}</h1>
<div>
<slot />
</div>
</section>
<style>
h1 {
font-size: 40px;
line-height: 48px;
letter-spacing: -1px;
color: white;
font-size: 2.25rem;
margin-top: 1rem;
margin-bottom: 0;
margin-left: auto;
margin-right: auto;
padding: 0.25rem 0.75rem;
max-width: max-content;
background-color: var(--c-darkgray);
padding: 0.25rem 1.5rem;
border-radius: 0.5rem;
padding-bottom: 0.5rem;
}
div {
row-gap: 1em;
column-gap: 1em;
justify-content: center;
align-self: center;
display: flex;
flex-flow: row wrap;
padding: 1em;
color: white;
font-size: 1em;
}
.base {
margin-left: 1rem;
margin-right: 1rem;
}
@media (min-width: 400px) {
.base {
margin-left: 3rem;
margin-right: 3rem;
}
}
@media (min-width: 1500px) {
.base {
margin-left: 10%;
margin-right: 10%;
}
}
@media (min-width: 512px) {
div {
justify-content: left;
}
}
@media (min-width: 520px) {
h1 {
margin: 0.5rem 0.75rem 0.5rem 0.75rem;
}
}
</style>

View file

@ -1,4 +1,5 @@
--- ---
import SmallTitle from '../components/titles/smallTitle.astro'
import Layout from './Layout.astro' import Layout from './Layout.astro'
const { frontmatter } = Astro.props const { frontmatter } = Astro.props
@ -13,15 +14,12 @@ const date = new Date(frontmatter.pubDate).toLocaleDateString(
'en-GB', 'en-GB',
options_date options_date
) )
const subtext = `Written by ${frontmatter.author} • Published on ${date}`
--- ---
<Layout title={title} currentpage="blog" descriptionOverride={description}> <Layout title={title} currentpage="blog" descriptionOverride={description}>
<a href="/blog"><i class="iconoir-fast-arrow-left"></i>Back to all posts</a> <SmallTitle maintext={frontmatter.title} subtext={subtext} fadeout={true} returnbutton={true} baseurl='blog'/>
<div> <div>
<h1>
{frontmatter.title}
</h1>
<p>by {frontmatter.author} • Published on {date}</p>
<article> <article>
<slot /> <slot />
</article> </article>

View file

@ -1,36 +1,59 @@
--- ---
export interface Props { export interface Props {
title: string title: string
titlehidden?: boolean
displayLine?: boolean
} }
const { title, titlehidden, displayLine } = Astro.props
const { title } = Astro.props const display = titlehidden ? "display: none" : ""
const line = displayLine ? "flex" : "none"
--- ---
<section> <section>
<h1>{title}</h1> <h1 style={display}>{title}</h1>
<div class="wrapper"> <div class="wrapper">
<div class="start hightlighter"></div>
<div class="line"></div> <div class="line"></div>
<slot /> <slot />
<div class="drop"></div> <div class="drop hightlighter"></div>
</div> </div>
</section> </section>
<style> <style define:vars={{ line }}>
.drop { section {
padding-left: 0.25em;
padding-right: 0.25em;
padding-bottom: 5rem;
}
.hightlighter {
left: 0;
right: 0;
display: flex; display: flex;
position: absolute; position: absolute;
visibility: visible; visibility: visible;
left: 0;
right: 0;
bottom: -5rem;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
height: 1.5rem; height: 1.5rem;
width: 1.5rem; width: 1.5rem;
}
.drop {
bottom: -5rem;
border-radius: 0% 50% 50% 50%; border-radius: 0% 50% 50% 50%;
transform: rotate(45deg); transform: rotate(45deg);
background-color: var(--c-darkpurple); background-color: var(--c-darkpurple);
} }
.start {
top: -2rem;
border-radius: 40%;
border-style: solid;
border-width: 0.25rem;
border-color: var(--c-lightgray);
background-color: var(--c-darkpurple);
}
.line { .line {
display: flex; display: flex;
position: absolute; position: absolute;
@ -46,30 +69,31 @@ const { title } = Astro.props
z-index: -1; z-index: -1;
} }
h1 { h1 {
font-size: 40px;
line-height: 48px; line-height: 48px;
letter-spacing: -1px; letter-spacing: -1px;
color: white; color: white;
font-size: 2.25rem; font-size: 1.6rem;
margin-top: 1rem; margin-top: 1rem;
margin-bottom: 0; margin-bottom: 0;
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
padding: 0.25rem 0.75rem;
max-width: max-content; max-width: max-content;
background-color: var(--c-darkgray); background-color: var(--c-darkgray);
padding: 0.25rem 1.5rem; padding: 0.25rem 1.5rem;
border-radius: 0.5rem; border-radius: 0.5rem;
padding-bottom: 0.5rem; padding-bottom: 0.5rem;
justify-self: center;
text-align: center;
} }
.wrapper { .wrapper {
margin: 2rem 3rem 0.5rem 3rem; margin: 2rem 2rem 0.5rem 2rem;
display: flex; display: flex;
flex-flow: column wrap; flex-flow: column wrap;
row-gap: 1em; row-gap: 1em;
column-gap: 1em; column-gap: 1em;
align-self: center; align-self: center;
align-items: stretch; align-items: stretch;
align-content: center;
justify-content: space-around; justify-content: space-around;
padding: 1em; padding: 1em;
color: white; color: white;
@ -80,21 +104,41 @@ const { title } = Astro.props
.drop { .drop {
margin-left: 1.5rem; margin-left: 1.5rem;
} }
.start {
margin-left: 1.25rem;
}
.line { .line {
margin-left: 2.1rem; margin-left: 2.1rem;
} }
h1 { h1 {
margin-left: 3rem; margin-left: 3rem;
font-size: 1.85rem;
} }
} }
@media (min-width: 1500px) { @media (min-width: 1500px) {
.wrapper { .wrapper {
margin-left: 20rem; margin-left: 15rem;
margin-right: 20rem; margin-right: 15rem;
flex-direction: row;
}
section {
padding-bottom: unset;
}
.drop, .start, .line {
display: var(--line);
margin-left: 2rem;
}
.start {
margin-left: 1.75rem;
}
.line {
margin-left: 2.6rem;
height: calc(100% + 6rem);
translate: 0px -2rem;
} }
h1 { h1 {
margin-left: 20rem; margin-left: 15rem;
margin-right: 20rem; margin-right: 15rem;
} }
} }
</style> </style>

View file

@ -1,8 +1,11 @@
--- ---
import '@fontsource/work-sans/500.css'
import '@fontsource/work-sans/600.css'
import { Image } from 'astro:assets' import { Image } from 'astro:assets'
import Layout from '../layouts/Layout.astro' import Layout from '../layouts/Layout.astro'
import BaseSection from '../layouts/baseSection.astro' import BaseSection from '../layouts/baseSection.astro'
import sadshishou from '../assets/shishousad.webp' import sadshishou from '../assets/shishousad.webp'
import SmallTitle from '../components/titles/smallTitle.astro'
const description = "Error. This shouldn't happen :/" const description = "Error. This shouldn't happen :/"
--- ---
@ -12,7 +15,7 @@ const description = "Error. This shouldn't happen :/"
currentpage="404" currentpage="404"
descriptionOverride={description} descriptionOverride={description}
> >
<BaseSection title="FirqhundredandFirq - Not Found"> <SmallTitle maintext='Error' subtext='FirqhundredandFirq - Not Found' fadeout={true}/>
<div> <div>
<Image src={sadshishou} alt="Sad Shishou" /> <Image src={sadshishou} alt="Sad Shishou" />
<h2>Well ... you were not supposed to end up here.</h2> <h2>Well ... you were not supposed to end up here.</h2>
@ -20,44 +23,51 @@ const description = "Error. This shouldn't happen :/"
&lt;&lt; Go back home &lt;&lt; Go back home
</a> </a>
</div> </div>
</BaseSection>
</Layout> </Layout>
<style> <style>
div { div {
padding: 0px 2rem;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: nowrap;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
} }
h2 { h2 {
font-family: 'Work Sans', 'Helvetica Neue', Helvetica, Helvetica, Arial, sans-serif;
font-weight: 500;
color: white; color: white;
font-size: 2rem; font-size: 1.25rem;
font-weight: bold;
margin-top: 1rem; margin-top: 1rem;
max-width: max-content; max-width: max-content;
}
a {
display: flex;
align-items: center;
justify-content: center;
width: 75%;
text-align: center; text-align: center;
color: white; font-style: italic;
background-color: var(--c-gray); }
padding: 0.5rem 0px;
margin-bottom: 2rem;
text-decoration: none;
font-size: 1.5rem;
font-weight: bold;
&:hover { a {
color: var(--c-darkpurple); text-align: center;
} width: fit-content;
font-weight: 600;
font-family: 'Work Sans', 'Helvetica Neue', Helvetica, Helvetica, Arial, sans-serif;
color: white;
margin: 1rem 0px 0px;
padding: 0.5rem 0.75rem;
text-decoration: none;
background-color: var(--c-darkergray);
border-radius: 10px;
border-style: solid;
border-width: 2px;
border-color: var(--c-darkergray);
text-transform: capitalize;
}
a:hover {
border-color: var(--c-darkpurple);
} }
img { img {
width: 256px; width: 200px;
height: 256px; height: auto;
border-radius: 10%;
} }
</style> </style>

View file

@ -1,17 +1,19 @@
--- ---
import Layout from '../layouts/Layout.astro' import Layout from '../layouts/Layout.astro'
import AboutSection from '../layouts/aboutSection.astro'
import ContactSection from '../layouts/contactSection.astro' import ContactSection from '../layouts/contactSection.astro'
import ContactCard from '../components/contactCard.astro' import ContactCard from '../components/cards/contactCard.astro'
import contactdata from '../../static/data/_contactdata.json' import contactdata from '../../static/data/_contactdata.json'
import CustomFooter from '../layouts/customFooter.astro' import CustomFooter from '../layouts/customFooter.astro'
import TechnologyCard from '../components/technologyCard.astro' import TechnologyCard from '../components/cards/technologyCard.astro'
import technologydata from '../../static/data/_technologydata.json' import technologydata from '../../static/data/_technologydata.json'
import SmallTitle from '../components/titles/smallTitle.astro'
const description = const description =
"A summary of the technologies used as well as my contact information. You'll also find disclaimers and thank you notes for the people that helped me." "A summary of the technologies used as well as my contact information. You'll also find disclaimers and thank you notes for the people that helped me."
const subtext =
"This is a small sideproject that I'm creating. First time doing webdev in general, and first project using Typescript."
--- ---
<Layout <Layout
@ -19,10 +21,7 @@ const description =
currentpage="about" currentpage="about"
descriptionOverride={description} descriptionOverride={description}
> >
<AboutSection title="About"> <SmallTitle maintext="About" subtext={subtext} fadeout={true} />
This is a small sideproject that I'm creating. First time doing webdev in
general, and first project using Typescript.
</AboutSection>
<ContactSection title="Technologies used"> <ContactSection title="Technologies used">
{technologydata.map((item) => <TechnologyCard {...item} />)} {technologydata.map((item) => <TechnologyCard {...item} />)}
</ContactSection> </ContactSection>

View file

@ -1,35 +0,0 @@
---
import Layout from '../layouts/Layout.astro'
import BlogCard from '../components/blogCard.astro'
import BlogSection from '../layouts/blogSection.astro'
const description =
'My own small blog. Topics include FGO, TA, Programming, web technologies and more!'
const allPosts = await Astro.glob('../pages/blog/*.{md,mdx}')
allPosts.sort(
(a, b) =>
Date.parse(b.frontmatter.pubDate) - Date.parse(a.frontmatter.pubDate)
)
---
<Layout
title="Blog - Firq FGO Site"
currentpage="blog"
descriptionOverride={description}
>
<BlogSection title="Blog Articles">
{
allPosts.map((post) => (
<BlogCard
url={post.url}
title={post.frontmatter.title}
pubdate={post.frontmatter.pubDate}
description={post.frontmatter.description}
author={post.frontmatter.author}
/>
))
}
</BlogSection>
</Layout>
<style></style>

View file

@ -0,0 +1,17 @@
---
import { getCollection } from 'astro:content'
export async function getStaticPaths() {
const blogEntries = await getCollection('blog')
return blogEntries.map((entry) => ({
params: { slug: entry.slug },
props: { entry },
}))
}
const { entry } = Astro.props
const { Content } = await entry.render()
---
<Content />

View file

@ -0,0 +1,39 @@
---
import Layout from '../../layouts/Layout.astro'
import BlogCard from '../../components/cards/blogCard.astro'
import BlogSection from '../../layouts/blogSection.astro'
import SmallTitle from '../../components/titles/smallTitle.astro'
import { getCollection } from 'astro:content'
const description =
'My own small blog. Topics include FGO, TA, Programming, web technologies and more!'
const blogEntries = await getCollection('blog')
blogEntries.sort(
(a, b) =>
(b.data.pubDate.valueOf() - a.data.pubDate.valueOf() )
)
---
<Layout
title="Blog - Firq FGO Site"
currentpage="blog"
descriptionOverride={description}
>
<SmallTitle maintext="Blog Articles" subtext="" fadeout={true} />
<BlogSection title="Blog Articles" displayLine={true} titlehidden={true}>
{
blogEntries.map((post) => (
<BlogCard
url="blog"
slug={post.slug}
title={post.data.title}
pubdate={post.data.pubDate}
description={post.data.description}
author={post.data.author}
/>
))
}
</BlogSection>
</Layout>
<style></style>

View file

@ -1,9 +1,9 @@
--- ---
import Layout from '../layouts/Layout.astro' import Layout from '../layouts/Layout.astro'
import Hero from '../components/hero.astro'
import BaseSection from '../layouts/baseSection.astro' import BaseSection from '../layouts/baseSection.astro'
import FavouriteCard from '../components/favouriteCard.astro' import FavouriteCard from '../components/cards/favouriteCard.astro'
import favouritesdata from '../../static/data/_favouritesdata.json' import favouritesdata from '../../static/data/_favouritesdata.json'
import Hi from '../components/titles/title.astro'
const description = const description =
'The very own page of Firq for providing informating about TA servants, listing past TA achievements and hosting a blog for talking about FGO, Programming and other stuff' 'The very own page of Firq for providing informating about TA servants, listing past TA achievements and hosting a blog for talking about FGO, Programming and other stuff'
@ -14,7 +14,7 @@ const description =
currentpage="home" currentpage="home"
descriptionOverride={description} descriptionOverride={description}
> >
<Hero /> <Hi />
<BaseSection title="Favourites"> <BaseSection title="Favourites">
{favouritesdata.map((item) => <FavouriteCard {...item} />)} {favouritesdata.map((item) => <FavouriteCard {...item} />)}
</BaseSection> </BaseSection>

View file

@ -2,11 +2,12 @@
import Layout from '../layouts/Layout.astro' import Layout from '../layouts/Layout.astro'
import BaseSection from '../layouts/baseSection.astro' import BaseSection from '../layouts/baseSection.astro'
import ServantCard from '../components/servantCard.astro' import ServantCard from '../components/cards/servantCard.astro'
import servantdata from '../../static/data/_servantdata.json' import servantdata from '../../static/data/_servantdata.json'
import CeCard from '../components/ceCard.astro' import CeCard from '../components/cards/ceCard.astro'
import cedata from '../../static/data/_cedata.json' import cedata from '../../static/data/_cedata.json'
import SmallTitle from '../components/titles/smallTitle.astro'
const description = const description =
'A list of all the servants and ces that Firq can offer up on support for TA.' 'A list of all the servants and ces that Firq can offer up on support for TA.'
@ -17,6 +18,7 @@ const description =
currentpage="servants" currentpage="servants"
descriptionOverride={description} descriptionOverride={description}
> >
<SmallTitle maintext='TA Offering' subtext='Servants and CEs I can offer for your TAs' fadeout={true}/>
<BaseSection title="Servants"> <BaseSection title="Servants">
{servantdata.map((item) => <ServantCard {...item} />)} {servantdata.map((item) => <ServantCard {...item} />)}
</BaseSection> </BaseSection>

View file

@ -8,10 +8,11 @@
import Layout from '../layouts/Layout.astro' import Layout from '../layouts/Layout.astro'
import TaSection from '../layouts/taSection.astro' import TaSection from '../layouts/taSection.astro'
import TaCard from '../components/taCard.astro' import TaCard from '../components/cards/taCard.astro'
import tadata from '../../static/data/_tadata.json' import tadata from '../../static/data/_tadata.json'
import featured_data from '../../static/data/_featureddata.json' import featured_data from '../../static/data/_featureddata.json'
import FgotaHero from '../components/fgotaHero.astro' import FgotaHero from '../components/fgotaHero.astro'
import SmallTitle from '../components/titles/smallTitle.astro'
const important_data = tadata.filter(function (el) { const important_data = tadata.filter(function (el) {
return [ return [
@ -37,7 +38,8 @@ const description = 'A collection of TAs previously completed be Firq.'
currentpage="ta-collection" currentpage="ta-collection"
descriptionOverride={description} descriptionOverride={description}
> >
<FgotaHero /> <SmallTitle maintext='TA Collection' subtext=''/>
<FgotaHero fadeout={true}/>
<TaSection title="Notable TAs" abovetext="My most notable TAs"> <TaSection title="Notable TAs" abovetext="My most notable TAs">
{important_data.map((item) => <TaCard {...item} />)} {important_data.map((item) => <TaCard {...item} />)}
</TaSection> </TaSection>