Skip to content

Commit da39353

Browse files
feat(website): update hero with real GitHub Action output
- Replace sample data with real output from stringly-typed-demo repo - Redesign GitHubComment to match actual GitHub dark theme - Add collapsible file sections with markdown tables - Show real validation results (98 strings, 80 valid, 18 invalid)
1 parent 30431d2 commit da39353

File tree

2 files changed

+180
-113
lines changed

2 files changed

+180
-113
lines changed

website/components/GitHubComment.tsx

Lines changed: 127 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,125 +1,167 @@
1+
"use client";
2+
3+
import { useState } from "react";
4+
15
interface Issue {
2-
file: string;
36
line: number;
4-
original: string;
7+
content: string;
58
issue: string;
69
}
710

11+
interface FileIssues {
12+
file: string;
13+
issues: Issue[];
14+
}
15+
816
interface CommentData {
9-
author: string;
10-
avatarUrl: string;
1117
timestamp: string;
12-
validCount: number;
13-
totalCount: number;
14-
issues: Issue[];
18+
criticalCount: number;
19+
files: FileIssues[];
1520
}
1621

1722
interface GitHubCommentProps {
1823
data: CommentData;
1924
}
2025

2126
export default function GitHubComment({ data }: GitHubCommentProps) {
22-
const percentage = Math.round((data.validCount / data.totalCount) * 100);
23-
const passed = percentage >= 90;
27+
const [expandedFiles, setExpandedFiles] = useState<Set<string>>(
28+
new Set([data.files[0]?.file])
29+
);
30+
31+
const toggleFile = (file: string) => {
32+
setExpandedFiles((prev) => {
33+
const next = new Set(prev);
34+
if (next.has(file)) {
35+
next.delete(file);
36+
} else {
37+
next.add(file);
38+
}
39+
return next;
40+
});
41+
};
2442

2543
return (
2644
<div>
2745
{/* GitHub Comment Container */}
28-
<div className="bg-white rounded-lg border border-[#d0d7de] shadow-lg overflow-hidden">
46+
<div className="bg-[#0d1117] rounded-lg border border-[#30363d] shadow-lg overflow-hidden">
2947
{/* Comment Header */}
30-
<div className="bg-[#f6f8fa] border-b border-[#d0d7de] px-4 py-3 flex items-center gap-3">
31-
{/* Avatar */}
32-
<div className="w-8 h-8 rounded-full bg-[var(--chocolate-brown)] flex items-center justify-center text-white text-xs font-bold">
33-
ST
48+
<div className="bg-[#161b22] border-b border-[#30363d] px-4 py-3 flex items-center gap-3">
49+
{/* GitHub Avatar */}
50+
<div className="w-10 h-10 rounded-full bg-[#21262d] flex items-center justify-center">
51+
<svg className="w-6 h-6 text-[#8b949e]" fill="currentColor" viewBox="0 0 16 16">
52+
<path d="M8 0c4.42 0 8 3.58 8 8a8.013 8.013 0 0 1-5.45 7.59c-.4.08-.55-.17-.55-.38 0-.27.01-1.13.01-2.2 0-.75-.25-1.23-.54-1.48 1.78-.2 3.65-.88 3.65-3.95 0-.88-.31-1.59-.82-2.15.08-.2.36-1.02-.08-2.12 0 0-.67-.22-2.2.82-.64-.18-1.32-.27-2-.27-.68 0-1.36.09-2 .27-1.53-1.03-2.2-.82-2.2-.82-.44 1.1-.16 1.92-.08 2.12-.51.56-.82 1.28-.82 2.15 0 3.06 1.86 3.75 3.64 3.95-.23.2-.44.55-.51 1.07-.46.21-1.61.55-2.33-.66-.15-.24-.6-.83-1.23-.82-.67.01-.27.38.01.53.34.19.73.9.82 1.13.16.45.68 1.31 2.69.94 0 .67.01 1.3.01 1.49 0 .21-.15.45-.55.38A7.995 7.995 0 0 1 0 8c0-4.42 3.58-8 8-8Z" />
53+
</svg>
3454
</div>
3555

3656
{/* Author info */}
3757
<div className="flex items-center gap-2 flex-wrap">
38-
<span className="font-semibold text-[#1f2328] text-sm">
39-
{data.author}
58+
<span className="font-semibold text-[#e6edf3] text-sm">
59+
github-actions
60+
</span>
61+
<span className="text-[#8b949e] text-xs bg-[#30363d] px-1.5 py-0.5 rounded-full border border-[#30363d]">
62+
bot
63+
</span>
64+
<span className="text-[#8b949e] text-sm">
65+
commented {data.timestamp}
4066
</span>
41-
<span className="text-[#656d76] text-sm">bot</span>
42-
<span className="text-[#656d76] text-sm">commented {data.timestamp}</span>
4367
</div>
4468
</div>
4569

4670
{/* Comment Body */}
47-
<div className="p-4 text-sm text-[#1f2328]">
48-
{/* Status Badge */}
49-
<div className="flex items-center gap-2 mb-4">
50-
<span
51-
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${
52-
passed
53-
? "bg-[#dafbe1] text-[#1a7f37]"
54-
: "bg-[#ffebe9] text-[#cf222e]"
55-
}`}
56-
>
57-
{passed ? (
58-
<svg className="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 16 16">
59-
<path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 0 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z" />
60-
</svg>
61-
) : (
62-
<svg className="w-3 h-3 mr-1" fill="currentColor" viewBox="0 0 16 16">
63-
<path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.75.75 0 1 1 1.06 1.06L9.06 8l3.22 3.22a.75.75 0 1 1-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 0 1-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z" />
64-
</svg>
65-
)}
66-
{passed ? "Passed" : "Failed"}
67-
</span>
68-
<span className="text-[#656d76]">
69-
{data.validCount}/{data.totalCount} strings valid ({percentage}%)
70-
</span>
71-
</div>
71+
<div className="p-4 text-sm text-[#e6edf3]">
72+
{/* Title */}
73+
<h2 className="text-lg font-semibold mb-3 flex items-center gap-2">
74+
<span>🎯</span>
75+
Stringly-Typed Results
76+
</h2>
7277

73-
{/* Heading */}
74-
<h3 className="font-semibold text-base mb-3 flex items-center gap-2">
75-
<svg className="w-4 h-4 text-[var(--burnt-sienna)]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
76-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
77-
</svg>
78-
Brand Voice Issues Found
79-
</h3>
78+
{/* Status */}
79+
<p className="mb-4">
80+
<span className="text-[#f85149]"></span>{" "}
81+
<strong>Failed:</strong> Found {data.criticalCount} critical issue(s)
82+
</p>
8083

81-
{/* Issues List */}
82-
<div className="space-y-3">
83-
{data.issues.map((issue, index) => (
84-
<div
85-
key={index}
86-
className="bg-[#fff8f7] border border-[#ffcecb] rounded-md p-3"
87-
>
88-
{/* File location */}
89-
<div className="flex items-center gap-2 text-xs text-[#656d76] mb-2">
90-
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
91-
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
92-
</svg>
93-
<code className="bg-[#f6f8fa] px-1.5 py-0.5 rounded text-[#1f2328]">
94-
{issue.file}:{issue.line}
95-
</code>
96-
</div>
84+
{/* Issues Found Header */}
85+
<h3 className="font-semibold text-base mb-3">Issues Found</h3>
9786

98-
{/* Original text */}
99-
<div className="mb-2">
100-
<code className="bg-[#ffebe9] text-[#cf222e] px-2 py-1 rounded text-xs block">
101-
&quot;{issue.original}&quot;
87+
{/* Collapsible File Sections */}
88+
<div className="space-y-2">
89+
{data.files.map((fileData) => (
90+
<div key={fileData.file}>
91+
{/* Details Summary */}
92+
<button
93+
onClick={() => toggleFile(fileData.file)}
94+
className="flex items-center gap-2 text-[#e6edf3] hover:text-[#58a6ff] transition-colors w-full text-left"
95+
>
96+
<span
97+
className={`transition-transform ${
98+
expandedFiles.has(fileData.file) ? "rotate-90" : ""
99+
}`}
100+
>
101+
102+
</span>
103+
<code className="bg-[#343941] px-1.5 py-0.5 rounded text-[#e6edf3] text-xs">
104+
{fileData.file}
102105
</code>
103-
</div>
106+
<span className="text-[#8b949e]">
107+
({fileData.issues.length} issues)
108+
</span>
109+
</button>
104110

105-
{/* Issue description */}
106-
<div className="flex items-start gap-2 text-sm">
107-
<svg className="w-4 h-4 text-[var(--burnt-sienna)] mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 16 16">
108-
<path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.75.75 0 1 1 1.06 1.06L9.06 8l3.22 3.22a.75.75 0 1 1-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 0 1-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z" />
109-
</svg>
110-
<span className="text-[#1f2328]">{issue.issue}</span>
111-
</div>
111+
{/* Expanded Table */}
112+
{expandedFiles.has(fileData.file) && (
113+
<div className="mt-2 ml-4 overflow-x-auto">
114+
<table className="w-full border-collapse text-xs">
115+
<thead>
116+
<tr className="border-b border-[#30363d]">
117+
<th className="text-left py-2 px-3 text-[#8b949e] font-medium">
118+
Line
119+
</th>
120+
<th className="text-left py-2 px-3 text-[#8b949e] font-medium">
121+
Content
122+
</th>
123+
<th className="text-left py-2 px-3 text-[#8b949e] font-medium">
124+
Issue
125+
</th>
126+
</tr>
127+
</thead>
128+
<tbody>
129+
{fileData.issues.map((issue, idx) => (
130+
<tr
131+
key={idx}
132+
className="border-b border-[#21262d] hover:bg-[#161b22]"
133+
>
134+
<td className="py-2 px-3 text-[#e6edf3]">
135+
{issue.line}
136+
</td>
137+
<td className="py-2 px-3">
138+
<code className="bg-[#343941] px-1.5 py-0.5 rounded text-[#e6edf3] text-xs">
139+
{issue.content}
140+
</code>
141+
</td>
142+
<td className="py-2 px-3 text-[#e6edf3]">
143+
{issue.issue}
144+
</td>
145+
</tr>
146+
))}
147+
</tbody>
148+
</table>
149+
</div>
150+
)}
112151
</div>
113152
))}
114153
</div>
115154

116-
{/* Footer hint */}
117-
<p className="mt-4 text-xs text-[#656d76] flex items-center gap-1">
118-
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 16 16">
119-
<path d="M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 0 1-1.484.211c-.04-.282-.163-.547-.37-.847a8.456 8.456 0 0 0-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.751.751 0 0 1-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75ZM5.75 12h4.5a.75.75 0 0 1 0 1.5h-4.5a.75.75 0 0 1 0-1.5ZM6 15.25a.75.75 0 0 1 .75-.75h2.5a.75.75 0 0 1 0 1.5h-2.5a.75.75 0 0 1-.75-.75Z" />
120-
</svg>
121-
Configure rules in your STYLE_GUIDE.md
122-
</p>
155+
{/* Footer */}
156+
<div className="mt-4 pt-3 border-t border-[#30363d]">
157+
<p className="text-xs text-[#8b949e] flex items-center gap-1">
158+
<span>🎯</span>
159+
<span>Posted by</span>
160+
<a href="#" className="text-[#58a6ff] hover:underline">
161+
Stringly-Typed
162+
</a>
163+
</p>
164+
</div>
123165
</div>
124166
</div>
125167
</div>

website/components/HeroAnimation.tsx

Lines changed: 53 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,46 +3,71 @@
33
import Terminal from "./Terminal";
44
import GitHubComment from "./GitHubComment";
55

6-
// Sample data - replace with actual output from running the action
6+
// Real output from stringly-typed-demo repository
77
const terminalLines = [
8-
{ text: "$ stringly-typed --files 'src/**/*.tsx'", type: "command" as const },
8+
{ text: "$ npx stringly-typed --files 'src/**/*.ts'", type: "command" as const },
99
{ text: "", type: "output" as const },
10-
{ text: "Stringly-Typed v1.0.0", type: "output" as const },
11-
{ text: "Scanning files...", type: "output" as const },
10+
{ text: "\uD83C\uDFAF Stringly-Typed v1.4.14", type: "output" as const },
11+
{ text: "\uD83D\uDCD6 Loaded style guide from STYLE_GUIDE.md", type: "output" as const },
1212
{ text: "", type: "output" as const },
13-
{ text: "src/components/Button.tsx", type: "file" as const },
14-
{ text: ' Line 12: "Click here to continue"', type: "output" as const },
15-
{ text: " \u2717 Use \"Select\" not \"Click\" (terminology)", type: "error" as const },
13+
{ text: "src/bad-examples.ts", type: "file" as const },
14+
{ text: ' Line 6: "ERROR: Persistence layer failed..."', type: "output" as const },
15+
{ text: " \u2717 Technical jargon, unfriendly tone", type: "error" as const },
1616
{ text: "", type: "output" as const },
17-
{ text: ' Line 18: "Your order has been placed"', type: "output" as const },
18-
{ text: " \u2713 Matches brand voice", type: "success" as const },
17+
{ text: ' Line 9: "The user\'s session has been..."', type: "output" as const },
18+
{ text: " \u2717 Passive voice, refers to \"the user\"", type: "error" as const },
1919
{ text: "", type: "output" as const },
20-
{ text: "src/utils/errors.ts", type: "file" as const },
21-
{ text: ' Line 5: "An error was encountered by the system"', type: "output" as const },
22-
{ text: " \u2717 Use active voice: \"Something went wrong\"", type: "error" as const },
20+
{ text: "src/good-examples.ts", type: "file" as const },
21+
{ text: ' Line 5: "Welcome back! Ready to pick up..."', type: "output" as const },
22+
{ text: " \u2713 Friendly, uses active voice", type: "success" as const },
2323
{ text: "", type: "output" as const },
24-
{ text: "Summary: 4/6 strings valid (67%)", type: "output" as const },
25-
{ text: "Status: FAILED", type: "error" as const },
24+
{ text: ' Line 11: "Your changes have been saved!"', type: "output" as const },
25+
{ text: " \u2713 Clear, positive confirmation", type: "success" as const },
26+
{ text: "", type: "output" as const },
27+
{ text: "\uD83D\uDCCA Processed 98 strings", type: "output" as const },
28+
{ text: "\u2705 80 valid, \u274C 18 invalid", type: "output" as const },
29+
{ text: "Status: FAILED - Found 15 critical issue(s)", type: "error" as const },
2630
];
2731

32+
// Real data matching the actual GitHub PR comment format
2833
const commentData = {
29-
author: "stringly-typed",
30-
avatarUrl: "/stringly-typed-avatar.svg",
31-
timestamp: "just now",
32-
validCount: 4,
33-
totalCount: 6,
34-
issues: [
34+
timestamp: "2 minutes ago",
35+
criticalCount: 15,
36+
files: [
3537
{
36-
file: "src/components/Button.tsx",
37-
line: 12,
38-
original: "Click here to continue",
39-
issue: 'Use "Select" not "Click" (terminology)',
38+
file: "src/bad-examples.ts",
39+
issues: [
40+
{
41+
line: 6,
42+
content: "ERROR: Persistence layer failed to commit trans...",
43+
issue: "Brand style violations found: 1 error(s), 0 warning(s)",
44+
},
45+
{
46+
line: 9,
47+
content: "The user's session has been successfully authen...",
48+
issue: "Brand style violations found: 1 error(s), 0 warning(s)",
49+
},
50+
{
51+
line: 18,
52+
content: "WARNING: THIS ACTION CANNOT BE UNDONE. ALL DATA...",
53+
issue: "Brand style violations found: 1 error(s), 0 warning(s)",
54+
},
55+
],
4056
},
4157
{
42-
file: "src/utils/errors.ts",
43-
line: 5,
44-
original: "An error was encountered by the system",
45-
issue: 'Use active voice: "Something went wrong"',
58+
file: "src/example-strings.ts",
59+
issues: [
60+
{
61+
line: 5,
62+
content: "ERROR: Connection was terminated by the server...",
63+
issue: "Brand style violations found: 1 error(s), 0 warning(s)",
64+
},
65+
{
66+
line: 11,
67+
content: "YOUR REQUEST COULD NOT BE PROCESSED AT THIS TIM...",
68+
issue: "Brand style violations found: 1 error(s), 0 warning(s)",
69+
},
70+
],
4671
},
4772
],
4873
};

0 commit comments

Comments
 (0)