Skip to content

Commit 10a6f3d

Browse files
authored
Merge pull request #8 from febinbellamy/add-functionality-to-customize-repo-structure
Add functionality to customize repo structure
2 parents 57e2d5a + 2b51db5 commit 10a6f3d

8 files changed

Lines changed: 360 additions & 7 deletions

File tree

assets/languageLevelProblem.png

112 KB
Loading

assets/levelLanguageProblem.png

109 KB
Loading

assets/levelProblemLanguage.png

107 KB
Loading

css/welcome.css

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,179 @@ footer {
217217
transform: translateX(0);
218218
}
219219
}
220+
221+
.modal {
222+
display: none;
223+
position: fixed;
224+
z-index: 1000;
225+
left: 0;
226+
top: 0;
227+
width: 100%;
228+
height: 100%;
229+
background-color: rgba(0, 0, 0, 0.8);
230+
}
231+
232+
.modal-content {
233+
background-color: #2a2b35;
234+
margin: 2% auto;
235+
padding: 0;
236+
border-radius: 10px;
237+
width: 90%;
238+
max-width: 600px;
239+
max-height: 90vh;
240+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
241+
color: white;
242+
display: flex;
243+
flex-direction: column;
244+
overflow: hidden;
245+
}
246+
247+
.modal-header {
248+
display: flex;
249+
justify-content: center;
250+
align-items: center;
251+
padding: 15px 30px;
252+
border-bottom: 1px solid #444;
253+
position: relative;
254+
flex-shrink: 0;
255+
}
256+
257+
.modal-header h2 {
258+
margin: 0;
259+
font-size: 28px;
260+
color: white;
261+
}
262+
263+
.close {
264+
color: #aaa;
265+
font-size: 35px;
266+
font-weight: bold;
267+
cursor: pointer;
268+
transition: color 0.2s ease;
269+
position: absolute;
270+
top: 20px;
271+
right: 30px;
272+
}
273+
274+
.close:hover,
275+
.close:focus {
276+
color: rgba(229, 44, 55, 255);
277+
}
278+
279+
.modal-body {
280+
padding: 20px 30px;
281+
line-height: 1.6;
282+
flex: 1;
283+
overflow-y: auto;
284+
}
285+
286+
.modal-body h3 {
287+
margin-top: 0;
288+
margin-bottom: 15px;
289+
font-size: 24px;
290+
color: rgb(76, 190, 228);
291+
}
292+
293+
.modal-body p {
294+
font-size: 16px;
295+
margin-bottom: 20px;
296+
color: #ddd;
297+
}
298+
299+
.folder-option {
300+
margin-bottom: 15px;
301+
padding: 6px;
302+
border: 2px solid #444;
303+
border-radius: 8px;
304+
transition: border-color 0.3s ease;
305+
}
306+
307+
.folder-option:hover {
308+
border-color: rgb(76, 190, 228);
309+
}
310+
311+
.folder-option:has(input[type="radio"]:checked),
312+
.folder-option.selected {
313+
border-color: rgb(76, 190, 228);
314+
background-color: rgba(76, 190, 228, 0.1);
315+
}
316+
317+
.folder-option input[type="radio"] {
318+
margin-right: 12px;
319+
transform: scale(1.3);
320+
}
321+
322+
.folder-option label {
323+
cursor: pointer;
324+
display: block;
325+
font-size: 18px;
326+
padding: 0;
327+
}
328+
329+
.folder-option label strong {
330+
color: white;
331+
font-size: 20px;
332+
}
333+
334+
.modal-footer {
335+
padding: 20px 30px;
336+
border-top: 1px solid #444;
337+
text-align: right;
338+
}
339+
340+
#save-settings-btn {
341+
background-color: rgb(76, 190, 228);
342+
color: white;
343+
border: none;
344+
padding: 12px 25px;
345+
font-size: 18px;
346+
border-radius: 5px;
347+
cursor: pointer;
348+
transition: all 0.2s ease;
349+
font-weight: bold;
350+
}
351+
352+
#save-settings-btn:hover {
353+
background-color: rgb(56, 170, 208);
354+
transform: scale(1.05);
355+
}
356+
357+
#settings-icon {
358+
cursor: pointer;
359+
}
360+
361+
@media (max-width: 768px) {
362+
.modal-content {
363+
width: 95%;
364+
margin: 10% auto;
365+
}
366+
367+
.modal-header,
368+
.modal-body,
369+
.modal-footer {
370+
padding: 20px;
371+
}
372+
373+
.modal-header h2 {
374+
font-size: 24px;
375+
}
376+
377+
.modal-body h3 {
378+
font-size: 20px;
379+
}
380+
381+
.folder-option label strong {
382+
font-size: 18px;
383+
}
384+
}
385+
386+
.folder-option img {
387+
display: block;
388+
max-width: 100%;
389+
width: 100%;
390+
height: auto;
391+
margin-top: 4px;
392+
margin-bottom: 4px;
393+
border-radius: 8px;
394+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
395+
}

scripts/background.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ chrome.runtime.onInstalled.addListener(({ reason }) => {
2222
chrome.storage.local.set({
2323
isUserAuthenticated: false,
2424
isRepoConnected: false,
25+
folderStructure: "level-problem-language",
2526
});
2627
}
2728
chrome.runtime.setUninstallURL(
@@ -187,6 +188,7 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
187188
directory,
188189
rank,
189190
directoryName,
191+
languageOfUserSolution,
190192
encodedReadMe,
191193
accessToken
192194
);
@@ -197,6 +199,7 @@ chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
197199
rank,
198200
directoryName,
199201
fileName,
202+
languageOfUserSolution,
200203
encodedSolution,
201204
accessToken
202205
);

