Skip to content

Commit 1e35134

Browse files
lwinmoepaingclaude
andcommitted
✨ feat(how-to): add PR workflow steps with sub-step visualization
Add steps 9-11 (commit, push, create PR) to the How-To guide using bun commit (gitmoji helper) instead of plain git commit. Introduces SubStepsBlock component for nested mini-terminals within step cards. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent b9e5eed commit 1e35134

3 files changed

Lines changed: 300 additions & 10 deletions

File tree

messages/en.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,24 @@
137137
"step7Line4": "4. Save the file to:",
138138
"step8Line1": "Your profile card appears in the grid!",
139139
"step8Line2": "Search by typing your name if needed.",
140+
"step9Title": "Commit Your Changes",
141+
"step9Desc": "Stage your profile file and use the interactive gitmoji commit helper to create a well-formatted commit.",
142+
"step9Sub1": "Stage your profile file",
143+
"step9Sub2": "Run the commit helper",
144+
"step9Sub3": "Fill in gitmoji prompts",
145+
"step9Sub4": "Commit created",
146+
"step10Title": "Push to GitHub",
147+
"step10Desc": "Push your branch to your forked repository on GitHub.",
148+
"step11Title": "Create a Pull Request",
149+
"step11Desc": "Go to the original MMSWE repository on GitHub and create a pull request from your branch.",
150+
"step11Sub1": "Open pull request page",
151+
"step11Sub2": "Fill in details",
152+
"step11Sub3": "Submit",
153+
"step11Line1": "Open Pull Request",
154+
"step11Line2": "Base: main ← Compare: your_name",
155+
"step11Line3": "Title: add your_name profile",
156+
"step11Line4": "Description: Added my developer profile",
157+
"step11Line5": "Click Create Pull Request",
140158
"ctaOpenEditor": "Open Profile Editor",
141159
"ctaViewProfiles": "View Profiles"
142160
},

messages/mm.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,24 @@
137137
"step7Line4": "4. ဖိုင်ကို ဤနေရာတွင် သိမ်းပါ:",
138138
"step8Line1": "သင့်ပရိုဖိုင်ကတ် grid ထဲတွင် ပေါ်လာပါပြီ!",
139139
"step8Line2": "လိုအပ်ပါက သင့်အမည်ရိုက်ပြီး ရှာဖွေပါ။",
140+
"step9Title": "ပြောင်းလဲမှုများ Commit လုပ်ပါ",
141+
"step9Desc": "သင့်ပရိုဖိုင် ဖိုင်ကို stage လုပ်ပြီး gitmoji commit helper ဖြင့် ပုံစံကျသော commit ဖန်တီးပါ။",
142+
"step9Sub1": "ပရိုဖိုင် ဖိုင်ကို stage လုပ်ပါ",
143+
"step9Sub2": "Commit helper ကို run ပါ",
144+
"step9Sub3": "Gitmoji prompts များ ဖြည့်ပါ",
145+
"step9Sub4": "Commit ဖန်တီးပြီးပါပြီ",
146+
"step10Title": "GitHub သို့ Push လုပ်ပါ",
147+
"step10Desc": "သင့် branch ကို GitHub ရှိ fork လုပ်ထားသော repository သို့ push လုပ်ပါ။",
148+
"step11Title": "Pull Request ဖန်တီးပါ",
149+
"step11Desc": "GitHub ရှိ မူရင်း MMSWE repository သို့သွားပြီး သင့် branch မှ pull request ဖန်တီးပါ။",
150+
"step11Sub1": "Pull request စာမျက်နှာ ဖွင့်ပါ",
151+
"step11Sub2": "အချက်အလက်များ ဖြည့်ပါ",
152+
"step11Sub3": "တင်သွင်းပါ",
153+
"step11Line1": "Pull Request ဖွင့်ပါ",
154+
"step11Line2": "Base: main ← Compare: your_name",
155+
"step11Line3": "ခေါင်းစဉ်: add your_name profile",
156+
"step11Line4": "ဖော်ပြချက်: ကျွန်တော်/ကျွန်မ၏ developer ပရိုဖိုင် ထည့်ပါသည်",
157+
"step11Line5": "Create Pull Request ကို နှိပ်ပါ",
140158
"ctaOpenEditor": "Profile Editor ဖွင့်ရန်",
141159
"ctaViewProfiles": "ပရိုဖိုင်များ ကြည့်ရန်"
142160
},

src/app/how-to/HowToPageClient.tsx

Lines changed: 264 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import {
1616
CheckCircle2,
1717
ArrowRight,
1818
ChevronRight,
19+
GitCommitHorizontal,
20+
Upload,
21+
GitPullRequestArrow,
1922
} from "lucide-react";
2023
import type { LucideIcon } from "lucide-react";
2124
import { useTranslations } from "next-intl";
@@ -27,21 +30,26 @@ const prismColors = ["#22d3ee", "#a78bfa", "#fb7185", "#fbbf24"] as const;
2730
const colorAt = (i: number) => prismColors[i % prismColors.length];
2831

