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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added apps/dashboard/public/login-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion apps/dashboard/src/components/details/detail-sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function DetailParticipantAvatars({
}>;
}) {
return (
<div className="group/participants flex items-center">
<div className="group/participants flex flex-wrap items-center">
{actors.map((actor, index) => (
<Tooltip key={actor.login}>
<TooltipTrigger asChild>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
ChevronDownIcon,
ChevronUpIcon,
CircleIcon,
Delete01Icon,
EditIcon,
GitCommitIcon,
GitMergeIcon,
Expand Down Expand Up @@ -40,6 +41,7 @@ import {
import { LabelPill } from "#/components/details/label-pill";
import { formatRelativeTime } from "#/lib/format-relative-time";
import {
deleteBranch,
dismissPullReview,
getCommentPage,
getTimelineEventPage,
Expand Down Expand Up @@ -160,6 +162,16 @@ export function PullDetailActivitySection({
</div>
)}

{pr.isMerged && (
<div className="mt-6">
<MergedBranchBanner
owner={owner}
repo={repo}
branchName={pr.headRefName}
/>
</div>
)}

<div className="mt-6">
<DetailCommentBox />
</div>
Expand Down Expand Up @@ -199,6 +211,85 @@ function MergeStatusSection({
);
}

function MergedBranchBanner({
owner,
repo,
branchName,
}: {
owner: string;
repo: string;
branchName: string;
}) {
const [isDeleting, setIsDeleting] = useState(false);
const [isDeleted, setIsDeleted] = useState(false);

const handleDelete = async () => {
setIsDeleting(true);
try {
const result = await deleteBranch({
data: { owner, repo, branch: branchName },
});
if (result.ok) {
setIsDeleted(true);
} else {
toast.error(result.error);
checkPermissionWarning(result, `${owner}/${repo}`);
setIsDeleting(false);
}
} catch {
toast.error("Failed to delete branch");
setIsDeleting(false);
}
};

return (
<div className="flex items-center gap-3 rounded-lg bg-purple-500/15 px-4 py-3">
<div className="flex size-5 shrink-0 items-center justify-center rounded-full bg-purple-500 text-white">
<GitMergeIcon size={12} strokeWidth={2} />
</div>
<p className="flex-1 text-sm text-purple-900 dark:text-purple-200">
{isDeleted ? (
<>
Branch{" "}
<code className="rounded bg-purple-500/20 px-1 py-0.5 font-mono text-xs">
{branchName}
</code>{" "}
has been deleted.
</>
) : (
<>
Branch{" "}
<code className="rounded bg-purple-500/20 px-1 py-0.5 font-mono text-xs">
{branchName}
</code>{" "}
has been merged.
</>
)}
</p>
{!isDeleted && (
<Button
variant="ghost"
size="xs"
disabled={isDeleting}
className="shrink-0 text-purple-700 hover:bg-purple-500/10 hover:text-purple-800 dark:text-purple-300 dark:hover:bg-purple-500/10 dark:hover:text-purple-200"
iconLeft={
isDeleting ? (
<Spinner size={12} />
) : (
<Delete01Icon size={12} strokeWidth={2} />
)
}
onClick={() => {
void handleDelete();
}}
>
Delete branch
</Button>
)}
</div>
);
}

function MergeStatusCard({
status,
owner,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ export const ReviewFileDiffBlock = memo(function ReviewFileDiffBlock({
`[data-utility-button] { background-color: ${mutedFg}; }`,
`[data-line-annotation] { font-family: 'Inter Variable', 'Inter', 'Avenir Next', ui-sans-serif, system-ui, sans-serif; }`,
`[data-line-annotation] code { font-family: var(--diffs-font-family, var(--diffs-font-fallback)); }`,
`[data-diff] { border: 1px solid var(--border); border-top: 0; border-radius: 4px; border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; overflow: hidden; }`,
isDark
? `:host { --diffs-bg-addition-override: color-mix(in lab, var(--diffs-bg) 92%, var(--diffs-addition-base)); --diffs-bg-addition-number-override: color-mix(in lab, var(--diffs-bg) 88%, var(--diffs-addition-base)); --diffs-bg-addition-emphasis-override: color-mix(in lab, var(--diffs-bg) 75%, var(--diffs-addition-base)); --diffs-bg-deletion-override: color-mix(in lab, var(--diffs-bg) 92%, var(--diffs-deletion-base)); --diffs-bg-deletion-number-override: color-mix(in lab, var(--diffs-bg) 88%, var(--diffs-deletion-base)); --diffs-bg-deletion-emphasis-override: color-mix(in lab, var(--diffs-bg) 75%, var(--diffs-deletion-base)); }`
: `:host { --diffs-bg-addition-override: color-mix(in lab, var(--diffs-bg) 82%, var(--diffs-addition-base)); --diffs-bg-addition-number-override: color-mix(in lab, var(--diffs-bg) 78%, var(--diffs-addition-base)); --diffs-bg-deletion-override: color-mix(in lab, var(--diffs-bg) 82%, var(--diffs-deletion-base)); --diffs-bg-deletion-number-override: color-mix(in lab, var(--diffs-bg) 78%, var(--diffs-deletion-base)); }`,
Expand Down
22 changes: 22 additions & 0 deletions apps/dashboard/src/lib/github.functions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2325,6 +2325,28 @@ export const mergePullRequest = createServerFn({ method: "POST" })
}
});

export const deleteBranch = createServerFn({ method: "POST" })
.inputValidator(
identityValidator<{ owner: string; repo: string; branch: string }>,
)
.handler(async ({ data }): Promise<MutationResult> => {
const context = await getGitHubContext();
if (!context) {
return { ok: false, error: "Not authenticated" };
}

try {
await context.octokit.rest.git.deleteRef({
owner: data.owner,
repo: data.repo,
ref: `heads/${data.branch}`,
});
return { ok: true };
} catch (error) {
return toMutationError("delete branch", error);
}
});

async function getPullFilesResult(
context: GitHubContext,
data: PullFilesPageInput,
Expand Down
70 changes: 7 additions & 63 deletions apps/dashboard/src/routes/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ function LoginPage() {
DiffKit
</p>
<p className="text-base text-muted-foreground sm:text-sm">
Review workspace
Beta version
</p>
</div>
</div>
Expand All @@ -74,11 +74,6 @@ function LoginPage() {
<h1 className="w-full text-3xl font-semibold tracking-tight text-balance text-foreground sm:text-2xl">
Review your GitHub work in one place
</h1>
<p className="mt-3 text-base leading-7 text-muted-foreground sm:text-sm sm:leading-6">
DiffKit pulls together open pull requests, assigned issues,
and pending code reviews into one fast workspace so you can
move through GitHub work without tab sprawl.
</p>
</div>

<form
Expand All @@ -97,79 +92,28 @@ function LoginPage() {
Continue with GitHub
</Button>
</form>

<div className="space-y-3 rounded-xl border border-border bg-card/40 p-4">
<h2 className="text-sm font-medium text-foreground">
What DiffKit helps you do
</h2>
<ul className="space-y-2 text-sm leading-6 text-muted-foreground">
<li>
Track pull requests across repositories from one queue.
</li>
<li>
See assigned issues, mentions, and review requests together.
</li>
<li>
Open diffs, comments, and issue details without context
switching.
</li>
</ul>
</div>
</div>

<div className="flex items-center gap-2 text-base text-muted-foreground sm:text-sm">
<span
aria-hidden="true"
className="size-1.5 rounded-full bg-border"
/>
<p>Simple now, room to layer more later.</p>
<p>Your GitHub activity, one dashboard away.</p>
</div>
</div>
</section>

<section className="hidden min-h-dvh items-center overflow-hidden bg-background py-4 pl-4 lg:flex lg:py-6 lg:pl-6 xl:py-8 xl:pl-8">
<div className="[-webkit-mask-image:linear-gradient(to_right,black_0,black_80%,transparent_100%)] [mask-image:linear-gradient(to_right,black_0,black_80%,transparent_100%)] flex w-[114%] shrink-0 translate-x-20 items-center justify-center rounded-[2rem] bg-background p-6 shadow-[0_24px_80px_-48px_rgba(15,23,42,0.3)] dark:shadow-none xl:translate-x-32">
<div className="flex aspect-[16/10] w-full max-w-[56rem] flex-col justify-between rounded-[1.5rem] border border-border bg-card p-8 shadow-[0_18px_40px_-34px_rgba(15,23,42,0.25)] dark:shadow-none xl:max-w-[64rem]">
<div className="max-w-xl space-y-4">
<p className="text-sm font-medium uppercase tracking-[0.18em] text-muted-foreground">
Developer workflow
</p>
<h2 className="text-4xl font-semibold tracking-tight text-foreground">
A calmer way to triage PRs, issues, and review requests.
</h2>
<p className="max-w-lg text-base leading-7 text-muted-foreground">
Use one dashboard for GitHub queues, detailed pull request
views, issue threads, and code review context.
</p>
</div>

<div className="grid grid-cols-3 gap-4">
<FeaturePanel
label="Pull Requests"
value="Track authored, assigned, mentioned, and involved PRs."
/>
<FeaturePanel
label="Issues"
value="Monitor assigned issues, authored work, and mentions."
/>
<FeaturePanel
label="Code Reviews"
value="Review diffs, comments, and status updates in one flow."
/>
</div>
</div>
<img
src="/login-preview.png"
alt="DiffKit dashboard preview"
className="aspect-[16/10] w-full max-w-[56rem] rounded-xl border border-border object-cover object-left-top shadow-[0_18px_40px_-34px_rgba(15,23,42,0.25)] dark:shadow-none xl:max-w-[64rem]"
/>
</div>
</section>
</div>
</main>
);
}

function FeaturePanel({ label, value }: { label: string; value: string }) {
return (
<div className="rounded-2xl border border-border bg-background/70 p-4">
<p className="text-sm font-medium text-foreground">{label}</p>
<p className="mt-2 text-sm leading-6 text-muted-foreground">{value}</p>
</div>
);
}
1 change: 1 addition & 0 deletions packages/icons/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export {
ComputerIcon as SystemIcon,
Copy01Icon as CopyIcon,
DashboardSquare01Icon as DashboardIcon,
Delete01Icon,
DragDropVerticalIcon as GripVerticalIcon,
File02Icon as FileIcon,
Folder01Icon as FolderIcon,
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@diffkit/icons": "workspace:*",
"@fontsource-variable/geist-mono": "^5.2.7",
"@fontsource-variable/inter": "^5.2.8",
"@m2d/react-markdown": "^1.0.0",
"@radix-ui/react-alert-dialog": "^1.1.6",
"@radix-ui/react-avatar": "^1.1.3",
"@radix-ui/react-checkbox": "^1.1.4",
Expand All @@ -43,7 +44,6 @@
"next-themes": "^0.4.4",
"react-day-picker": "8.10.1",
"react-hook-form": "^7.54.2",
"react-markdown": "^10.1.0",
"react-resizable-panels": "^3.0.3",
"rehype-raw": "^7.0.0",
"remark-gfm": "^4.0.1",
Expand Down
Loading
Loading