1+ import { useEffect , useState } from "react" ;
2+ import { Container , Form , Stack , Button } from "react-bootstrap" ;
3+ import SavedArticleItem from "./SaveArticleItem/SavedArticleItem" ;
4+ import ConfirmDeleteModal from "./ConfirmDeleteModal" ;
5+
6+ const test_articles = [
7+ {
8+ id : 0 ,
9+ image :
10+ "https://builtin.com/cdn-cgi/image/f=auto,quality=80,width=752,height=435/https://builtin.com/sites/www.builtin.com/files/styles/byline_image/public/2021-12/machine-learning-examples-applications.png" ,
11+ title : "Intro to Machine Learning" ,
12+ description : "Brief description about this topic..." ,
13+ } ,
14+ {
15+ id : 1 ,
16+ image :
17+ "https://imageio.forbes.com/specials-images/dam/imageserve/966248982/960x0.jpg?height=456&width=711&fit=bounds" ,
18+ title : "Intro to Machine Learning" ,
19+ description : "Brief description about this topic..." ,
20+ } ,
21+ {
22+ id : 2 ,
23+ image :
24+ "https://www.mathworks.com/solutions/machine-learning/_jcr_content/mainParsys/band_copy_1919605364/mainParsys/columns/a03cc495-1c23-4402-82ea-1c8fd4d25234/pictogram.adapt.full.medium.svg/1701252724596.svg" ,
25+ title : "Intro to Machine Learning" ,
26+ description : "Brief description about this topic..." ,
27+ } ,
28+ ] ;
29+
130export default function SavedArticles ( ) {
2- return < h1 > Saved Articles</ h1 > ;
3- }
4-
31+ //array all the articles currently not deleted
32+ const [ articles , setArticles ] = useState ( [ ] ) ;
33+
34+ //the state of the articles of whether they are being deleted or not, is object, key = article id, value = whether it is selected orn ot
35+ const [ isDeletedArticles , setIsDeletedArticles ] = useState ( { } ) ;
36+
37+ //toggler of selected state for a specific article
38+ //this returns a FUNCTION that toggles an article's state with the provided id
39+ const articleToggleHandler = ( id ) => ( ) =>
40+ setIsDeletedArticles ( ( prevArticles ) => {
41+ return { ...prevArticles , [ id ] : ! prevArticles [ id ] } ;
42+ } ) ;
43+
44+ //deselects all articles from deletion
45+ const resetDeletionHandler = ( ) => {
46+ let resetArticles = { } ;
47+ articles . forEach ( ( { id } ) => {
48+ resetArticles [ id ] = false ;
49+ } ) ;
50+ setIsDeletedArticles ( resetArticles ) ;
51+ } ;
52+
53+ //use effect to get articles upon page load once, also init selected state of every article as false
54+ //just simulating retrieving articles
55+ useEffect ( ( ) => {
56+ let initArticles = async ( ) => {
57+ let retrieved_articles = await test_articles ;
58+ setArticles ( retrieved_articles ) ;
59+
60+ let initIsDeletedArticles = { } ;
61+ retrieved_articles . forEach ( ( { id } ) => {
62+ initIsDeletedArticles [ id ] = false ;
63+ } ) ;
64+ setIsDeletedArticles ( initIsDeletedArticles ) ;
65+ } ;
66+
67+ initArticles ( ) ;
68+ } , [ ] ) ;
69+
70+ //submit handler (the yes button in modal does not trigger submit event)
71+ //simply removed the selected articles from the displayed articles state
72+ //insert backend actions here
73+ const submitHandler = ( ) => {
74+ //filter out kept articles, replace articles state with them
75+ let keptArticles = articles . filter (
76+ ( article ) => ! isDeletedArticles [ article . id ]
77+ ) ;
78+ setArticles ( keptArticles ) ;
79+
80+ //reset selected state
81+ let initIsDeletedArticles = { } ;
82+ keptArticles . forEach ( ( { id } ) => {
83+ initIsDeletedArticles [ id ] = false ;
84+ } ) ;
85+ setIsDeletedArticles ( initIsDeletedArticles ) ;
86+ } ;
87+
88+ //state for whether delete confirmation modal is displayed or now
89+ const [ deleteConfirmOpen , setDeleteConfirmOpen ] = useState ( false ) ;
90+
91+ //show and hide handlers
92+ const showDeleteConfirm = ( ) => setDeleteConfirmOpen ( true ) ;
93+ const hideDeleteConfirm = ( ) => setDeleteConfirmOpen ( false ) ;
94+
95+ return (
96+ < Container className = "my-3" >
97+ < Form >
98+ < h4 className = "ps-2 py-1 border-start border-4 border-primary" >
99+ My Bookmarks
100+ </ h4 >
101+ < Container className = "p-0 pt-4" >
102+ { articles . map ( ( article ) => (
103+ < SavedArticleItem
104+ key = { article . id }
105+ articleImg = { article . image }
106+ articleDesc = { article . description }
107+ articleTitle = { article . title }
108+ toBeDeleted = { isDeletedArticles [ article . id ] }
109+ deleteToggler = { articleToggleHandler ( article . id ) }
110+ />
111+ ) ) }
112+ </ Container >
113+ { /*Remove/Cancel will only show if there are any articles selected to be deleted*/ }
114+ { Object . values ( isDeletedArticles ) . some ( ( isDeleted ) => isDeleted ) && (
115+ < Stack
116+ direction = "horizontal"
117+ gap = { 3 }
118+ className = "mt-3 justify-content-end"
119+ >
120+ < div >
121+ < Button
122+ className = "border-0 text-dark fw-medium"
123+ style = { { backgroundColor : "#24BEEF" } }
124+ onClick = { showDeleteConfirm }
125+ >
126+ Remove
127+ </ Button >
128+ </ div >
129+ < div >
130+ < Button
131+ className = "border-0 text-dark fw-medium"
132+ style = { { backgroundColor : "#B9B2B2" } }
133+ onClick = { resetDeletionHandler }
134+ >
135+ Cancel
136+ </ Button >
137+ </ div >
138+ </ Stack >
139+ ) }
140+ < ConfirmDeleteModal
141+ isOpen = { deleteConfirmOpen }
142+ handleClose = { hideDeleteConfirm }
143+ submitHandler = { submitHandler }
144+ />
145+ </ Form >
146+ </ Container >
147+ ) ;
148+ }
0 commit comments