Skip to content

Commit

Permalink
Merge pull request #21 from Saasfy/infra
Browse files Browse the repository at this point in the history
Infra
  • Loading branch information
IKatsuba authored Apr 20, 2024
2 parents c253f95 + c18c7e8 commit b1e65d4
Show file tree
Hide file tree
Showing 121 changed files with 3,602 additions and 415 deletions.
4 changes: 4 additions & 0 deletions .husky/commit-msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx --no -- commitlint --edit ${1}
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged --concurrent false --relative
16 changes: 16 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,21 @@
"proseWrap": "always"
}
}
],
"plugins": [
"prettier-plugin-packagejson",
"prettier-plugin-tailwindcss",
"@ianvs/prettier-plugin-sort-imports"
],
"importOrder": [
"^react$",
"next",
"",
"<BUILTIN_MODULES>",
"<THIRD_PARTY_MODULES>",
"",
"^@(saasfy)/(.*)$",
"",
"^[./]"
]
}
7 changes: 4 additions & 3 deletions apps/web/app/admin/(auth)/signin/[view]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { getUser } from '@saasfy/supabase/server';
import { redirect } from 'next/navigation';

import { getUser } from '@saasfy/supabase/server';

import { SignInForm } from '../../../../app/(auth)/signin/[view]/signin-form';
import * as process from 'process';

