Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Bulk reformats. `git config blame.ignoreRevsFile .git-blame-ignore-revs`
6e3cbb357b6cccf73052848bcae815bcb9c057d7 # prettier, 759 files
6 changes: 3 additions & 3 deletions .github/workflows/auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ name: Auto-merge

on:
workflow_run:
workflows: ['CI']
workflows: ["CI"]
types: [completed]
schedule:
- cron: '*/10 * * * *'
- cron: "*/10 * * * *"
workflow_dispatch: {}

# Declared on the CALLER as well as inside the reusable workflow: a called
Expand All @@ -46,4 +46,4 @@ jobs:
# SPACE-separated: the sweep word-splits this. A comma would become one
# bogus token, every dispatch would fail, and the only symptom would be
# that nothing deploys — while the sweep still reported success.
rearm_workflows: 'ci.yml deploy.yml'
rearm_workflows: "ci.yml deploy.yml"
22 changes: 11 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@ on:
push:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- '.vscode/**'
- "**.md"
- "docs/**"
- "LICENSE"
- ".vscode/**"
pull_request:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- 'LICENSE'
- '.vscode/**'
- "**.md"
- "docs/**"
- "LICENSE"
- ".vscode/**"

# Cancel in-progress runs on new pushes to the same PR
concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
NODE_VERSION: '20'
PNPM_VERSION: '9'
NODE_VERSION: "20"
PNPM_VERSION: "9"

jobs:
ci:
Expand All @@ -40,7 +40,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile
Expand Down
21 changes: 21 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Build output and vendored trees — formatting these is noise.
node_modules
.next
dist
build
out
coverage
.turbo
.vercel
*.min.js
*.min.css

# Lockfiles are generated; prettier would rewrite them wholesale.
package-lock.json
pnpm-lock.yaml
yarn.lock

