Skip to content

Commit 994dab0

Browse files
committed
feat: add copy button to points system modal
1 parent d13b37f commit 994dab0

1 file changed

Lines changed: 70 additions & 4 deletions

File tree

src/components/HomePointsGuide.tsx

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,61 @@
11
"use client";
22
import { useState, useEffect } from "react";
33
import { createPortal } from "react-dom";
4-
import { Info, X, GitPullRequest, Users } from "lucide-react";
4+
import { Info, X, GitPullRequest, Users, Copy, Check } from "lucide-react";
55
import { ds, fontMono } from "@/lib/ds";
66
import { getLabelChipColors } from "@/lib/labelColors";
77

8+
/* ── Copy text ─────────────────────────────────────────────────── */
9+
const COPY_CONTRIBUTOR = `🌟 GSSoC '26 Contributor Points System 🌟
10+
11+
Base (every approved PR):
12+
gssoc:approved = +50 pts
13+
14+
Difficulty:
15+
level:beginner = 20 pts
16+
level:intermediate = 35 pts
17+
level:advanced = 55 pts
18+
level:critical = 80 pts
19+
20+
Quality Multiplier:
21+
quality:clean = ×1.2
22+
quality:exceptional = ×1.5
23+
24+
Type Bonus:
25+
type:docs = +5 pts
26+
type:testing = +10 pts
27+
type:design = +10 pts
28+
type:refactor = +10 pts
29+
type:bug = +10 pts
30+
type:feature = +10 pts
31+
type:accessibility = +15 pts
32+
type:performance = +15 pts
33+
type:devops = +15 pts
34+
type:security = +20 pts
35+
36+
Blocking Labels:
37+
gssoc:invalid = 0 pts
38+
gssoc:spam = 0 pts
39+
gssoc:ai-slop = 0 pts
40+
41+
Example: gssoc:approved + level:advanced + quality:exceptional + type:devops = 50 + (55 × 1.5) + 15 = 147 pts
42+
Full label guide: https://gssoc.girlscript.org/guidelines/labeling`;
43+
44+
const COPY_MENTOR = `🌟 GSSoC '26 Mentor Points System 🌟
45+
46+
Level Base (per reviewed PR):
47+
level:beginner = 10 pts
48+
level:intermediate = 20 pts
49+
level:advanced = 30 pts
50+
level:critical = 50 pts
51+
52+
Quality Bonus:
53+
quality:clean = +5 pts
54+
quality:exceptional = +10 pts
55+
56+
Example: level:advanced + quality:exceptional = 30 + 10 = 40 pts
57+
Only PRs labeled mentor:username + gssoc:approved are counted.`;
58+
859
/* ── Contributor data ────────────────────────────────────────── */
960
const C_DIFF = [
1061
{ label: "level:beginner", value: "20 pts" },
@@ -161,12 +212,19 @@ function MentorTab() {
161212
/* ── Modal ───────────────────────────────────────────────────── */
162213
function Modal({ onClose }: { onClose: () => void }) {
163214
const [tab, setTab] = useState<"contributor" | "mentor">("contributor");
215+
const [copied, setCopied] = useState(false);
164216

165217
const tabs = [
166218
{ id: "contributor" as const, label: "Contributor", icon: <GitPullRequest size={12} />, accent: ds.primaryDeep, activeBg: "rgba(62,207,142,0.08)", activeBorder: ds.primaryDeep },
167219
{ id: "mentor" as const, label: "Mentor", icon: <Users size={12} />, accent: "#ca8a04", activeBg: "rgba(251,191,36,0.08)", activeBorder: "#ca8a04" },
168220
];
169221

222+
const handleCopy = () => {
223+
navigator.clipboard.writeText(tab === "contributor" ? COPY_CONTRIBUTOR : COPY_MENTOR);
224+
setCopied(true);
225+
setTimeout(() => setCopied(false), 2000);
226+
};
227+
170228
return createPortal(
171229
<div
172230
className="light"
@@ -180,9 +238,17 @@ function Modal({ onClose }: { onClose: () => void }) {
180238
{/* Header */}
181239
<div style={{ padding: "16px 20px 14px", borderBottom: `1px solid ${ds.hairlineCool}`, display: "flex", alignItems: "center", justifyContent: "space-between", flexShrink: 0 }}>
182240
<p style={{ margin: 0, fontSize: 15, fontWeight: 700, color: ds.ink }}>Points System</p>
183-
<button onClick={onClose} style={{ width: 28, height: 28, border: `1px solid ${ds.hairlineCool}`, borderRadius: ds.rSm, background: "transparent", color: ds.inkMute2, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }}>
184-
<X size={14} />
185-
</button>
241+
<div style={{ display: "flex", gap: 8, alignItems: "center" }}>
242+
<button
243+
onClick={handleCopy}
244+
style={{ display: "inline-flex", alignItems: "center", gap: 5, padding: "5px 10px", borderRadius: ds.rSm, border: `1px solid ${copied ? "rgba(62,207,142,0.4)" : ds.hairlineCool}`, background: copied ? "rgba(62,207,142,0.08)" : "transparent", color: copied ? ds.primaryDeep : ds.inkMute2, fontSize: 11, fontWeight: 600, cursor: "pointer", transition: "all 0.15s" }}
245+
>
246+
{copied ? <Check size={12} /> : <Copy size={12} />} {copied ? "Copied" : "Copy"}
247+
</button>
248+
<button onClick={onClose} style={{ width: 28, height: 28, border: `1px solid ${ds.hairlineCool}`, borderRadius: ds.rSm, background: "transparent", color: ds.inkMute2, cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }}>
249+
<X size={14} />
250+
</button>
251+
</div>
186252
</div>
187253

188254
{/* Tabs */}

0 commit comments

Comments
 (0)