Skip to content

Commit b9c650a

Browse files
authored
Merge pull request #31 from openpatch/copilot/add-landing-page-web-platform
Add landing page for web platform with hero section, featured maps, and teacher-student use case
2 parents 2b6437c + 1c88575 commit b9c650a

9 files changed

Lines changed: 3518 additions & 2308 deletions

File tree

packages/learningmap/src/ShareDialog.tsx

Lines changed: 104 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { useEditorStore } from "./editorStore";
55
import { useJsonStore } from "./useJsonStore";
66

77
export function ShareDialog() {
8-
const [copied, setCopied] = useState(false);
8+
const [copiedEdit, setCopiedEdit] = useState(false);
9+
const [copiedLearn, setCopiedLearn] = useState(false);
910

1011
// Get state from store
1112
const open = useEditorStore(state => state.shareDialogOpen);
@@ -20,11 +21,25 @@ export function ShareDialog() {
2021

2122
if (!open) return null;
2223

23-
const handleCopyLink = async () => {
24+
// Generate both edit and learn links
25+
const editLink = shareLink;
26+
const learnLink = shareLink.replace(/(#json=.+)/, '/learn$1');
27+
28+
const handleCopyEditLink = async () => {
29+
try {
30+
await navigator.clipboard.writeText(editLink);
31+
setCopiedEdit(true);
32+
setTimeout(() => setCopiedEdit(false), 2000);
33+
} catch (err) {
34+
console.error("Failed to copy link:", err);
35+
}
36+
};
37+
38+
const handleCopyLearnLink = async () => {
2439
try {
25-
await navigator.clipboard.writeText(shareLink);
26-
setCopied(true);
27-
setTimeout(() => setCopied(false), 2000);
40+
await navigator.clipboard.writeText(learnLink);
41+
setCopiedLearn(true);
42+
setTimeout(() => setCopiedLearn(false), 2000);
2843
} catch (err) {
2944
console.error("Failed to copy link:", err);
3045
}
@@ -41,46 +56,93 @@ export function ShareDialog() {
4156
</button>
4257
</header>
4358
<div className="drawer-content">
44-
<p style={{ marginBottom: 16 }}>{t.shareLink}</p>
45-
<div style={{ display: "flex", gap: 8, marginBottom: 16 }}>
46-
<input
47-
type="text"
48-
value={shareLink}
49-
readOnly
59+
<div style={{ marginBottom: 24 }}>
60+
<h3 style={{ fontSize: 14, fontWeight: 600, marginBottom: 8 }}>Edit Link</h3>
61+
<p style={{ fontSize: 13, color: '#666', marginBottom: 12 }}>Share this link to allow others to edit the map</p>
62+
<div style={{ display: "flex", gap: 8, marginBottom: 8 }}>
63+
<input
64+
type="text"
65+
value={editLink}
66+
readOnly
67+
style={{
68+
flex: 1,
69+
padding: "8px 12px",
70+
border: "1px solid #d1d5db",
71+
borderRadius: 4,
72+
fontSize: 14,
73+
fontFamily: "monospace",
74+
}}
75+
onClick={(e) => e.currentTarget.select()}
76+
/>
77+
</div>
78+
<button
79+
onClick={handleCopyEditLink}
80+
className="drawer-button"
5081
style={{
51-
flex: 1,
52-
padding: "8px 12px",
53-
border: "1px solid #d1d5db",
54-
borderRadius: 4,
55-
fontSize: 14,
56-
fontFamily: "monospace",
82+
width: "100%",
83+
display: "flex",
84+
alignItems: "center",
85+
justifyContent: "center",
86+
gap: 8,
5787
}}
58-
onClick={(e) => e.currentTarget.select()}
59-
/>
88+
>
89+
{copiedEdit ? (
90+
<>
91+
<Check size={16} />
92+
{t.linkCopied}
93+
</>
94+
) : (
95+
<>
96+
<Link2 size={16} />
97+
Copy Edit Link
98+
</>
99+
)}
100+
</button>
101+
</div>
102+
103+
<div>
104+
<h3 style={{ fontSize: 14, fontWeight: 600, marginBottom: 8 }}>Learn Link</h3>
105+
<p style={{ fontSize: 13, color: '#666', marginBottom: 12 }}>Share this link for others to learn from the map</p>
106+
<div style={{ display: "flex", gap: 8, marginBottom: 8 }}>
107+
<input
108+
type="text"
109+
value={learnLink}
110+
readOnly
111+
style={{
112+
flex: 1,
113+
padding: "8px 12px",
114+
border: "1px solid #d1d5db",
115+
borderRadius: 4,
116+
fontSize: 14,
117+
fontFamily: "monospace",
118+
}}
119+
onClick={(e) => e.currentTarget.select()}
120+
/>
121+
</div>
122+
<button
123+
onClick={handleCopyLearnLink}
124+
className="drawer-button"
125+
style={{
126+
width: "100%",
127+
display: "flex",
128+
alignItems: "center",
129+
justifyContent: "center",
130+
gap: 8,
131+
}}
132+
>
133+
{copiedLearn ? (
134+
<>
135+
<Check size={16} />
136+
{t.linkCopied}
137+
</>
138+
) : (
139+
<>
140+
<Link2 size={16} />
141+
Copy Learn Link
142+
</>
143+
)}
144+
</button>
60145
</div>
61-
<button
62-
onClick={handleCopyLink}
63-
className="drawer-button"
64-
style={{
65-
width: "100%",
66-
display: "flex",
67-
alignItems: "center",
68-
justifyContent: "center",
69-
gap: 8,
70-
}}
71-
>
72-
{copied ? (
73-
<>
74-
<Check size={16} />
75-
{t.linkCopied}
76-
</>
77-
) : (
78-
<>
79-
<Link2 size={16} />
80-
{t.copyLink}
81-
</>
82-
)}
83-
</button>
84146
</div>
85147
</div>
86148
</>

platforms/web/index.html

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,12 @@
55
<meta charset="UTF-8" />
66
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
77
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8-
<title>Learningmap</title>
8+
<title>Learningmap - Interactive Visual Maps for Teaching and Learning</title>
9+
<meta name="description" content="Create, share, and explore interactive visual learning maps. Perfect for teachers and students. All data stored locally in your browser for privacy and offline access." />
10+
<meta name="keywords" content="learning map, education, teaching, interactive learning, visual learning, roadmap" />
11+
<meta property="og:title" content="Learningmap - Interactive Visual Maps for Teaching and Learning" />
12+
<meta property="og:description" content="Create, share, and explore interactive visual learning maps. Perfect for teachers and students." />
13+
<meta property="og:type" content="website" />
914
</head>
1015

1116
<body>
23.6 KB
Binary file not shown.

platforms/web/src/App.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@ import { BrowserRouter, Routes, Route } from 'react-router-dom';
33
import { LearningMapEditor } from '@learningmap/learningmap';
44
import "@learningmap/learningmap/index.css";
55
import Learn from './Learn';
6+
import Landing from './Landing';
67

78
function App() {
89
return (
910
<BrowserRouter>
1011
<Routes>
11-
<Route path="/" element={<LearningMapEditor jsonStore="https://json.openpatch.org" />} />
12+
<Route path="/" element={<Landing />} />
13+
<Route path="/create" element={<LearningMapEditor jsonStore="https://json.openpatch.org" />} />
1214
<Route path="/learn" element={<Learn />} />
1315
</Routes>
1416
</BrowserRouter>

0 commit comments

Comments
 (0)