2932
/* ── Step data ── */
33+
type TerminalData = {
34+
label: string;
35+
lines: { prompt?: boolean; text: string; accent?: string }[];
36+
};
37+
38+
type SubStepData = {
39+
label: string;
40+
terminal: TerminalData;
41+
};
42+
3043
type StepData = {
3144
title: string;
3245
description: string;
3346
icon: LucideIcon;
34-
terminal: {
35-
label: string;
36-
lines: { prompt?: boolean; text: string; accent?: string }[];
37-
};
47+
terminal: TerminalData;
3848
optionToggle?: {
3949
labels: [string, string];
40-
terminals: [
41-
{ label: string; lines: { prompt?: boolean; text: string; accent?: string }[] },
42-
{ label: string; lines: { prompt?: boolean; text: string; accent?: string }[] },
43-
];
50+
terminals: [TerminalData, TerminalData];
4451
};
52+
subSteps?: SubStepData[];
4553
};
4654

4755
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -198,6 +206,108 @@ const getSteps = (t: any): StepData[] => [
198206
],
199207
},
200208
},
209+
{
210+
title: t("step9Title"),
211+
description: t("step9Desc"),
212+
icon: GitCommitHorizontal,
213+
terminal: { label: "terminal", lines: [] },
214+
subSteps: [
215+
{
216+
label: t("step9Sub1"),
217+
terminal: {
218+
label: "terminal",
219+
lines: [
220+
{ prompt: true, text: "git add content/profile/your_name.mdx" },
221+
],
222+
},
223+
},
224+
{
225+
label: t("step9Sub2"),
226+
terminal: {
227+
label: "terminal",
228+
lines: [
229+
{ prompt: true, text: "bun commit" },
230+
{ text: "? Select the type of change:", accent: "#a78bfa" },
231+
],
232+
},
233+
},
234+
{
235+
label: t("step9Sub3"),
236+
terminal: {
237+
label: "gitmoji interactive",
238+
lines: [
239+
{ text: "? Choose a gitmoji: :fire: build", accent: "#fbbf24" },
240+
{ text: "? Choose the type: build", accent: "#22d3ee" },
241+
{ text: "? Scope: profile" },
242+
{ text: '? Message: add your_name profile', accent: "#fb7185" },
243+
],
244+
},
245+
},
246+
{
247+
label: t("step9Sub4"),
248+
terminal: {
249+
label: "terminal",
250+
lines: [
251+
{ text: ":fire: build(profile): add your_name profile", accent: "#22d3ee" },
252+
{ text: "1 file changed, 12 insertions(+)" },
253+
],
254+
},
255+
},
256+
],
257+
},
258+
{
259+
title: t("step10Title"),
260+
description: t("step10Desc"),
261+
icon: Upload,
262+
terminal: {
263+
label: "terminal",
264+
lines: [
265+
{ prompt: true, text: "git push origin your_name" },
266+
{ text: "Enumerating objects: 5, done.", accent: "#a78bfa" },
267+
{ text: "Writing objects: 100% (3/3), done." },
268+
{ text: "remote: Create a pull request for 'your_name' on GitHub by visiting:", accent: "#fb7185" },
269+
{ text: "remote: https://github.com/YOUR_USERNAME/...github.io/pull/new/your_name" },
270+
],
271+
},
272+
},
273+
{
274+
title: t("step11Title"),
275+
description: t("step11Desc"),
276+
icon: GitPullRequestArrow,
277+
terminal: { label: "github.com", lines: [] },
278+
subSteps: [
279+
{
280+
label: t("step11Sub1"),
281+
terminal: {
282+
label: "github.com",
283+
lines: [
284+
{ text: t("step11Line1"), accent: "#fbbf24" },
285+
{ text: "" },
286+
{ text: t("step11Line2") },
287+
],
288+
},
289+
},
290+
{
291+
label: t("step11Sub2"),
292+
terminal: {
293+
label: "github.com — pull request",
294+
lines: [
295+
{ text: t("step11Line3"), accent: "#22d3ee" },
296+
{ text: t("step11Line4") },
297+
],
298+
},
299+
},
300+
{
301+
label: t("step11Sub3"),
302+
terminal: {
303+
label: "github.com",
304+
lines: [
305+
{ text: t("step11Line5"), accent: "#fb7185" },
306+
],
307+
},
308+
},
309+
],
310+
},
201311
];
202312

