Skip to content

Commit 578c564

Browse files
committed
Merge branch 'stripe'
2 parents 68e929d + bebd96e commit 578c564

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1531
-527
lines changed

Dockerfile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ ARG DATABASE_URL
44
ARG GOOGLE_OAUTH_CLIENT_ID
55
ARG GOOGLE_OAUTH_CLIENT_SECRET
66
ARG GOOGLE_OAUTH_CALLBACK_URL
7+
ARG STRIPE_SECRET_KEY
8+
ARG STRIPE_WEBHOOK_SECRET
9+
ARG STRIPE_INDIE_HACKER_PLAN_PRICE_ID
10+
ARG DOMAIN
11+
712
RUN mkdir /app
813

914
COPY . /app

package-lock.json

Lines changed: 357 additions & 111 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,18 @@
1616
"@sveltejs/adapter-node": "^5.2.1",
1717
"@sveltejs/kit": "^2.5.27",
1818
"@sveltejs/vite-plugin-svelte": "^4.0.0",
19+
"@tailwindcss/container-queries": "^0.1.1",
1920
"@tailwindcss/typography": "^0.5.15",
2021
"@types/eslint": "^9.6.0",
2122
"@types/gtag.js": "^0.0.20",
2223
"@types/node": "^22.5.4",
2324
"autoprefixer": "^10.4.20",
24-
"bits-ui": "^1.0.0-next.77",
25+
"bits-ui": "^1.0.0-next.78",
2526
"clsx": "^2.1.1",
2627
"embla-carousel-svelte": "^8.3.1",
27-
"eslint": "^9.0.0",
28+
"eslint": "^9.18.0",
2829
"eslint-config-prettier": "^9.1.0",
29-
"eslint-plugin-svelte": "^2.45.1",
30+
"eslint-plugin-svelte": "^2.46.1",
3031
"globals": "^15.0.0",
3132
"lucide-svelte": "^0.452.0",
3233
"prettier": "^3.1.1",
@@ -40,18 +41,20 @@
4041
"tailwindcss": "^3.4.9",
4142
"tailwindcss-animate": "^1.0.7",
4243
"typescript": "^5.5.0",
43-
"typescript-eslint": "^8.0.0",
44+
"typescript-eslint": "^8.20.0",
4445
"vite": "^5.4.4"
4546
},
4647
"type": "module",
4748
"dependencies": {
4849
"@oslojs/crypto": "^1.0.1",
4950
"@oslojs/encoding": "^1.1.0",
5051
"@prisma/client": "^6.1.0",
52+
"@types/stripe-v3": "^3.1.33",
5153
"@yizy/spec": "npm:@jsr/yizy__spec@^0.0.1",
5254
"arctic": "^2.3.3",
5355
"handlebars": "^4.7.8",
5456
"mode-watcher": "^0.4.1",
57+
"stripe": "^17.5.0",
5558
"svelte-highlight": "^7.7.0",
5659
"swapy": "^0.4.2",
5760
"uuid": "^11.0.3",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-- CreateTable
2+
CREATE TABLE "StripeSubscription" (
3+
"id" SERIAL NOT NULL,
4+
"uuid" TEXT NOT NULL,
5+
"userId" INTEGER NOT NULL,
6+
"active" BOOLEAN NOT NULL,
7+
"stripeId" TEXT NOT NULL,
8+
"stripeSubscriptionId" TEXT NOT NULL,
9+
10+
CONSTRAINT "StripeSubscription_pkey" PRIMARY KEY ("id")
11+
);
12+
13+
-- AddForeignKey
14+
ALTER TABLE "StripeSubscription" ADD CONSTRAINT "StripeSubscription_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

prisma/schema.prisma

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ model User {
2525
Workspaces BridgeWorkspaceAndUser[]
2626
Workspace Workspace[]
2727
Specification Specification[]
28+
Subscription StripeSubscription[]
2829
}
2930

3031
model Workspace {
@@ -85,3 +86,13 @@ model SpecificationSnapshot {
8586
creatorId Int
8687
createdBy User @relation(references: [id], fields: [creatorId], onDelete: Cascade)
8788
}
89+
90+
model StripeSubscription {
91+
id Int @id @default(autoincrement())
92+
uuid String
93+
userId Int
94+
user User @relation(references: [id], fields: [userId])
95+
active Boolean
96+
stripeId String
97+
stripeSubscriptionId String
98+
}

src/app.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
div::-webkit-scrollbar {
5151
width: 6px;
52+
height: 6px;
5253
}
5354

5455
div::-webkit-scrollbar-track {
@@ -65,6 +66,7 @@ div::-webkit-scrollbar-corner {
6566

6667
textarea::-webkit-scrollbar {
6768
width: 6px;
69+
height: 6px;
6870
}
6971

7072
textarea::-webkit-scrollbar-track {

src/app.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// See https://kit.svelte.dev/docs/types#app
2-
import type { SessionValidationResult } from "$lib/server/services/data/dbService";
2+
import type { SessionValidationResult } from "$lib/server/services/data/db/dbService";
33

44
// for information about these interfaces
55
declare global {

src/hooks.server.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { dev } from "$app/environment";
2-
import { validateSessionToken } from "$lib/server/services/data/dbService";
2+
import { validateSessionToken } from "$lib/server/services/data/db/dbService";
33
import { type Handle, json, type RequestEvent } from "@sveltejs/kit";
44

55
export function setSessionTokenCookie(
@@ -46,7 +46,16 @@ function isApiRoute(url: string) {
4646
return url.toString().includes("/api") &&
4747
!url.toString().includes("/api/auth");
4848
}
49+
50+
function isStripeWebhook(url: string) {
51+
return url.toString().includes("/api/stripe/webhook");
52+
}
53+
4954
export const handle: Handle = async ({ event, resolve }) => {
55+
if (isStripeWebhook(event.url.toString())) {
56+
return resolve(event);
57+
}
58+
5059
const url = event.url.toString();
5160
const token = event.cookies.get("sessionToken") ?? null;
5261
if (token === null) {

src/lib/components/ui/Navbar.svelte

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,20 @@
66
import YizyLogo from './YIZYLogo.svelte';
77
import Button from './button/button.svelte';
88
import { User } from 'lucide-svelte';
9-
import * as localStorageService from '$lib/localStorageService';
109
import { onMount } from 'svelte';
1110
12-
let { onOpenSidebarBtnClicked }: { onOpenSidebarBtnClicked?: () => void } = $props();
11+
let {
12+
isUserLoggedIn,
13+
userHasActiveSubscription,
14+
onOpenSidebarBtnClicked
15+
}: {
16+
isUserLoggedIn: boolean;
17+
userHasActiveSubscription: boolean;
18+
onOpenSidebarBtnClicked?: () => void;
19+
} = $props();
1320
14-
let isLoggedIn = $state(false);
1521
let isMounted = $state(false);
1622
onMount(() => {
17-
isLoggedIn = localStorageService.getIsLoggedIn();
1823
isMounted = true;
1924
});
2025
@@ -38,22 +43,25 @@
3843
class="mx-2 my-auto hidden text-sm font-bold hover:text-primary sm:mx-4 sm:text-lg md:block"
3944
>Home</a>
4045

41-
<a
42-
href="/demo"
43-
class="mx-2 my-auto hidden text-center text-sm font-bold hover:text-primary sm:mx-4 sm:text-left sm:text-lg md:block"
44-
>Demo</a>
45-
4646
<a
4747
href="/doc/introduction"
4848
class="mx-2 my-auto hidden text-center text-sm font-bold hover:text-primary sm:mx-4 sm:text-left sm:text-lg md:block"
4949
>Documentation</a>
5050

51-
{#if !isLoggedIn && isMounted}
51+
{#if !isUserLoggedIn && isMounted}
5252
<a
5353
href="/login"
5454
class="mx-2 my-auto hidden text-center text-sm font-bold hover:text-primary sm:mx-4 sm:text-left sm:text-lg md:block"
5555
>Login</a>
5656
{/if}
57+
58+
{#if userHasActiveSubscription}
59+
<a
60+
href="/app"
61+
class="mx-2 my-auto hidden text-center text-sm font-bold hover:text-primary sm:mx-4 sm:text-left sm:text-lg md:block">
62+
App
63+
</a>
64+
{/if}
5765
<div class="ml-4 flex h-full">
5866
<a
5967
href="https://github.com/YIZY-API/yizy-web-app"
@@ -66,7 +74,7 @@
6674
<div class="my-auto ml-2 hidden md:block">
6775
<DarkModeToggle />
6876
</div>
69-
{#if isLoggedIn && isMounted}
77+
{#if isUserLoggedIn && isMounted}
7078
<DropdownMenu.Root>
7179
<DropdownMenu.Trigger>
7280
<div class="my-auto ml-2 hidden md:block">
@@ -81,14 +89,21 @@
8189
<DropdownMenu.Separator />
8290
<DropdownMenu.Item>
8391
<button
84-
class="bg-transparent"
92+
class="bg-transparent outline-none"
8593
onclick={() => {
86-
localStorageService.setClientSideLogoutState();
8794
window.location.href = '/api/auth/logout';
8895
}}>
8996
Log out
9097
</button>
9198
</DropdownMenu.Item>
99+
100+
{#if userHasActiveSubscription}
101+
<DropdownMenu.Item>
102+
<form action="/api/stripe/createPortalSession" method="POST">
103+
<button class="bg-transparent" type="submit"> Billing </button>
104+
</form>
105+
</DropdownMenu.Item>
106+
{/if}
92107
</DropdownMenu.Group>
93108
</DropdownMenu.Content>
94109
</DropdownMenu.Root>

src/lib/components/ui/ProgrammingLanguagesDropdown.svelte

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@
2727
if (val != '') {
2828
lang = convertStringToProgrammingLanguage(val);
2929
}
30-
}}
31-
controlledValue={true}>
30+
}}>
3231
<Select.Trigger class="mt-2 w-[300px]">{triggerContent}</Select.Trigger>
3332
<Select.Content>
3433
<Select.Group>

0 commit comments

Comments
 (0)