Skip to content

Commit 87227b1

Browse files
authored
Merge pull request #69 from React-ChatBotify/react-router-themes
feat: add theme param url behaviour with react-router
2 parents 55380c1 + eab9021 commit 87227b1

File tree

2 files changed

+59
-10
lines changed

2 files changed

+59
-10
lines changed

src/components/Themes/ThemeCard.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,26 @@
1-
import React, { useState } from "react";
1+
import React from "react";
22

33
import Skeleton from "react-loading-skeleton";
44

55
import { Theme } from "../../interfaces/Theme";
66
import { useTranslation } from 'react-i18next';
77
import "../../styles/theme_card.css";
8-
import ThemeModal from "./ThemeModal";
98
import { InfoIcon } from "lucide-react";
109

1110
type Props = {
1211
theme: Theme;
1312
isPreviewed: boolean;
1413
onPreview: (name: string) => void;
1514
isLoading: boolean;
15+
onViewDetails: (theme: Theme) => void
1616
};
1717

1818
/**
1919
* Theme card component to hold the details of each theme in the themes page.
2020
*/
21-
const ThemeCard: React.FC<Props> = ({ theme, isPreviewed, onPreview, isLoading }) => {
22-
const [viewDetails, setViewDetails] = useState(false);
21+
const ThemeCard: React.FC<Props> = ({ theme, isPreviewed, onViewDetails, onPreview, isLoading }) => {
22+
2323

24-
const onViewDetails = () => {
25-
setViewDetails(true);
26-
};
2724

2825
const onClickPreview = () => {
2926
onPreview(theme.name)
@@ -68,7 +65,7 @@ const ThemeCard: React.FC<Props> = ({ theme, isPreviewed, onPreview, isLoading }
6865
</div>
6966
<div className="flex-1 basis-1/6 md:basis-1/6 flex flex-col">
7067
<div className="flex items-center text-blue-500">
71-
<button onClick={onViewDetails} className="text-sm my-4 w-fit mr-[3px]">
68+
<button onClick={()=>(onViewDetails(theme))} className="text-sm my-4 w-fit mr-[3px]">
7269
More Info
7370
</button>
7471
<InfoIcon size={15}/>
@@ -79,7 +76,7 @@ const ThemeCard: React.FC<Props> = ({ theme, isPreviewed, onPreview, isLoading }
7976
</label>
8077
</div>
8178
</div>
82-
<ThemeModal isOpen={viewDetails} theme={theme} onClose={() => setViewDetails(false)} />
79+
8380
</>
8481
);
8582
};

src/pages/Themes.tsx

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import ThemePreview from '../components/Themes/ThemePreview';
1111
import { InfoIcon } from 'lucide-react';
1212

1313
import { useTranslation } from 'react-i18next';
14+
import ThemeModal from '@/components/Themes/ThemeModal';
15+
import { useEffect } from 'react';
16+
import { Theme } from '@/interfaces/Theme';
1417

1518
/**
1619
* Displays themes for users to search, browse and rate.
@@ -26,6 +29,8 @@ const Themes: React.FC = () => {
2629
() => searchParams.get('searchQuery') || ''
2730
);
2831

32+
const [focusedTheme, setFocusedTheme] = useState<null | Theme>(null)
33+
2934
// id of themes being selected to be preview (and applied to the interactive chatbot)
3035
const [previewIds, setPreviewIds] = useState<string[]>([]);
3136

@@ -41,7 +46,47 @@ const Themes: React.FC = () => {
4146
searchQuery
4247
);
4348

44-
console.log(themes);
49+
useEffect(()=>{
50+
//to update the current focused theme based on url and fetched themes
51+
const focusedThemeId = searchParams.get('theme') || '';
52+
if (focusedThemeId == '') {
53+
return;
54+
}
55+
const focusedThemeObject = themes.find(theme => theme.id === focusedThemeId);
56+
if (!focusedThemeObject) {
57+
return
58+
}
59+
setFocusedTheme(focusedThemeObject)
60+
61+
}, [themes])
62+
63+
/**
64+
* Handles the closinf of modal and cleanup of url
65+
*
66+
*/
67+
const modalCloseHandler = () => {
68+
//first update the search params
69+
setSearchParams(params => {
70+
params.delete('theme')
71+
return params;
72+
})
73+
return null;
74+
}
75+
76+
/**
77+
* Handles opening of the modal for a theme, and updates the url accordingly
78+
*
79+
* @param theme the theme to focus on
80+
*/
81+
const modalOpenHandler = (theme: Theme) => {
82+
setSearchParams(params => {
83+
params.set('theme', theme.id)
84+
return params;
85+
})
86+
return theme
87+
}
88+
89+
4590
/**
4691
* Handles setting of search query when user hits enter.
4792
*
@@ -75,6 +120,7 @@ const Themes: React.FC = () => {
75120
return <div>Error: {error.message}</div>;
76121
}
77122

123+
78124
return (
79125
// 92vh comes from 100vh - 8vh (the height of the navbar)
80126
<div className="bg-accent-950 flex h-[92vh] w-full">
@@ -107,11 +153,17 @@ const Themes: React.FC = () => {
107153
isPreviewed={previewIds.includes(theme.id)}
108154
onPreview={() => onPreview(theme.id)}
109155
isLoading={loading}
156+
onViewDetails={(theme) => (setFocusedTheme(modalOpenHandler(theme)))}
110157
/>
111158
);
112159
})}
113160
</div>
114161
</div>
162+
<ThemeModal
163+
isOpen={focusedTheme !== null}
164+
onClose={()=>(setFocusedTheme(modalCloseHandler()))}
165+
theme={focusedTheme as Theme}
166+
/>
115167
{/* Drawer Section */}
116168
<ThemePreview
117169
setPreviewIds={setPreviewIds}

0 commit comments

Comments
 (0)