# Markdown is deliberately out of scope for now. Prettier rewraps prose, which
# is where it is most opinionated and least useful, and it would bury the real
# diff. Remove this line when you want docs formatted too.
*.md
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"semi": true,
"singleQuote": false,
"printWidth": 100,
"tabWidth": 2,
"trailingComma": "all",
"arrowParens": "always",
"endOfLine": "lf"
}
4 changes: 1 addition & 3 deletions apps/web/app/(auth)/error.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ export default function AuthError({
<AlertTriangle className="h-8 w-8 text-destructive" />
</div>
<h2 className="mt-4 text-xl font-semibold">{t("errorTitle")}</h2>
<p className="mt-2 max-w-md text-sm text-muted-foreground">
{t("errorDescription")}
</p>
<p className="mt-2 max-w-md text-sm text-muted-foreground">{t("errorDescription")}</p>
<div className="mt-6 flex gap-3">
<button
onClick={reset}
Expand Down
27 changes: 6 additions & 21 deletions apps/web/app/(auth)/forgot-password/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,8 @@ function ForgotPasswordForm() {
<div className="mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-success/10">
<Mail className="h-6 w-6 text-success" />
</div>
<h1 className="mb-2 text-2xl font-semibold">
{t("checkYourEmail")}
</h1>
<p className="mb-6 text-muted-foreground">
{t("resetEmailSent")}
</p>
<h1 className="mb-2 text-2xl font-semibold">{t("checkYourEmail")}</h1>
<p className="mb-6 text-muted-foreground">{t("resetEmailSent")}</p>
<Link
href="/login"
className="flex min-h-[44px] items-center justify-center gap-2 rounded-lg border bg-background py-2.5 text-sm font-medium shadow-sm hover:bg-muted"
Expand All @@ -77,20 +73,12 @@ function ForgotPasswordForm() {
</>
) : (
<>
<h1 className="mb-2 text-2xl font-semibold">
{t("resetPassword")}
</h1>
<p className="mb-6 text-muted-foreground">
{t("resetPasswordSubtitle")}
</p>
<h1 className="mb-2 text-2xl font-semibold">{t("resetPassword")}</h1>
<p className="mb-6 text-muted-foreground">{t("resetPasswordSubtitle")}</p>

{error && (
<div className="mb-4 flex items-center gap-2 rounded-lg bg-destructive/10 p-3 text-sm text-destructive">
<svg
className="h-4 w-4 shrink-0"
viewBox="0 0 16 16"
fill="currentColor"
>
<svg className="h-4 w-4 shrink-0" viewBox="0 0 16 16" fill="currentColor">
<path
fillRule="evenodd"
d="M8 15A7 7 0 108 1a7 7 0 000 14zM8 4a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 018 4zm0 8a1 1 0 100-2 1 1 0 000 2z"
Expand All @@ -102,10 +90,7 @@ function ForgotPasswordForm() {

<form onSubmit={handleSubmit} className="space-y-5">
<div>
<label
htmlFor="email"
className="mb-1.5 block text-sm font-medium"
>
<label htmlFor="email" className="mb-1.5 block text-sm font-medium">
{t("emailAddress")}
</label>
<input
Expand Down
43 changes: 9 additions & 34 deletions apps/web/app/(auth)/invite/[token]/invite-register-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,7 @@ interface InviteRegisterFormProps {
invitationEmail: string | undefined;
error: string;
isPending: boolean;
onSubmit: (form: {
name: string;
email: string;
password: string;
}) => Promise<void>;
onSubmit: (form: { name: string; email: string; password: string }) => Promise<void>;
onBack: () => void;
}

Expand Down Expand Up @@ -51,67 +47,50 @@ export function InviteRegisterForm({
</div>

{error && (
<div className="rounded-lg bg-destructive/10 p-3 text-sm text-destructive">
{error}
</div>
<div className="rounded-lg bg-destructive/10 p-3 text-sm text-destructive">{error}</div>
)}

<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label
htmlFor="reg-name"
className="mb-1.5 block text-sm font-medium"
>
<label htmlFor="reg-name" className="mb-1.5 block text-sm font-medium">
{t("fullName")}
</label>
<input
id="reg-name"
type="text"
value={form.name}
onChange={(e) =>
setForm((p) => ({ ...p, name: e.target.value }))
}
onChange={(e) => setForm((p) => ({ ...p, name: e.target.value }))}
required
autoComplete="name"
className="w-full rounded-lg border bg-background px-4 py-2.5 text-sm focus:border-primary focus:outline-none focus:ring-2 focus:ring-ring/20"
/>
</div>

<div>
<label
htmlFor="reg-email"
className="mb-1.5 block text-sm font-medium"
>
<label htmlFor="reg-email" className="mb-1.5 block text-sm font-medium">
{t("email")}
</label>
<input
id="reg-email"
type="email"
value={form.email}
onChange={(e) =>
setForm((p) => ({ ...p, email: e.target.value }))
}
onChange={(e) => setForm((p) => ({ ...p, email: e.target.value }))}
required
autoComplete="email"
className="w-full rounded-lg border bg-background px-4 py-2.5 text-sm focus:border-primary focus:outline-none focus:ring-2 focus:ring-ring/20"
/>
</div>

<div>
<label
htmlFor="reg-password"
className="mb-1.5 block text-sm font-medium"
>
<label htmlFor="reg-password" className="mb-1.5 block text-sm font-medium">
{t("password")}
</label>
<div className="relative">
<input
id="reg-password"
type={showPassword ? "text" : "password"}
value={form.password}
onChange={(e) =>
setForm((p) => ({ ...p, password: e.target.value }))
}
onChange={(e) => setForm((p) => ({ ...p, password: e.target.value }))}
required
minLength={8}
autoComplete="new-password"
Expand All @@ -123,11 +102,7 @@ export function InviteRegisterForm({
tabIndex={-1}
className="absolute right-3 top-1/2 -translate-y-1/2 text-muted-foreground hover:text-foreground"
>
{showPassword ? (
<EyeOff className="h-4 w-4" />
) : (
<Eye className="h-4 w-4" />
)}
{showPassword ? <EyeOff className="h-4 w-4" /> : <Eye className="h-4 w-4" />}
</button>
</div>
</div>
Expand Down
23 changes: 5 additions & 18 deletions apps/web/app/(auth)/invite/[token]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ import { useRouter } from "next/navigation";
import Link from "next/link";
import { Loader2, Building2, CheckCircle2, XCircle, Clock } from "lucide-react";
import { useTranslations } from "next-intl";
import {
getInvitationDetailsAction,
acceptInvitationAction,
} from "@/app/actions/invitations";
import { getInvitationDetailsAction, acceptInvitationAction } from "@/app/actions/invitations";
import { registerAndAcceptInviteAction } from "@/app/actions/auth";
import type { InvitationWithCompany } from "@kivvi/core/src/domain/invitations";
import { InviteRegisterForm } from "./invite-register-form";
Expand All @@ -20,18 +17,12 @@ interface InvitePageProps {

export default function InvitePage({ params }: InvitePageProps) {
const { token } = params;
const {
data: session,
status: sessionStatus,
update: updateSession,
} = useSession();
const { data: session, status: sessionStatus, update: updateSession } = useSession();
const router = useRouter();
const t = useTranslations("team");
const tc = useTranslations("common");

const [invitation, setInvitation] = useState<InvitationWithCompany | null>(
null,
);
const [invitation, setInvitation] = useState<InvitationWithCompany | null>(null);
const [loading, setLoading] = useState(true);
const [accepting, setAccepting] = useState(false);
const [error, setError] = useState("");
Expand Down Expand Up @@ -221,17 +212,13 @@ export default function InvitePage({ params }: InvitePageProps) {
</p>
<p className="mt-1 text-sm text-muted-foreground">
{t("roleAssignment", {
role: invitation
? tc(`permissionPresetLabel.${invitation.permissionPreset}`)
: "",
role: invitation ? tc(`permissionPresetLabel.${invitation.permissionPreset}`) : "",
})}
</p>
</div>

{error && (
<div className="rounded-lg bg-destructive/10 p-3 text-sm text-destructive">
{error}
</div>
<div className="rounded-lg bg-destructive/10 p-3 text-sm text-destructive">{error}</div>
)}

<button
Expand Down
Loading
Loading