203313
/* ── Hero Section ── */
@@ -358,6 +468,143 @@ const TerminalBlock = ({
358468
</motion.div>
359469
);
360470

471+
/* ── Sub-Steps Block ── */
472+
const subStepLetters = "abcdefghijklmnopqrstuvwxyz";
473+
474+
const SubStepsBlock = ({
475+
subSteps,
476+
color,
477+
isInView,
478+
mmFont = "",
479+
}: {
480+
subSteps: SubStepData[];
481+
color: string;
482+
isInView: boolean;
483+
mmFont?: string;
484+
}) => (
485+
<div className="space-y-0">
486+
{subSteps.map((sub, i) => {
487+
const isLast = i === subSteps.length - 1;
488+
return (
489+
<div key={i} className="flex gap-3">
490+
{/* Sub-step indicator: letter + connecting line */}
491+
<div className="flex flex-col items-center shrink-0 pt-1">
492+
<motion.div
493+
className="relative flex items-center justify-center w-6 h-6 rounded-full z-10"
494+
style={{
495+
background: `linear-gradient(135deg, ${color}14, ${color}06)`,
496+
border: `1.5px solid ${color}30`,
497+
}}
498+
initial={{ scale: 0, opacity: 0 }}
499+
animate={
500+
isInView
501+
? { scale: 1, opacity: 1 }
502+
: { scale: 0, opacity: 0 }
503+
}
504+
transition={{
505+
type: "spring",
506+
stiffness: 300,
507+
damping: 20,
508+
delay: 0.2 + i * 0.1,
509+
}}
510+
>
511+
<span
512+
className="font-mono text-[10px] font-bold"
513+
style={{ color }}
514+
>
515+
{subStepLetters[i]}
516+
</span>
517+
</motion.div>
518+
{!isLast && (
519+
<motion.div
520+
className="w-[1.5px] flex-1 min-h-[12px] origin-top"
521+
style={{
522+
background: `linear-gradient(180deg, ${color}25, ${color}08)`,
523+
}}
524+
initial={{ scaleY: 0 }}
525+
animate={isInView ? { scaleY: 1 } : { scaleY: 0 }}
526+
transition={{
527+
duration: 0.4,
528+
delay: 0.35 + i * 0.1,
529+
ease: [0.22, 1, 0.36, 1],
530+
}}
531+
/>
532+
)}
533+
</div>
534+
535+
{/* Sub-step content */}
536+
<motion.div
537+
className={cn("flex-1", isLast ? "" : "pb-3")}
538+
initial={{ opacity: 0, x: -8 }}
539+
animate={
540+
isInView ? { opacity: 1, x: 0 } : { opacity: 0, x: -8 }
541+
}
542+
transition={{
543+
duration: 0.4,
544+
delay: 0.25 + i * 0.1,
545+
ease: [0.22, 1, 0.36, 1],
546+
}}
547+
>
548+
{/* Sub-step label */}
549+
<p
550+
className={cn(
551+
"font-mono text-[11px] text-zinc-500 mb-1.5 tracking-wide",
552+
mmFont
553+
)}
554+
>
555+
{sub.label}
556+
</p>
557+
{/* Mini terminal */}
558+
<div
559+
className={cn(
560+
"rounded-xl overflow-hidden",
561+
"bg-surface/60 backdrop-blur-sm",
562+
"border border-white/[0.04]"
563+
)}
564+
>
565+
<div className="flex items-center gap-1.5 px-3 py-1.5 border-b border-white/[0.03]">
566+
<div className="flex gap-1">
567+
<div className="w-1.5 h-1.5 rounded-full bg-prism-rose/40" />
568+
<div className="w-1.5 h-1.5 rounded-full bg-accent-gold/40" />
569+
<div className="w-1.5 h-1.5 rounded-full bg-prism-cyan/40" />
570+
</div>
571+
<span className="font-mono text-[9px] text-zinc-600 ml-0.5">
572+
{sub.terminal.label}
573+
</span>
574+
</div>
575+
<div className="px-3 py-2.5 space-y-0.5">
576+
{sub.terminal.lines.map((line, j) => (
577+
<div key={j} className="flex items-start gap-1.5">
578+
{line.prompt && (
579+
<span
580+
className="font-mono text-[11px] shrink-0"
581+
style={{ color: `${color}80` }}
582+
>
583+
$
584+
</span>
585+
)}
586+
<span
587+
className={cn(
588+
"font-mono text-[11px] leading-relaxed break-all",
589+
line.accent ? "" : "text-zinc-400"
590+
)}
591+
style={
592+
line.accent ? { color: line.accent } : undefined
593+
}
594+
>
595+
{line.text || "\u00A0"}
596+
</span>
597+
</div>
598+
))}
599+
</div>
600+
</div>
601+
</motion.div>
602+
</div>
603+
);
604+
})}
605+
</div>
606+
);
607+
361608
/* ── Option Toggle for Step 7 ── */
362609
const OptionToggle = ({
363610
labels,
@@ -527,8 +774,15 @@ const StepCard = ({
527774
/>
528775
)}
529776

530-
{/* Terminal block */}
531-
{step.optionToggle ? (
777+
{/* Terminal / Sub-steps / Option toggle */}
778+
{step.subSteps ? (
779+
<SubStepsBlock
780+
subSteps={step.subSteps}
781+
color={color}
782+
isInView={inView}
783+
mmFont={mmFont}
784+
/>
785+
) : step.optionToggle ? (
532786
<AnimatePresence mode="wait">
533787
<motion.div
534788
key={activeOption}

0 commit comments

Comments
 (0)