Skip to content

Commit fffebe3

Browse files
committed
added mock terminal to homepage hero
1 parent 3e11301 commit fffebe3

5 files changed

Lines changed: 196 additions & 5 deletions

File tree

docusaurus.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const config: Config = {
6161

6262
stylesheets: [
6363
{
64-
href: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;700&display=swap",
64+
href: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Space+Grotesk:wght@500;700&family=JetBrains+Mono:wght@400;500&display=swap",
6565
type: "text/css",
6666
},
6767
],

src/components/FloatingContributors/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,12 @@ interface ContributorActivity {
101101

102102
interface FloatingContributorsProps {
103103
headerEmbedded?: boolean;
104+
onClose?: () => void;
104105
}
105106

106107
const FloatingContributors: React.FC<FloatingContributorsProps> = ({
107108
headerEmbedded = false,
109+
onClose,
108110
}) => {
109111
const [contributors, setContributors] = useState<Contributor[]>([]);
110112
const [activities, setActivities] = useState<ContributorActivity[]>([]);
@@ -535,7 +537,7 @@ const FloatingContributors: React.FC<FloatingContributorsProps> = ({
535537
{/* Close button */}
536538
<button
537539
className="floating-contributors-close"
538-
onClick={() => setIsVisible(false)}
540+
onClick={() => (onClose ? onClose() : setIsVisible(false))}
539541
aria-label="Close contributors showcase"
540542
>
541543
×
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/* Mock terminal card — light variant by default, dark variant under [data-theme='dark'] */
2+
.mock-terminal {
3+
width: 450px;
4+
max-width: 100%;
5+
border-radius: 16px;
6+
border: 1px solid rgba(0, 0, 0, 0.08);
7+
background: #ffffff;
8+
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.12);
9+
overflow: hidden;
10+
text-align: left;
11+
}
12+
13+
[data-theme="dark"] .mock-terminal {
14+
border: 1px solid rgba(255, 255, 255, 0.14);
15+
background: #131513;
16+
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
17+
}
18+
19+
.mock-terminal__titlebar {
20+
display: flex;
21+
align-items: center;
22+
gap: 8px;
23+
padding: 13px 18px;
24+
background: #f5f6f2;
25+
border-bottom: 1px solid rgba(0, 0, 0, 0.07);
26+
}
27+
28+
[data-theme="dark"] .mock-terminal__titlebar {
29+
background: #181b18;
30+
border-bottom: 1px solid rgba(255, 255, 255, 0.09);
31+
}
32+
33+
.mock-terminal__dot {
34+
width: 11px;
35+
height: 11px;
36+
border-radius: 50%;
37+
flex-shrink: 0;
38+
}
39+
40+
.mock-terminal__dot--red {
41+
background: #ff5f57;
42+
}
43+
44+
.mock-terminal__dot--yellow {
45+
background: #febc2e;
46+
}
47+
48+
.mock-terminal__dot--green {
49+
background: #28c840;
50+
}
51+
52+
.mock-terminal__label {
53+
margin-left: 6px;
54+
font-family: "JetBrains Mono", monospace;
55+
font-size: 12px;
56+
color: rgba(45, 55, 50, 0.55);
57+
}
58+
59+
[data-theme="dark"] .mock-terminal__label {
60+
color: rgba(244, 246, 243, 0.45);
61+
}
62+
63+
.mock-terminal__body {
64+
padding: 24px 22px;
65+
font-family: "JetBrains Mono", monospace;
66+
font-size: 13.5px;
67+
line-height: 2.1;
68+
}
69+
70+
.mock-terminal__prompt {
71+
color: #1fa45b;
72+
}
73+
74+
[data-theme="dark"] .mock-terminal__prompt {
75+
color: #37d67a;
76+
}
77+
78+
.mock-terminal__cmd {
79+
color: #21313c;
80+
}
81+
82+
[data-theme="dark"] .mock-terminal__cmd {
83+
color: #f4f6f3;
84+
}
85+
86+
.mock-terminal__out {
87+
color: rgba(55, 65, 70, 0.62);
88+
}
89+
90+
[data-theme="dark"] .mock-terminal__out {
91+
color: rgba(244, 246, 243, 0.6);
92+
}
93+
94+
.mock-terminal__cursor {
95+
display: inline-block;
96+
width: 9px;
97+
height: 17px;
98+
background: #2fbf71;
99+
vertical-align: text-bottom;
100+
animation: mock-terminal-blink 1.1s infinite;
101+
}
102+
103+
[data-theme="dark"] .mock-terminal__cursor {
104+
background: #37d67a;
105+
}
106+
107+
@keyframes mock-terminal-blink {
108+
0%,
109+
100% {
110+
opacity: 1;
111+
}
112+
50% {
113+
opacity: 0.35;
114+
}
115+
}
116+
117+
@media (max-width: 520px) {
118+
.mock-terminal {
119+
width: 100%;
120+
}
121+
122+
.mock-terminal__body {
123+
font-size: 12px;
124+
padding: 18px 16px;
125+
}
126+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import React from "react";
2+
import "./MockTerminal.css";
3+
4+
const MockTerminal: React.FC = () => {
5+
return (
6+
<div className="mock-terminal" aria-hidden="true">
7+
<div className="mock-terminal__titlebar">
8+
<span className="mock-terminal__dot mock-terminal__dot--red" />
9+
<span className="mock-terminal__dot mock-terminal__dot--yellow" />
10+
<span className="mock-terminal__dot mock-terminal__dot--green" />
11+
<span className="mock-terminal__label">~/recodehive</span>
12+
</div>
13+
<div className="mock-terminal__body">
14+
<div>
15+
<span className="mock-terminal__prompt">$</span>{" "}
16+
<span className="mock-terminal__cmd">
17+
git clone recodehive/recode-website
18+
</span>
19+
</div>
20+
<div className="mock-terminal__out">
21+
Cloning into 'recode-website'… done.
22+
</div>
23+
<div>
24+
<span className="mock-terminal__prompt">$</span>{" "}
25+
<span className="mock-terminal__cmd">
26+
gh issue list --label "good first issue"
27+
</span>
28+
</div>
29+
<div className="mock-terminal__out">#412 · Add SQL joins tutorial</div>
30+
<div className="mock-terminal__out">#398 · Improve Docker intro docs</div>
31+
<div>
32+
<span className="mock-terminal__prompt">$</span>{" "}
33+
<span className="mock-terminal__cmd">
34+
git commit -m "my first contribution 🎉"
35+
</span>
36+
</div>
37+
<div className="mock-terminal__out">→ sponsored: ₹500 this week</div>
38+
<div>
39+
<span className="mock-terminal__prompt">$</span>{" "}
40+
<span className="mock-terminal__cursor" />
41+
</div>
42+
</div>
43+
</div>
44+
);
45+
};
46+
47+
export default MockTerminal;

src/components/header/header.tsx

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import React from "react";
1+
import React, { useState } from "react";
22
import "./header.css";
33
import Link from "@docusaurus/Link";
44
import { motion } from "framer-motion";
55
import FloatingContributors from "../FloatingContributors";
6+
import MockTerminal from "../MockTerminal";
67
import { useCommunityStatsContext } from "../../lib/statsProvider";
78

89
const HeaderStats = () => {
@@ -122,6 +123,8 @@ const HeaderContent = () => {
122123
};
123124

124125
const HeaderToaster = () => {
126+
const [showActivity, setShowActivity] = useState(true);
127+
125128
return (
126129
<motion.div
127130
initial={{ scale: 0, x: 10 }}
@@ -143,14 +146,27 @@ const HeaderToaster = () => {
143146
width: "100%",
144147
}}
145148
>
146-
{/* Render the FloatingContributors component as the header toaster */}
149+
{/* Live Activity by default; mock terminal takes its place once closed */}
147150
<div
148151
style={{
149152
position: "relative",
150153
zIndex: 1,
151154
}}
152155
>
153-
<FloatingContributors headerEmbedded={true} />
156+
{showActivity ? (
157+
<FloatingContributors
158+
headerEmbedded={true}
159+
onClose={() => setShowActivity(false)}
160+
/>
161+
) : (
162+
<motion.div
163+
initial={{ opacity: 0, scale: 0.95 }}
164+
animate={{ opacity: 1, scale: 1 }}
165+
transition={{ duration: 0.5, ease: [0.4, 0, 0.2, 1] }}
166+
>
167+
<MockTerminal />
168+
</motion.div>
169+
)}
154170
</div>
155171
</motion.div>
156172
);

0 commit comments

Comments
 (0)