scripts/codewarsToGithub.js

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,67 @@ const checkFileExists = async (baseUrl, accessToken) => {
8989
};
9090
};
9191

92+
const getUrl = (
93+
githubUsername,
94+
repo,
95+
directory,
96+
rank,
97+
directoryName,
98+
fileName,
99+
languageOfUserSolution,
100+
isReadmeFile,
101+
folderStructure
102+
) => {
103+
let url = `https://api.github.com/repos/${githubUsername}/${repo}/contents/${
104+
directory ? directory + "/" : ""
105+
}`;
106+
107+
if (folderStructure === "level-problem-language") {
108+
return (
109+
url + `${rank}/${directoryName}/${isReadmeFile ? "README.md" : fileName}`
110+
);
111+
} else if (folderStructure === "language-level-problem") {
112+
return (
113+
url +
114+
`${languageOfUserSolution}/${rank}/${directoryName}/${
115+
isReadmeFile ? "README.md" : fileName
116+
}`
117+
);
118+
} else if (folderStructure === "level-language-problem") {
119+
return (
120+
url +
121+
`${rank}/${languageOfUserSolution}/${directoryName}/${
122+
isReadmeFile ? "README.md" : fileName
123+
}`
124+
);
125+
}
126+
};
127+
92128
const addOrUpdateSolution = async (
93129
githubUsername,
94130
repo,
95131
directory,
96132
rank,
97133
directoryName,
98134
fileName,
135+
languageOfUserSolution,
99136
encodedSolution,
100137
accessToken
101138
) => {
102-
const url = `https://api.github.com/repos/${githubUsername}/${repo}/contents/${
103-
directory ? directory + "/" : ""
104-
}${rank}/${directoryName}/${fileName}`;
139+
const { folderStructure = "level-problem-language" } =
140+
await chrome.storage.local.get("folderStructure");
141+
142+
const url = getUrl(
143+
githubUsername,
144+
repo,
145+
directory,
146+
rank,
147+
directoryName,
148+
fileName,
149+
languageOfUserSolution,
150+
false,
151+
folderStructure
152+
);
105153

106154
const { fileExists, data: fileData } = await checkFileExists(
107155
url,
@@ -141,7 +189,7 @@ const addOrUpdateSolution = async (
141189
);
142190
return { success: true };
143191
} catch (error) {
144-
console.log("Error pushing codewars solution to Github!");
192+
console.log("Error pushing codewars solution to GitHub!");
145193
return { success: false, error: error.message };
146194
}
147195
};
@@ -152,12 +200,24 @@ const addReadme = async (
152200
directory,
153201
rank,
154202
directoryName,
203+
languageOfUserSolution,
155204
encodedReadMe,
156205
accessToken
157206
) => {
158-
const url = `https://api.github.com/repos/${githubUsername}/${repo}/contents/${
159-
directory ? directory + "/" : ""
160-
}${rank}/${directoryName}/README.md`;
207+
const { folderStructure = "level-problem-language" } =
208+
await chrome.storage.local.get("folderStructure");
209+
210+
const url = getUrl(
211+
githubUsername,
212+
repo,
213+
directory,
214+
rank,
215+
directoryName,
216+
"README.md",
217+
languageOfUserSolution,
218+
true,
219+
folderStructure
220+
);
161221

162222
const { fileExists } = await checkFileExists(url, accessToken);
163223
if (fileExists) {

scripts/welcome.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,22 @@ const repoConnectedSection = document.querySelector("#repo-connected");
88
const aTagForRepoUrl = document.querySelector("#repo-url");
99
const aTagforUnlinkRepo = document.querySelector("#unlink-repo");
1010
const starCodeHubButton = document.querySelector("#star-repo-button");
11+
const settingsIcon = document.querySelector("#settings-icon");
12+
const settingsModal = document.querySelector("#settings-modal");
13+
const saveSettingsBtn = document.querySelector("#save-settings-btn");
14+
const closeModal = document.querySelector(".close");
15+
16+
document.addEventListener("DOMContentLoaded", () => {
17+
chrome.storage.local.get("folderStructure", (result) => {
18+
const saved = result.folderStructure || "level-problem-language";
19+
const radio = document.querySelector(
20+
`input[name="folder-structure"][value="${saved}"]`
21+
);
22+
if (radio) {
23+
radio.checked = true;
24+
}
25+
});
26+
});
1127

1228
authButton.addEventListener("click", () => {
1329
chrome.runtime.sendMessage({ action: "authenticateUser" });
@@ -21,6 +37,29 @@ starCodeHubButton.addEventListener("click", () => {
2137
window.open("http://www.github.com/febinbellamy/codehub", "_blank").focus();
2238
});
2339

40+
settingsIcon.addEventListener("click", () => {
41+
settingsModal.style.display = "block";
42+
});
43+
44+
saveSettingsBtn.addEventListener("click", () => {
45+
const selected = document.querySelector(
46+
'input[name="folder-structure"]:checked'
47+
).value;
48+
chrome.storage.local.set({ folderStructure: selected }, () => {
49+
settingsModal.style.display = "none";
50+
});
51+
});
52+
53+
closeModal.addEventListener("click", () => {
54+
settingsModal.style.display = "none";
55+
});
56+
57+
window.addEventListener("click", (event) => {
58+
if (event.target === settingsModal) {
59+
settingsModal.style.display = "none";
60+
}
61+
});
62+
2463
getStartedButton.addEventListener("click", () => {
2564
const selectedOption = document.querySelector("#repo-options").value;
2665
const userInput = document.querySelector("#user-input").value;

0 commit comments

Comments
 (0)