-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
366 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// TagInput.tsx | ||
import React, { useEffect, useState } from "react"; | ||
import Autocomplete from "@mui/material/Autocomplete"; | ||
import TextField from "@mui/material/TextField"; | ||
import TAGS from "../../../lib/constants/TAGS"; | ||
import { Button, Chip, Stack, Typography } from "@mui/material"; | ||
import useEditorContent from "../../../lib/store/useEditorContent"; | ||
|
||
interface BlogTagTypes { | ||
tags: string[]; | ||
} | ||
|
||
const TagInput: React.FC = () => { | ||
const [tags, setTags] = useState<string[]>([]); | ||
const [tagInput, setTagInput] = useState<string>(""); | ||
|
||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment | ||
const [blog, setBlog] = useEditorContent((state: any) => [ state.blog as BlogTagTypes,state.setBlog,]); | ||
// const onTagsChnage = (e: React.ChangeEvent<HTMLInputElement>) => { | ||
|
||
// } | ||
|
||
const handleTagInputChange = (event: React.ChangeEvent<HTMLInputElement>) => { | ||
setTagInput(event.target.value); | ||
}; | ||
|
||
console.log("tags", tags); | ||
const handleAddTag = () => { | ||
if (tagInput.trim() !== "" && !tags.includes(tagInput)) { | ||
setTags([...tags, tagInput]); | ||
setTagInput(""); | ||
} | ||
}; | ||
|
||
const handleAutocompleteChange = ( | ||
event: React.SyntheticEvent, | ||
value: string | null | ||
) => { | ||
console.log("value", event); | ||
if (value) { | ||
setTags([...tags, value]); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call | ||
setBlog({ ...blog, tags: tags }); | ||
}, [tags]); | ||
|
||
const handleDeleteTag = (tagToDelete: string) => { | ||
setTags(tags.filter((tag) => tag !== tagToDelete)); | ||
}; | ||
|
||
return ( | ||
<Stack gap={3} justifyContent={"center"} alignItems={"center"}> | ||
<Typography>Select category/categories</Typography> | ||
<Stack direction={"row"} gap={1}> | ||
<Autocomplete | ||
freeSolo | ||
sx={{ | ||
width: "400px", | ||
}} | ||
options={[...tags, ...TAGS]} | ||
renderInput={(params) => ( | ||
<TextField | ||
{...params} | ||
variant="outlined" | ||
label="Tags" | ||
placeholder="Enter tags" | ||
value={tagInput} | ||
onChange={handleTagInputChange} | ||
onKeyDown={(e) => { | ||
if (e.key === "Enter") { | ||
e.preventDefault(); | ||
handleAddTag(); | ||
} | ||
}} | ||
/> | ||
)} | ||
onChange={handleAutocompleteChange} | ||
/> | ||
<Button | ||
variant="contained" | ||
sx={{ color: "white", background: "#474747" }} | ||
onClick={handleAddTag} | ||
> | ||
Add Tag | ||
</Button> | ||
</Stack> | ||
<Stack direction={"row"} width={"500px"} flexWrap={"wrap"} gap={"4px"}> | ||
{tags.map((tag, index) => ( | ||
<Chip | ||
key={index} | ||
label={tag} | ||
onDelete={() => handleDeleteTag(tag)} | ||
sx={{ | ||
background: "#474747", | ||
color: "white", | ||
borderRadius: "14px", | ||
padding: "5px 10px", | ||
"& .MuiChip-deleteIcon": { | ||
color: "white", // Change this to the desired color for the delete icon | ||
}, | ||
}} | ||
/> | ||
))} | ||
</Stack> | ||
</Stack> | ||
); | ||
}; | ||
|
||
export default TagInput; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { CircularProgress, Stack, Typography } from '@mui/material' | ||
import { useEffect } from 'react' | ||
import APIMethods from '../../../lib/axios/api' | ||
import useLoadingStore from '../../../lib/store/useLoading' | ||
import { blogTypes } from '../../blog/types/blogTypes' | ||
import useSearchStore from '../../../lib/store/useSearchStore' | ||
import { useState } from 'react' | ||
import Blog from './Blog' | ||
|
||
export default function SearchedBlogs() { | ||
|
||
const { isLoading, setIsLoading } = useLoadingStore(); | ||
const [blogs,setBlogs] = useState<blogTypes[]>([]); | ||
const {searchItem} = useSearchStore(); | ||
|
||
const fetchSearchedBlogs = async () => { | ||
try { | ||
setIsLoading(true); | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call | ||
await APIMethods.blog.getBlogsByTag(searchItem).then((res:{data:{blogs:any}}) => { | ||
const blogsRes = res.data.blogs as blogTypes[]; | ||
setBlogs(blogsRes); | ||
console.log("searched blogs",blogsRes); | ||
}); | ||
|
||
} catch (error) { | ||
console.log(error); | ||
} | ||
} | ||
|
||
|
||
useEffect(() => { | ||
fetchSearchedBlogs().then(() => { | ||
console.log("fetching done"); | ||
}).catch((err) => { | ||
console.log(err); | ||
}).finally(() => { | ||
console.log("finally",blogs); | ||
setIsLoading(false); | ||
} | ||
); | ||
}, [searchItem]) | ||
|
||
useEffect(() => { | ||
if(!blogs || blogs.length === 0) { | ||
return; | ||
} | ||
else | ||
{ | ||
setIsLoading(false); | ||
} | ||
}, [blogs]) | ||
|
||
return ( | ||
<Stack paddingTop={5} width={'100%'} padding={5}> | ||
{ | ||
isLoading ? <Stack justifyContent={'center'} alignItems={'center'} width={'100%'} height={'100%'} border={2} flexGrow={1}> | ||
<CircularProgress /> | ||
</Stack> | ||
: | ||
<Stack> | ||
{blogs.length!=0 && blogs.map((blog, index) => ( | ||
<Blog | ||
key={index} | ||
blogId={blog._id} | ||
author={blog.authorName} | ||
date={blog.date} | ||
title={blog.title} | ||
tags={blog.tags} | ||
image={blog.coverImageURL} | ||
likes={blog.likes} | ||
/> | ||
))} | ||
</Stack> | ||
} | ||
{ | ||
!isLoading && blogs.length === 0 && <Typography variant='h5'>No blogs found</Typography> | ||
} | ||
</Stack> | ||
) | ||
} |
Oops, something went wrong.