create partner layout

This commit is contained in:
Jesse Winton
2025-03-07 16:00:25 -05:00
parent e0adf7b422
commit b2bc9247aa
5 changed files with 232 additions and 11 deletions

View File

@@ -0,0 +1,188 @@
<script lang="ts">
import FooterNav from '$lib/components/FooterNav.svelte';
import MainFooter from '$lib/components/MainFooter.svelte';
import { Main } from '$lib/layouts';
import { DEFAULT_HOST } from '$lib/utils/metadata';
import { isHeaderHidden } from '$lib/layouts/Main.svelte';
import { integrationCategoryDescriptions } from '$lib/constants';
import { classNames } from '$lib/utils/classnames';
import type { Partner } from '$routes/partners/catalog/+page';
export let title: Partner['title'];
export let isPartner: Partner['isPartner'];
export let product: Partner['product'];
export let category: Partner['category'];
export let description: Partner['description'];
export let cover: Partner['cover'];
const ogImage = DEFAULT_HOST + cover;
const categoryHeading = integrationCategoryDescriptions.find(
(key) => key.slug === category.toLowerCase()
)?.heading;
</script>
<svelte:head>
<!-- Titles -->
<title>{title}</title>
<meta property="og:title" content={title} />
<meta name="twitter:title" content={title} />
<!-- Description -->
<meta name="description" content={description} />
<meta property="og:description" content={description} />
<meta name="twitter:description" content={description} />
<!-- Image -->
<meta property="og:image" content={ogImage} />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:image" content={ogImage} />
<meta name="twitter:card" content="summary_large_image" />
</svelte:head>
<Main>
<div
class={classNames(
'grid-bg border-smooth relative flex items-center border-b py-28 px-5 lg:px-8 xl:px-16',
'before:from-accent/20 before:absolute before:inset-0 before:-z-1 before:bg-linear-to-tr before:via-transparent before:via-40% before:to-transparent'
)}
>
<div class="container relative w-full pb-0">
<div class="flex flex-col gap-4">
<a href="/partners" class="text-caption text-primary group flex gap-2">
<span class="web-icon-arrow-left transition group-hover:-translate-x-1" />
Back to Partners Catalog
</a>
<h1 class="text-headline font-aeonik-pro text-primary">{title}</h1>
</div>
</div>
</div>
<div class="py-10">
<div class="container">
<article class="web-u-gap-60-not-mobile web-u-gap-40-mobile flex flex-col">
<div class="l-grid-2-1 web-u-row-gap-56 web-u-gap-40-mobile">
<div class="l-grid-content">
<div class="web-article">
<div class="web-article-content">
<slot />
</div>
</div>
</div>
<div class="l-grid-sidebar">
<dl
class="sidebar-desc flex flex-col gap-5"
style:top={$isHeaderHidden ? '4rem' : '9rem'}
>
<div class="flex justify-between gap-2">
<dt>Vendor</dt>
<dd class="text-primary">{product.vendor}</dd>
</div>
<div class="web-u-sep-block-end"></div>
{#if isPartner}
<div class="flex justify-between gap-2">
<dt>Partner</dt>
<dd><div class="web-inline-tag">Verified</div></dd>
</div>
{/if}
<div class="web-u-sep-block-end"></div>
<div class="flex justify-between gap-2">
<dt>Category</dt>
<dd class="text-primary">{categoryHeading}</dd>
</div>
</dl>
</div>
</div>
</article>
</div>
</div>
<div class="mt-12 overflow-hidden py-10">
<div class="container">
<FooterNav />
<MainFooter />
</div>
</div>
</Main>
<style lang="scss">
@use '$scss/abstract/functions' as f;
@use '$scss/abstract/variables/devices';
.grid-bg {
--line-color: rgba(255, 255, 255, 0.02);
--size: calc(100vw / 16);
position: relative;
z-index: 1;
overflow: hidden;
background-image: repeating-linear-gradient(
0deg,
var(--line-color),
var(--line-color) 1px,
transparent 1px,
transparent var(--size)
),
repeating-linear-gradient(
90deg,
var(--line-color),
var(--line-color) 1px,
transparent 1px,
transparent var(--size)
);
&::after {
content: '';
position: absolute;
width: 100%;
height: 100%;
background-image: radial-gradient(
circle at bottom right,
rgba(25, 25, 28, 0.5) 19%,
transparent 100%
);
z-index: -2;
}
}
.web-pre-footer-bg {
position: absolute;
top: clamp(300px, 50vw, 50%);
left: clamp(300px, 50vw, 50%);
transform: translate(-58%, -52%);
width: clamp(1200px, 200vw, 3000px);
height: auto;
max-inline-size: unset;
max-block-size: unset;
}
.l-grid-2-1 {
@media #{devices.$break1} {
display: flex;
flex-direction: column;
}
@media #{devices.$break2open} {
display: grid;
gap: f.pxToRem(64);
grid-template-columns: repeat(12, 1fr);
}
.l-grid-content {
display: flex;
flex-direction: column;
gap: 32px;
grid-column: span 7 / span 7;
}
.l-grid-sidebar {
display: flex;
flex-direction: column;
gap: 32px;
grid-column: span 5 / span 5;
position: relative;
.sidebar-desc {
position: sticky;
left: 0;
}
}
}
</style>

