From 8713d79250112a72fb0a4902bb786437e8f289d1 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 13 Mar 2026 06:43:04 +0000 Subject: [PATCH] refactor: extract DisplayOptions and ReadmeCardUrl into subcomponents Co-authored-by: is0692vs <135803462+is0692vs@users.noreply.github.com> --- dev_output.log | 30 +++ src/components/DashboardSettingsClient.tsx | 217 +-------------------- src/components/DisplayOptionsSection.tsx | 52 +++++ src/components/ReadmeCardUrlSection.tsx | 184 +++++++++++++++++ 4 files changed, 274 insertions(+), 209 deletions(-) create mode 100644 dev_output.log create mode 100644 src/components/DisplayOptionsSection.tsx create mode 100644 src/components/ReadmeCardUrlSection.tsx diff --git a/dev_output.log b/dev_output.log new file mode 100644 index 0000000..0355cf1 --- /dev/null +++ b/dev_output.log @@ -0,0 +1,30 @@ + +> github-user-summary@0.1.0 dev +> next dev + +▲ Next.js 16.1.6 (Turbopack) +- Local: http://localhost:3000 +- Network: http://192.168.0.2:3000 + +✓ Starting... +✓ Ready in 1120ms +○ Compiling /dashboard/settings ... +[next-auth][warn][NEXTAUTH_URL] +https://next-auth.js.org/warnings#nextauth_url + GET /dashboard/settings 307 in 5.9s (compile: 5.5s, render: 388ms) + GET / 200 in 769ms (compile: 692ms, render: 77ms) +[next-auth][warn][NEXTAUTH_URL] +https://next-auth.js.org/warnings#nextauth_url + GET /api/auth/session 200 in 2.4s (compile: 2.4s, render: 52ms) + GET / 200 in 106ms (compile: 6ms, render: 99ms) + GET /api/auth/session 200 in 40ms (compile: 27ms, render: 12ms) +⚠ metadataBase property in metadata export is not set for resolving social open graph or twitter images, using "http://localhost:3000". See https://nextjs.org/docs/app/api-reference/functions/generate-metadata#metadatabase +React expects the `children` prop of tags to be a string, number, bigint, or object with a novel `toString` method but found an Array with length 4 instead. Browsers treat all child Nodes of <title> tags as Text content and React expects to be able to convert `children` of <title> tags to a single string value which is why Arrays of length greater than 1 are not supported. When using JSX it can be common to combine text nodes and value nodes. For example: <title>hello {nameOfUser}. While not immediately apparent, `children` in this case is an Array with length 2. If your `children` prop is using this form try rewriting it using a template string: {`hello ${nameOfUser}`}. + GET /api/auth/session 200 in 41ms (compile: 28ms, render: 13ms) + GET /test-settings 200 in 3.8s (compile: 2.1s, render: 1679ms) + GET /test-settings 200 in 974ms (compile: 740ms, render: 235ms) +[next-auth][warn][NEXTAUTH_URL] +https://next-auth.js.org/warnings#nextauth_url + GET /api/auth/session 200 in 369ms (compile: 294ms, render: 75ms) + GET /api/auth/session 200 in 38ms (compile: 9ms, render: 30ms) +✓ Compiled in 61ms diff --git a/src/components/DashboardSettingsClient.tsx b/src/components/DashboardSettingsClient.tsx index e6ef1ca..9c1526c 100644 --- a/src/components/DashboardSettingsClient.tsx +++ b/src/components/DashboardSettingsClient.tsx @@ -1,10 +1,11 @@ "use client"; -import { useMemo } from "react"; import { useState } from "react"; import { useSession } from "next-auth/react"; import LayoutEditor from "@/components/LayoutEditor"; +import DisplayOptionsSection from "@/components/DisplayOptionsSection"; +import ReadmeCardUrlSection from "@/components/ReadmeCardUrlSection"; import { getDefaultCardSettings, loadCardSettings, @@ -12,19 +13,6 @@ import { } from "@/lib/cardSettings"; import type { CardBlockId, CardDisplayOptions, CardLayout } from "@/lib/types"; -const toggles: Array<{ key: keyof CardDisplayOptions; label: string }> = [ - { key: "showCompany", label: "Company" }, - { key: "showLocation", label: "Location" }, - { key: "showWebsite", label: "Website" }, - { key: "showTwitter", label: "Twitter" }, - { key: "showJoinedDate", label: "Joined date" }, - { key: "showTopics", label: "Topics" }, - { key: "showContributionBreakdown", label: "Contribution breakdown" }, - { key: "showStreaks", label: "Streaks" }, - { key: "showInterests", label: "Interests" }, - { key: "showActivityBreakdown", label: "Activity breakdown" }, -]; - export default function DashboardSettingsClient() { const { data: session } = useSession(); const [layout, setLayout] = useState( @@ -34,11 +22,6 @@ export default function DashboardSettingsClient() { () => loadCardSettings().options, ); const [status, setStatus] = useState(""); - const [readmeTheme, setReadmeTheme] = useState<"light" | "dark">("light"); - const [readmeCols, setReadmeCols] = useState<1 | 2>(1); - const [includeStreak, setIncludeStreak] = useState(false); - const [includeHeatmap, setIncludeHeatmap] = useState(false); - const [copyState, setCopyState] = useState(""); const onSave = () => { saveCardSettings(layout, options); @@ -62,106 +45,6 @@ export default function DashboardSettingsClient() { })); }; - const readmeUrl = useMemo(() => { - const username = session?.user?.login; - if (!username) { - return ""; - } - - const blockMap: Record< - CardBlockId, - "bio" | "stats" | "langs" | "repos" | null - > = { - avatar: null, - bio: "bio", - stats: "stats", - topLanguages: "langs", - topRepos: "repos", - }; - - const selected = layout.blocks - .filter((block) => block.visible) - .map((block) => blockMap[block.id]) - .filter((block): block is "bio" | "stats" | "langs" | "repos" => - Boolean(block), - ); - - const selectedBlocks: Array< - "bio" | "stats" | "langs" | "repos" | "streak" | "heatmap" - > = [...selected]; - - if (includeStreak) { - selectedBlocks.push("streak"); - } - - if (includeHeatmap) { - selectedBlocks.push("heatmap"); - } - - const uniqueBlocks = Array.from(new Set(selectedBlocks)); - - const layoutParts = layout.blocks - .filter((block) => block.visible && blockMap[block.id]) - .map((block) => { - const target = blockMap[block.id]; - if (!target) { - return null; - } - return `${block.column}:${target}`; - }) - .filter((value): value is string => Boolean(value)); - - const hide = []; - if (options.showContributionBreakdown === false) { - hide.push("stars"); - } - if (options.showActivityBreakdown === false) { - hide.push("forks"); - } - - const params = new URLSearchParams(); - params.set("format", "png"); - params.set("theme", readmeTheme); - params.set("cols", String(readmeCols)); - params.set( - "blocks", - uniqueBlocks.length > 0 ? uniqueBlocks.join(",") : "bio,stats,langs", - ); - if (layoutParts.length > 0) { - params.set("layout", layoutParts.join(",")); - } - if (hide.length > 0) { - params.set("hide", hide.join(",")); - } - params.set("width", "600"); - - const origin = typeof window !== "undefined" ? window.location.origin : ""; - return `${origin}/api/card/${encodeURIComponent(username)}?${params.toString()}`; - }, [ - session?.user?.login, - layout.blocks, - options.showContributionBreakdown, - options.showActivityBreakdown, - readmeTheme, - readmeCols, - includeStreak, - includeHeatmap, - ]); - - const onCopyReadmeUrl = async () => { - if (!readmeUrl) { - setCopyState("Sign in to generate URL"); - return; - } - - try { - await navigator.clipboard.writeText(readmeUrl); - setCopyState("Copied!"); - } catch { - setCopyState("Copy failed"); - } - }; - return (
@@ -182,97 +65,13 @@ export default function DashboardSettingsClient() { /> -
-

Display Options

-
- {toggles.map((toggle) => { - const checked = Boolean(options[toggle.key]); - return ( - - ); - })} -
-
- -
-

README Card URL

-
- - - - -
+ -
- {readmeUrl || "Sign in to generate your README URL"} -
- -
- - {copyState ? ( - {copyState} - ) : null} -
-
+
+ {copyState ? ( + {copyState} + ) : null} +
+ + ); +}