Skip to content

Commit 4e8665d

Browse files
Merge pull request #1946 from appwrite/partners-catalog
2 parents 7418a13 + d4cf745 commit 4e8665d

31 files changed

+1363
-6
lines changed

src/lib/constants.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ export type SocialShareOption = {
5959
type: 'link' | 'copy';
6060
};
6161

62-
export type IntegrationCategory = {
62+
export type SearchableCategory = {
6363
slug: string;
6464
heading: string;
6565
description: string;
6666
};
6767

68-
export const integrationCategoryDescriptions: IntegrationCategory[] = [
68+
export const integrationCategoryDescriptions: SearchableCategory[] = [
6969
{
7070
slug: 'ai',
7171
heading: 'AI',
@@ -118,6 +118,14 @@ export const integrationCategoryDescriptions: IntegrationCategory[] = [
118118
}
119119
];
120120

121+
export const partnerCategoryDescriptions: SearchableCategory[] = [
122+
{
123+
slug: 'agency',
124+
heading: 'Agency',
125+
description: 'Agencies that build software for their clients using Appwrite'
126+
}
127+
];
128+
121129
export const socialSharingOptions: Array<SocialShareOption> = [
122130
{
123131
icon: 'web-icon-x',

src/markdoc/layouts/Partner.svelte

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
<script lang="ts">
2+
import FooterNav from '$lib/components/FooterNav.svelte';
3+
import MainFooter from '$lib/components/MainFooter.svelte';
4+
import { Main } from '$lib/layouts';
5+
import { DEFAULT_HOST } from '$lib/utils/metadata';
6+
7+
import { classNames } from '$lib/utils/classnames';
8+
import type { Partner } from '$routes/partners/catalog/+page';
9+
import ContactPartner from '$routes/partners/catalog/(components)/contact-partner.svelte';
10+
11+
export let title: Partner['title'];
12+
export let partnerLevel: Partner['partnerLevel'];
13+
export let category: Partner['category'];
14+
export let description: Partner['description'];
15+
export let cover: Partner['cover'];
16+
export let capabilities: Partner['capabilities'];
17+
export let frameworks: Partner['frameworks'];
18+
export let regions: Partner['regions'];
19+
export let languages: Partner['languages'];
20+
export let website: Partner['website'];
21+
22+
const ogImage = DEFAULT_HOST + cover;
23+
</script>
24+
25+
<svelte:head>
26+
<!-- Titles -->
27+
<title>{title}</title>
28+
<meta property="og:title" content={title} />
29+
<meta name="twitter:title" content={title} />
30+
<!-- Description -->
31+
<meta name="description" content={description} />
32+
<meta property="og:description" content={description} />
33+
<meta name="twitter:description" content={description} />
34+
<!-- Image -->
35+
<meta property="og:image" content={ogImage} />
36+
<meta property="og:image:width" content="1200" />
37+
<meta property="og:image:height" content="630" />
38+
<meta name="twitter:image" content={ogImage} />
39+
<meta name="twitter:card" content="summary_large_image" />
40+
</svelte:head>
41+
42+
<Main>
43+
<div
44+
class={classNames(
45+
'grid-bg border-smooth relative flex items-center border-b px-5 py-28 lg:px-8 xl:px-16',
46+
'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'
47+
)}
48+
>
49+
<div class="relative container w-full pb-0">
50+
<div class="flex flex-col gap-7">
51+
<a href="/partners" class="text-caption text-primary group flex gap-2">
52+
<span class="web-icon-arrow-left transition group-hover:-translate-x-1" />
53+
Back to Partners Catalog
54+
</a>
55+
<h1 class="text-headline font-aeonik-pro text-primary">{title}</h1>
56+
</div>
57+
</div>
58+
</div>
59+
60+
<div class="py-10">
61+
<div class="container">
62+
<article class="flex flex-col gap-10 md:gap-14">
63+
<div class="grid grid-cols-1 gap-10 md:grid-cols-12 md:gap-x-14">
64+
<div class="md:col-span-7">
65+
<div class="web-article">
66+
<div class="web-article-content">
67+
<slot />
68+
</div>
69+
<ContactPartner />
70+
</div>
71+
</div>
72+
<div class="md:col-span-5">
73+
<h2 class="text-label text-primary font-aeonik-pro">About {title}</h2>
74+
<dl class="divide-smooth sticky top-32 mt-10 flex flex-col gap-7 divide-y">
75+
<div class="flex flex-col justify-between gap-7 pb-7">
76+
<dt class="text-micro font-aeonik-fono tracking-loose uppercase">
77+
Frameworks
78+
</dt>
79+
<dd class="flex flex-wrap gap-2">
80+
{#each frameworks as framework}
81+
<div
82+
class="text-primary text-caption bg-smooth rounded-full px-3 py-1"
83+
>
84+
{framework}
85+
</div>
86+
{/each}
87+
</dd>
88+
</div>
89+
90+
<div class="flex flex-col justify-between gap-7 pb-7">
91+
<dt class="text-micro font-aeonik-fono tracking-loose uppercase">
92+
Capabilities
93+
</dt>
94+
<dd class="flex flex-wrap gap-2">
95+
{#each capabilities as capability}
96+
<div
97+
class="text-primary text-caption bg-smooth rounded-full px-3 py-1"
98+
>
99+
{capability}
100+
</div>
101+
{/each}
102+
</dd>
103+
</div>
104+
105+
<div class="flex items-center justify-between gap-7 pb-7">
106+
<dt class="text-micro font-aeonik-fono tracking-loose uppercase">
107+
Category
108+
</dt>
109+
<dd class="text-primary text-caption">{category}</dd>
110+
</div>
111+
112+
<div class="flex items-center justify-between gap-7 pb-7">
113+
<dt class="text-micro font-aeonik-fono tracking-loose uppercase">
114+
Website
115+
</dt>
116+
<dd
117+
class="text-primary text-caption font-medium underline underline-offset-4"
118+
>
119+
{website}
120+
</dd>
121+
</div>
122+
123+
<div class="flex items-center justify-between gap-7 pb-7">
124+
<dt class="text-micro font-aeonik-fono tracking-loose uppercase">
125+
Partner Level
126+
</dt>
127+
<dd>
128+
<div
129+
class="text-primary text-caption rounded bg-white/24 px-2 py-0.5"
130+
>
131+
{partnerLevel}
132+
</div>
133+
</dd>
134+
</div>
135+
136+
<div class="flex items-center justify-between gap-8 pb-7">
137+
<dt class="text-micro font-aeonik-fono tracking-loose uppercase">
138+
Regions
139+
</dt>
140+
<dd class="text-primary text-caption">
141+
{regions.join(', ')}
142+
</dd>
143+
</div>
144+
145+
<div class="flex flex-col justify-between gap-7 pb-7">
146+
<dt class="text-micro font-aeonik-fono tracking-loose uppercase">
147+
Languages
148+
</dt>
149+
<dd class="flex flex-wrap gap-2">
150+
{#each languages as language}
151+
<div
152+
class="text-primary text-caption bg-smooth rounded-full px-3 py-1"
153+
>
154+
{language}
155+
</div>
156+
{/each}
157+
</dd>
158+
</div>
159+
</dl>
160+
</div>
161+
</div>
162+
</article>
163+
</div>
164+
</div>
165+
166+
<div class="mt-12 overflow-hidden py-10">
167+
<div class="container">
168+
<FooterNav />
169+
<MainFooter />
170+
</div>
171+
</div>
172+
</Main>

src/routes/integrations/+page.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { base } from '$app/paths';
22
import { groupBy } from 'remeda';
3-
import type { IntegrationCategory } from '$lib/constants';
4-
import { integrationCategoryDescriptions as categoryDescriptions } from '$lib/constants';
3+
import type { SearchableCategory } from '$lib/constants';
4+
import { partnerCategoryDescriptions as categoryDescriptions } from '$lib/constants';
55

66
export type Integration = {
77
title: string;
@@ -26,7 +26,7 @@ export const load = () => {
2626
eager: true
2727
});
2828

29-
const categories: IntegrationCategory[] = [];
29+
const categories: SearchableCategory[] = [];
3030
const platforms: string[] = [];
3131

3232
const integrations = Object.entries(integrationsGlob).map(([filepath, integrationList]) => {
@@ -40,7 +40,7 @@ export const load = () => {
4040
frontmatter.platform.map((platform) => platforms.push(platform));
4141
categories.push(
4242
categoryDescriptions.find((i) => i.slug === frontmatter.category) ??
43-
({} as IntegrationCategory)
43+
({} as SearchableCategory)
4444
);
4545

4646
return {
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<script lang="ts">
2+
import { classNames } from '$lib/utils/classnames';
3+
</script>
4+
5+
<div
6+
class={classNames(
7+
'border-smooth relative -mb-24 border-t py-32',
8+
'bg-[url("/images/bgs/building-blocks.webp")] [background-size:50%] bg-right-bottom bg-no-repeat',
9+
'before:absolute before:top-0 before:left-0 before:z-0 before:block before:h-80 before:w-full before:bg-[radial-gradient(at_25%_0%,_hsla(343,_98%,_60%,_0.05)_0px,_transparent_73%,_transparent_100%)] md:before:w-1/2',
10+
'after:absolute after:top-0 after:right-0 after:z-0 after:hidden after:h-80 after:w-1/2 after:bg-[radial-gradient(at_100%_0%,_hsla(177,_53%,_69%,_0.1)_0px,_transparent_73%,_transparent_100%)] after:md:block md:after:block'
11+
)}
12+
>
13+
<div class="relative container grid grid-cols-1 place-items-center md:grid-cols-2">
14+
<section class="flex flex-col gap-4">
15+
<h2 class="text-display font-aeonik-pro text-primary max-w-[600px]">
16+
Become a Technology Partner
17+
</h2>
18+
<p class="text-body font-medium">
19+
Join our Technology Partners program to integrate your solutions with Appwrite’s
20+
API, enhancing functionality and expanding your reach.
21+
</p>
22+
<a href="/integrations/technology-partner" class="web-button mt-4">
23+
<span class="text">Get Started</span>
24+
</a>
25+
</section>
26+
</div>
27+
</div>

0 commit comments

Comments
 (0)