export default async function SignInViews() {
const user = await getUser();
Expand All @@ -11,7 +12,7 @@ export default async function SignInViews() {
}

return (
<div className="flex justify-center min-h-screen items-center">
<div className="flex min-h-screen items-center justify-center">
<SignInForm view="signin" />
</div>
);
Expand Down
9 changes: 6 additions & 3 deletions apps/web/app/admin/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { ReactNode } from 'react';
import Link from 'next/link';
import { redirect } from 'next/navigation';

import { CloudyIcon } from 'lucide-react';

import { getUser } from '@saasfy/supabase/server';
import { redirect } from 'next/navigation';
import { ReactNode } from 'react';

import DashboardNav from './nav';

export default async function Component({ children }: { children: ReactNode }) {
Expand All @@ -14,7 +17,7 @@ export default async function Component({ children }: { children: ReactNode }) {

if (user.email !== process.env.SAASFY_ADMIN_EMAIL) {
return (
<div className="flex justify-center min-h-screen items-center">
<div className="flex min-h-screen items-center justify-center">
<h1 className="text-2xl font-semibold">You are not authorized to access this page.</h1>
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/admin/(dashboard)/nav.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use client';

import Link from 'next/link';
import { PackageIcon } from 'lucide-react';
import { usePathname } from 'next/navigation';

import { PackageIcon } from 'lucide-react';

export default function DashboardNav() {
const path = usePathname();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use client';

import { Slot } from '@radix-ui/react-slot';
import React from 'react';
import { useRouter } from 'next/navigation';

import { Slot } from '@radix-ui/react-slot';

export function DeletePlanButton({ id, children }: { id: string; children: React.ReactNode }) {
const router = useRouter();

Expand Down
6 changes: 4 additions & 2 deletions apps/web/app/admin/(dashboard)/plans/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { UserCircleIcon } from 'lucide-react';
import React, { ReactNode } from 'react';

import { UserCircleIcon } from 'lucide-react';

import { AccountMenu } from '@saasfy/components';
import { Button } from '@saasfy/ui/button';

export default async function Component({ children }: { children: ReactNode }) {
return (
<>
<header className="flex h-14 lg:h-[60px] items-center gap-4 border-b bg-gray-100/40 px-6 dark:bg-gray-800/40">
<header className="flex h-14 items-center gap-4 border-b bg-gray-100/40 px-6 lg:h-[60px] dark:bg-gray-800/40">
<div className="w-full flex-1"></div>
<AccountMenu>
<Button className="rounded-full" size="icon" variant="secondary">
Expand Down
14 changes: 8 additions & 6 deletions apps/web/app/admin/(dashboard)/plans/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Button } from '@saasfy/ui/button';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@saasfy/ui/table';
import { createAdminClient } from '@saasfy/supabase/server';
import React from 'react';
import Link from 'next/link';

import { createAdminClient } from '@saasfy/supabase/server';
import { Button } from '@saasfy/ui/button';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@saasfy/ui/table';

import { DeletePlanButton } from './_components/delete-plan-button';

export default async function Component() {
Expand All @@ -16,15 +18,15 @@ export default async function Component() {
return (
<main className="flex flex-1 flex-col gap-4 p-4 md:gap-8 md:p-6">
<div className="flex items-center">
<h1 className="font-semibold text-lg md:text-2xl">Plans</h1>
<h1 className="text-lg font-semibold md:text-2xl">Plans</h1>
{plans?.length ? (
<Button className="ml-auto" size="sm" asChild>
<Link href="/plans/new">Add Plan</Link>
</Button>
) : null}
</div>
{plans?.length ? (
<div className="border shadow-sm rounded-lg">
<div className="rounded-lg border shadow-sm">
<Table>
<TableHeader>
<TableRow>
Expand Down Expand Up @@ -70,7 +72,7 @@ export default async function Component() {
<div className="flex flex-1 items-center justify-center rounded-lg border border-dashed shadow-sm">
<div className="flex flex-col items-center gap-1 text-center">
<h3 className="text-2xl font-bold tracking-tight">You have no plans yet.</h3>
<p className="text-sm text-muted-foreground">
<p className="text-muted-foreground text-sm">
You can start selling as soon as you add a plan.
</p>
<Button className="mt-4" asChild>
Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/api/public/subscriptions/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { stripe } from '@saasfy/stripe/server';
import { z } from 'zod';

import { getUrl } from '@saasfy/api/server';
import { stripe } from '@saasfy/stripe/server';
import { createAdminClient } from '@saasfy/supabase/server';

const FormData = z.object({
Expand Down
7 changes: 4 additions & 3 deletions apps/web/app/api/webhooks/stripe/route.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { stripe } from '@saasfy/stripe/server';
import { Client } from 'pg';
import Stripe from 'stripe';
import { createAdminClient } from '@saasfy/supabase/server';
import { v4 as uuidv4 } from 'uuid';
import { Client } from 'pg';

import { stripe } from '@saasfy/stripe/server';
import { createAdminClient } from '@saasfy/supabase/server';

export async function POST(req: Request) {
if (!process.env.STRIPE_WEBHOOK_SECRET) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { stripe } from '@saasfy/stripe/server';
import { z } from 'zod';

import { getUrl, withWorkspaceOwner } from '@saasfy/api/server';
import { stripe } from '@saasfy/stripe/server';
import { createAdminClient } from '@saasfy/supabase/server';

const FormData = z.object({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { stripe } from '@saasfy/stripe/server';
import { getUrl, withWorkspaceOwner } from '@saasfy/api/server';
import { stripe } from '@saasfy/stripe/server';

export const GET = withWorkspaceOwner(async ({ req, workspace, params }) => {
const session = await stripe.billingPortal.sessions.create({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { withWorkspaceOwner } from '@saasfy/api/server';
import { deleteWorkspace } from '@saasfy/crud/workspaces/server';
import { getWorkspaceUser, updateWorkspaceUser } from '@saasfy/crud/workspace-users/server';
import { deleteWorkspace } from '@saasfy/crud/workspaces/server';

export const PATCH = withWorkspaceOwner<{ id: string }>(
async ({ req, user, workspace, params: { id } }) => {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/api/workspaces/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { withUser } from '@saasfy/api/server';
import { createWorkspace, deleteWorkspace } from '@saasfy/crud/workspaces/server';
import { createWorkspaceUser } from '@saasfy/crud/workspace-users/server';
import { createWorkspace, deleteWorkspace } from '@saasfy/crud/workspaces/server';

export const POST = withUser(async ({ req, user }) => {
const data = await req.json();
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/app/(auth)/auth/callback/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createAuthClient } from '@saasfy/supabase/server';
import { getUrl } from '@saasfy/api/server';
import { createAuthClient } from '@saasfy/supabase/server';

export async function GET(request: Request) {
// The `/auth/callback` route is required for the server-side auth flow implemented
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/app/(auth)/auth/logout/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createAuthClient } from '@saasfy/supabase/server';
import { getUrl } from '@saasfy/api/server';
import { createAuthClient } from '@saasfy/supabase/server';

export async function GET(request: Request) {
const auth = createAuthClient();
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/app/(auth)/auth/reset_password/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createAuthClient } from '@saasfy/supabase/server';
import { getUrl } from '@saasfy/api/server';
import { createAuthClient } from '@saasfy/supabase/server';

export async function GET(request: Request) {
// The `/auth/callback` route is required for the server-side auth flow implemented
Expand Down
8 changes: 5 additions & 3 deletions apps/web/app/app/(auth)/signin/[view]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { SignInForm, type SignInViews } from './signin-form';
import { getUser } from '@saasfy/supabase/server';
import { redirect } from 'next/navigation';

import { getUser } from '@saasfy/supabase/server';

import { SignInForm, type SignInViews } from './signin-form';

const views: SignInViews[] = ['signin', 'signup', 'forgot-password'];

export default async function SignInViews({ params }: { params: { view: SignInViews } }) {
Expand All @@ -18,7 +20,7 @@ export default async function SignInViews({ params }: { params: { view: SignInVi
}

return (
<div className="flex justify-center min-h-screen items-center">
<div className="flex min-h-screen items-center justify-center">
<SignInForm view={view} />
</div>
);
Expand Down
6 changes: 4 additions & 2 deletions apps/web/app/app/(auth)/signin/[view]/signin-actions.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use server';

import { createAuthClient } from '@saasfy/supabase/server';
import { redirect } from 'next/navigation';
import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';

import { z, ZodError } from 'zod';

import { createAuthClient } from '@saasfy/supabase/server';

const LoginSchema = z.object({
email: z.string().email().email('Invalid email'),
password: z.string().min(8, 'Password must be at least 8 characters'),
Expand Down
20 changes: 11 additions & 9 deletions apps/web/app/app/(auth)/signin/[view]/signin-form.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
'use client';

import { useToast } from '@saasfy/ui/use-toast';
import Link from 'next/link';

import { createClient } from '@saasfy/supabase';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@saasfy/ui/card';
import { Button } from '@saasfy/ui/button';
import { forgotPassword, login, signup } from './signin-actions';
import Link from 'next/link';
import { Label } from '@saasfy/ui/label';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@saasfy/ui/card';
import { Input } from '@saasfy/ui/input';
import { Label } from '@saasfy/ui/label';
import { useToast } from '@saasfy/ui/use-toast';

import { forgotPassword, login, signup } from './signin-actions';

export type SignInViews = 'signin' | 'signup' | 'forgot-password';

Expand All @@ -18,7 +20,7 @@ export function SignInForm({ view }: { view: SignInViews }) {

return (
<form>
<Card className="sm:min-w-[30rem] min-w-full">
<Card className="min-w-full sm:min-w-[30rem]">
<CardHeader>
<CardTitle className="text-2xl">
{
Expand Down Expand Up @@ -94,7 +96,7 @@ export function SignInForm({ view }: { view: SignInViews }) {
});
}}
>
<GoogleIcon className="w-6 h-6 mr-2" />
<GoogleIcon className="mr-2 h-6 w-6" />
Google
</Button>

Expand All @@ -111,14 +113,14 @@ export function SignInForm({ view }: { view: SignInViews }) {
});
}}
>
<GithubIcon className="w-6 h-6 mr-2" />
<GithubIcon className="mr-2 h-6 w-6" />
Github
</Button>
</div>
</>
) : null}

<div className="flex flex-col justify-center items-center">
<div className="flex flex-col items-center justify-center">
{
{
signin: (
Expand Down
11 changes: 6 additions & 5 deletions apps/web/app/app/(auth)/signin/check-your-email/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { Button } from '@saasfy/ui/button';
import Link from 'next/link';

import { Button } from '@saasfy/ui/button';

export default function Component() {
return (
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100 dark:bg-gray-800">
<div className="w-full max-w-md p-8 space-y-6 bg-white rounded-lg shadow-md dark:bg-gray-900">
<h1 className="text-3xl font-bold text-center">Check Your Email</h1>
<p className="text-gray-600 dark:text-gray-400 text-center">
<div className="flex min-h-screen flex-col items-center justify-center bg-gray-100 dark:bg-gray-800">
<div className="w-full max-w-md space-y-6 rounded-lg bg-white p-8 shadow-md dark:bg-gray-900">
<h1 className="text-center text-3xl font-bold">Check Your Email</h1>
<p className="text-center text-gray-600 dark:text-gray-400">
We have sent an email with further instructions to reset your password. Please check your
inbox and follow the instructions.
</p>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createAdminClient } from '@saasfy/supabase/server';
import { redirect } from 'next/navigation';

import { createAdminClient } from '@saasfy/supabase/server';

export default async function ProjectPage({ params }: { params: { project: string } }) {
const supabase = createAdminClient();

Expand All @@ -12,7 +13,7 @@ export default async function ProjectPage({ params }: { params: { project: strin

return (
<div className="flex items-center">
<h1 className="font-semibold text-lg md:text-2xl">{projects.at(0)?.name}</h1>
<h1 className="text-lg font-semibold md:text-2xl">{projects.at(0)?.name}</h1>
</div>
);
}
Loading

0 comments on commit b1e65d4

Please sign in to comment.