diff --git a/src/components/FrameRenderer/FrameRenderer.astro b/src/components/FrameRenderer/FrameRenderer.astro
index 6c274de9a..d050be9c2 100644
--- a/src/components/FrameRenderer/FrameRenderer.astro
+++ b/src/components/FrameRenderer/FrameRenderer.astro
@@ -27,4 +27,4 @@ const { resourceId, resourceType, jsonUrl, dimensions = null } = Astro.props;
-
+
diff --git a/src/components/FrameRenderer/renderer.js b/src/components/FrameRenderer/renderer.ts
similarity index 66%
rename from src/components/FrameRenderer/renderer.js
rename to src/components/FrameRenderer/renderer.ts
index a5e769f95..1719c4ba7 100644
--- a/src/components/FrameRenderer/renderer.js
+++ b/src/components/FrameRenderer/renderer.ts
@@ -1,9 +1,18 @@
import { wireframeJSONToSVG } from 'roadmap-renderer';
-import Cookies from 'js-cookie';
-import { TOKEN_COOKIE_NAME } from '../../lib/jwt.ts';
-import { httpGet } from '../../lib/http.ts';
+import {
+ renderResourceProgress,
+ ResourceType,
+} from '../../lib/resource-progress';
export class Renderer {
+ resourceId: string;
+ resourceType: string;
+ jsonUrl: string;
+ loaderHTML: string | null;
+
+ containerId: string;
+ loaderId: string;
+
constructor() {
this.resourceId = '';
this.resourceType = '';
@@ -35,83 +44,64 @@ export class Renderer {
}
// Clone it so we can use it later
- this.loaderHTML = this.loaderEl.innerHTML;
+ this.loaderHTML = this.loaderEl!.innerHTML;
const dataset = this.containerEl.dataset;
- this.resourceType = dataset.resourceType;
- this.resourceId = dataset.resourceId;
- this.jsonUrl = dataset.jsonUrl;
+ this.resourceType = dataset.resourceType!;
+ this.resourceId = dataset.resourceId!;
+ this.jsonUrl = dataset.jsonUrl!;
return true;
}
- async loadProgress() {
- const token = Cookies.get(TOKEN_COOKIE_NAME);
- if (!token) {
- return;
- }
-
- const { response, error } = await httpGet(
- `${import.meta.env.PUBLIC_API_URL}/v1-get-user-resource-progress`,
- {
- resourceId: this.resourceId,
- resourceType: this.resourceType,
- }
- );
-
- if (!response) {
- console.error(error);
- return;
- }
-
- const { done } = response;
- done.forEach((topic) => {
- const topicEl = document.querySelector(`[data-group-id$="-${topic}"]`);
-
- if (topicEl) {
- topicEl.classList.add('done');
- }
- });
- }
-
/**
* @param { string } jsonUrl
* @returns {Promise}
*/
- jsonToSvg(jsonUrl) {
+ jsonToSvg(jsonUrl: string) {
if (!jsonUrl) {
console.error('jsonUrl not defined in frontmatter');
return null;
}
- this.containerEl.innerHTML = this.loaderHTML;
- return Promise.all([
- fetch(jsonUrl)
- .then((res) => {
- return res.json();
- })
- .then((json) => {
- return wireframeJSONToSVG(json, {
- fontURL: '/fonts/balsamiq.woff2',
- });
- })
- .then((svg) => {
- this.containerEl.replaceChildren(svg);
- })
- .catch((error) => {
- const message = `
+ if (!this.containerEl) {
+ return null;
+ }
+
+ this.containerEl.innerHTML = this.loaderHTML!;
+
+ return fetch(jsonUrl)
+ .then((res) => {
+ return res.json();
+ })
+ .then((json) => {
+ return wireframeJSONToSVG(json, {
+ fontURL: '/fonts/balsamiq.woff2',
+ });
+ })
+ .then((svg) => {
+ this.containerEl?.replaceChildren(svg);
+ })
+ .then(() => {
+ return renderResourceProgress(
+ this.resourceType as ResourceType,
+ this.resourceId
+ );
+ })
+ .catch((error) => {
+ if (!this.containerEl) {
+ return;
+ }
+
+ const message = `
There was an error.
Try loading the page again. or submit an issue on GitHub with following:
${error.message}
${error.stack}
`;
-
- this.containerEl.innerHTML = `${message}
`;
- }),
-
- this.loadProgress(),
- ]);
+ this.containerEl.innerHTML = `${message}
`;
+ });
}
onDOMLoaded() {
@@ -129,16 +119,16 @@ export class Renderer {
}
}
- switchRoadmap(newJsonUrl) {
- const newJsonFileSlug = newJsonUrl.split('/').pop().replace('.json', '');
+ switchRoadmap(newJsonUrl: string) {
+ const newJsonFileSlug = newJsonUrl.split('/').pop()?.replace('.json', '');
// Update the URL and attach the new roadmap type
if (window?.history?.pushState) {
- const url = new URL(window.location);
+ const url = new URL(window.location.href);
const type = this.resourceType[0]; // r for roadmap, b for best-practices
url.searchParams.delete(type);
- url.searchParams.set(type, newJsonFileSlug);
+ url.searchParams.set(type, newJsonFileSlug!);
window.history.pushState(null, '', url.toString());
}
@@ -154,13 +144,13 @@ export class Renderer {
label: `${newJsonFileSlug}`,
});
- this.jsonToSvg(newJsonUrl).then(() => {
- this.containerEl.setAttribute('style', '');
+ this.jsonToSvg(newJsonUrl)?.then(() => {
+ this.containerEl?.setAttribute('style', '');
});
}
- handleSvgClick(e) {
- const targetGroup = e.target.closest('g') || {};
+ handleSvgClick(e: any) {
+ const targetGroup = e.target?.closest('g') || {};
const groupId = targetGroup.dataset ? targetGroup.dataset.groupId : '';
if (!groupId) {
return;
diff --git a/src/components/Setting/UpdatePasswordForm.tsx b/src/components/Setting/UpdatePasswordForm.tsx
index 8d1d2af00..8608d145d 100644
--- a/src/components/Setting/UpdatePasswordForm.tsx
+++ b/src/components/Setting/UpdatePasswordForm.tsx
@@ -59,13 +59,6 @@ export default function UpdatePasswordForm() {
);
if (error || !response) {
- if (error?.status === 401) {
- Cookies.remove(TOKEN_COOKIE_NAME);
- window.location.reload();
-
- return;
- }
-
setIsLoading(false);
setError(error?.message || 'Something went wrong');
diff --git a/src/components/Setting/UpdateProfileForm.tsx b/src/components/Setting/UpdateProfileForm.tsx
index c9c4cabf5..2628d9787 100644
--- a/src/components/Setting/UpdateProfileForm.tsx
+++ b/src/components/Setting/UpdateProfileForm.tsx
@@ -52,13 +52,6 @@ export function UpdateProfileForm() {
);
if (error || !response) {
- if (error?.status === 401) {
- Cookies.remove(TOKEN_COOKIE_NAME);
- window.location.reload();
-
- return;
- }
-
setIsLoading(false);
setError(error?.message || 'Something went wrong');
diff --git a/src/lib/http.ts b/src/lib/http.ts
index 3bba87272..79f5dc103 100644
--- a/src/lib/http.ts
+++ b/src/lib/http.ts
@@ -55,6 +55,12 @@ export async function httpCall<
};
}
+ // Logout user if token is invalid
+ if (data.status === 401) {
+ Cookies.remove(TOKEN_COOKIE_NAME);
+ window.location.reload();
+ }
+
return {
response: undefined,
error: data as ErrorType,
diff --git a/src/lib/resource-progress.ts b/src/lib/resource-progress.ts
index e98d6df95..c4e0d8733 100644
--- a/src/lib/resource-progress.ts
+++ b/src/lib/resource-progress.ts
@@ -49,15 +49,19 @@ export async function getResourceProgress(
resourceType: 'roadmap' | 'best-practice',
resourceId: string
): Promise {
+ // No need to load progress if user is not logged in
+ if (!Cookies.get(TOKEN_COOKIE_NAME)) {
+ return [];
+ }
+
const progressKey = `${resourceType}-${resourceId}-progress`;
+
const rawProgress = localStorage.getItem(progressKey);
const progress = JSON.parse(rawProgress || 'null');
const progressTimestamp = progress?.timestamp;
const diff = new Date().getTime() - parseInt(progressTimestamp || '0', 10);
- const isProgressExpired = diff > 10 * 60 * 1000; // 10 minutes
-
- console.log(progressKey);
+ const isProgressExpired = diff > 15 * 60 * 1000; // 15 minutes
if (!progress || isProgressExpired) {
return loadFreshProgress(resourceType, resourceId);
@@ -79,13 +83,6 @@ async function loadFreshProgress(
);
if (error) {
- if (error.status === 401) {
- Cookies.remove(TOKEN_COOKIE_NAME);
- window.location.reload();
-
- return [];
- }
-
console.error(error);
return [];
}