View File

@@ -0,0 +1,32 @@
---
layout: partner
title: Prompt ChatGPT
description: Send text prompts to OpenAI GPT-3.5 and receive text generations
date: 2024-07-30
featured: true
isPartner: true
isNew: true
cover: /images/integrations/ai-openai/cover.png
category: ai
product:
avatar: '/images/integrations/avatars/openai.png'
vendor: OpenAI
description: 'The OpenAI API allows you to integrate advanced AI models into your app.'
platform:
- 'Self-hosted'
- 'Cloud'
images:
- /images/integrations/ai-openai/cover.png
- /images/integrations/ai-openai/api-key.png
- /images/integrations/ai-openai/template.png
- /images/integrations/ai-openai/variables.png
- /images/integrations/ai-openai/demo.png
---
# Overview
When creating products, accessibility can be an afterthought. Understandably, we want to ship our products fast and deliver value to our users. We might think that accessibility is needed for edge cases and therefore not prioritize it. Its good to be reminded that the World Health Organization (WHO) estimates that 16% of the global population has some form of disability (Dec 2022).
# Services
Ignoring such a significant part of your user base simply doesnt create a good user experience.Creating accessible products is everyones responsibility. Designers, developers, content authors, and whoever else is involved in creating products should do their part and strive towards achieving a better experience for everyone.

View File

@@ -1,13 +1,13 @@
<script lang="ts">
import { Main } from '$lib/layouts';
import { DEFAULT_DESCRIPTION, DEFAULT_HOST } from '$lib/utils/metadata';
import { DEFAULT_HOST } from '$lib/utils/metadata';
import { TITLE_SUFFIX } from '$routes/titles';
import FooterNav from '$lib/components/FooterNav.svelte';
import MainFooter from '$lib/components/MainFooter.svelte';
import { type ResultType, Fuse } from '$lib/integrations';
import { writable } from 'svelte/store';
import { autoHash } from '$lib/actions/autoHash';
import type { Integration } from './+page';
import type { Partner } from './+page';
import { goto } from '$app/navigation';
import { onDestroy, onMount } from 'svelte';
import { browser } from '$app/environment';
@@ -31,7 +31,7 @@
distance: 500
};
let result: ResultType<Integration> = [];
let result: ResultType<Partner> = [];
let hasQuery: boolean;
let query = writable(decodeURIComponent($page.url.searchParams.get('search') ?? ''));

View File

@@ -3,7 +3,7 @@ import { groupBy } from 'remeda';
import type { IntegrationCategory } from '$lib/constants';
import { integrationCategoryDescriptions as categoryDescriptions } from '$lib/constants';
export type Integration = {
export type Partner = {
title: string;
description: string;
featured?: boolean;
@@ -12,13 +12,13 @@ export type Integration = {
isPartner?: boolean;
platform: string[];
category: string;
product: {
avatar: string;
vendor: string;
description: string;
};
frameworks: string[];
href: string;
images: string[];
product: {
vendor: string;
avatar: string;
href: string;
};
};
export const load = () => {
@@ -31,7 +31,7 @@ export const load = () => {
const integrations = Object.entries(integrationsGlob).map(([filepath, integrationList]) => {
const { frontmatter } = integrationList as {
frontmatter: Integration;
frontmatter: Partner;
};
const slug = filepath.replace('./', '').replace('/+page.markdoc', '');

View File

@@ -21,6 +21,7 @@ const config = {
article: absolute('./src/markdoc/layouts/Article.svelte'),
tutorial: absolute('./src/markdoc/layouts/Tutorial.svelte'),
post: absolute('./src/markdoc/layouts/Post.svelte'),
partner: absolute('./src/markdoc/layouts/Partner.svelte'),
author: absolute('./src/markdoc/layouts/Author.svelte'),
category: absolute('./src/markdoc/layouts/Category.svelte'),
policy: absolute('./src/markdoc/layouts/Policy.svelte'),