-
Notifications
You must be signed in to change notification settings - Fork 5
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
19 changed files
with
255 additions
and
93 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
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
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 |
---|---|---|
@@ -1,32 +1,59 @@ | ||
import { useForm, SubmitHandler } from "react-hook-form" | ||
|
||
|
||
import { useUserStore } from "../../Stores/stores" | ||
import api from '../../Api/base' | ||
import { toast } from "react-hot-toast" | ||
import { useNavigate } from "react-router-dom" | ||
import { UploadLogic } from './UploadLogic' | ||
type Inputs = { | ||
Avatar: string | ||
AvatarRequired: string | ||
Avatar: string; | ||
firstName : string ; | ||
lastName : string ; | ||
discreption : string; | ||
email : string; | ||
} | ||
|
||
|
||
const ERROR_MESSAGES = ["Field is required" , "Require min length of " , "Passed max length of"] | ||
const payload_objects = ["firstName","lastName","email","phone","discreption"] | ||
const data_names = ["First name", "Last name", "Email", "Phone", "Bio"]; | ||
export const UploadAvatar = () => { | ||
const userStore = useUserStore(); | ||
const navigate = useNavigate(); | ||
const { | ||
register, | ||
handleSubmit, | ||
formState: { errors }, | ||
} = useForm<Inputs>() | ||
const onSubmit: SubmitHandler<Inputs> = (data) => console.log(data) | ||
|
||
handleSubmit | ||
} = useForm<Inputs>() | ||
const onSubmit: SubmitHandler<any> = async(data) => { | ||
try{ | ||
|
||
toast.promise(api.post("/profile/me",{...data ,finishProfile: true }) , {loading:"Saving user information",success:"Saved successfully",error:"Error on Saving Data"}) | ||
userStore.login(); | ||
navigate("/Home") | ||
}catch(e) | ||
{} | ||
} | ||
const handleError = (errors : any) => { | ||
//eslint-disable-next-line | ||
payload_objects.map((item:any, index : number) =>{ | ||
if (errors[`${item}`]?.type === "required") toast.error(`${data_names[index]} ${ERROR_MESSAGES[0]} `); | ||
if (errors[`${item}`]?.type === "minLength") toast.error(`${data_names[index]} ${ERROR_MESSAGES[1]} 4`); | ||
if (errors[`${item}`]?.type === "maxLength")toast.error(`${data_names[index]} ${ERROR_MESSAGES[2]} 50 `); | ||
}) | ||
|
||
} | ||
|
||
return ( | ||
<form onSubmit={handleSubmit(onSubmit)}> | ||
<input type="file" {...register("Avatar")} /> | ||
|
||
|
||
<input {...register("AvatarRequired", { required: true })} /> | ||
{errors.AvatarRequired && <span>This field is required</span>} | ||
|
||
|
||
<input type="submit" /> | ||
</form> | ||
<> | ||
<form onSubmit={handleSubmit(onSubmit,handleError)} className="flex flex-col max-w-[50vw] gap-8 justify-center items-center"> | ||
<UploadLogic/> | ||
<input type="text" placeholder="First Name " {...register("firstName",{required: true, maxLength: 50 , minLength:4}) } defaultValue={userStore.name.first} className="input input-bordered input-primary w-full max-w-xs" /> | ||
<input type="text" placeholder="Last Name " {...register("lastName",{required: true, maxLength: 50 , minLength:4})} defaultValue={userStore.name.last} className="input input-bordered input-primary w-full max-w-xs" /> | ||
<input type="text" placeholder="Bio" {...register("discreption",{required: true, maxLength: 50 , minLength:4})} defaultValue={userStore.bio} className="input input-bordered input-primary w-full max-w-xs" /> | ||
<input type="text" placeholder="Email " {...register("email",{required:true, pattern: { | ||
value: /\S+@\S+\.\S+/, | ||
message: "Entered value does not match email format", | ||
}})} defaultValue={userStore.email} className="input input-bordered input-primary w-full max-w-xs" /> | ||
|
||
<input className="bg-primary h-12 w-80 rounded-md hover:bg-secondary hover:cursor-pointer transition-colors text-white" type="submit" value="Save" /> | ||
</form> | ||
</> | ||
) | ||
} |
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,47 @@ | ||
import {useRef} from 'react' | ||
import { Avatar } from '../Settings/assets/Avatar' | ||
import { Edit } from '../Settings/assets/Edit' | ||
import { useUserStore } from '../../Stores/stores' | ||
import api from '../../Api/base' | ||
import { toast } from 'react-hot-toast' | ||
export const UploadLogic = () => { | ||
const userStore = useUserStore(); | ||
const inputRef = useRef<any>(); | ||
const handleUploadedFile = async(event:any) => { | ||
const h_size = event.target.files[0].size / 1024; | ||
if (h_size > 5120) | ||
{ | ||
toast.error("uploded avatar is bigger than 5mb") | ||
return Promise.reject("Error"); | ||
} | ||
const formData = new FormData(); | ||
formData.append("image", event.target.files[0]); | ||
|
||
await api.post("/profile/avatar", formData ,{headers:{"Content-Type":"multipart/form-data"}}); | ||
const res = await api.get("/profile/me") | ||
userStore.setAvatar(res?.data?.picture); | ||
|
||
}; | ||
const handleClick = () => { | ||
inputRef?.current?.click(); | ||
|
||
} | ||
return ( | ||
<> | ||
<div className="relative pt-6 "> | ||
<Avatar picture={userStore.picture.medium} /> | ||
<div className="absolute bottom-0 right-0" onClick={handleClick}> | ||
<Edit /> | ||
</div> | ||
</div> | ||
<input type="file" className="hidden" id="picture" onChange={(e) => { | ||
toast.promise(handleUploadedFile(e),{ | ||
loading: "Updating Profile Image", | ||
success:"New Avatar Saved", | ||
error:"Error On Uploading image" | ||
},{position:"top-center",className:"h-20",duration:2000}) | ||
}} ref={inputRef} | ||
/> | ||
</> | ||
) | ||
} |
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
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 |
---|---|---|
@@ -1,10 +1,36 @@ | ||
import {useState , ChangeEvent , useEffect} from 'react' | ||
import {BiSearch} from 'react-icons/bi' | ||
import { SearchResults } from './SearchResults' | ||
|
||
function useDebounce<T>(value: T, delay?: number): T { | ||
const [debouncedValue, setDebouncedValue] = useState<T>(value) | ||
|
||
useEffect(() => { | ||
const timer = setTimeout(() => setDebouncedValue(value), delay || 500) | ||
|
||
return () => { | ||
clearTimeout(timer) | ||
} | ||
}, [value, delay]) | ||
|
||
return debouncedValue | ||
} | ||
|
||
export const Search = () => { | ||
const [searchText, setSearchText] = useState(""); | ||
const DebounceValue = useDebounce(searchText); | ||
const onSearchTextChange = (e: ChangeEvent<HTMLInputElement>) => setSearchText(e.target.value); | ||
|
||
return ( | ||
<div className='hidden sm:flex sm:items-center absolute pr-24 '> | ||
<input type="text" placeholder="Search" className={`input w-44 h-8 md:w-60 mr-4 md:h-12`}/> | ||
<div className='relative right-12 top-0 w-12 '><BiSearch size="1.4em" /></div> | ||
|
||
<div className='dropdown hover:cursor-pointer hidden sm:flex sm:items-center absolute w-80 right-52'> | ||
|
||
<input tabIndex={0} type="text" placeholder="Search" className={`input w-80 h-8 md:w-full mr-4 md:h-12`} onChange={onSearchTextChange} onBlur={() => {setSearchText("")}} onFocus={()=>{setSearchText("")}} value={searchText}/> | ||
|
||
<div className='relative right-14 top-0 w-12 '><BiSearch size="1.4em" /></div> | ||
<ul tabIndex={0} className="dropdown-content z-[9999] menu p-2 shadow bg-base-100 rounded-box w-full top-12"> | ||
<SearchResults query={DebounceValue} /> | ||
</ul> | ||
</div> | ||
) | ||
} |
40 changes: 40 additions & 0 deletions
40
frontend/code/src/Components/Layout/Assets/SearchResults.tsx
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,40 @@ | ||
import { useEffect, useState } from "react" | ||
import api from "../../../Api/base" | ||
import { Link } from "react-router-dom"; | ||
export const SearchResults = (props:any) => { | ||
const [result , setResult] = useState([]); | ||
useEffect(() => | ||
{ | ||
const search = async() => { | ||
try { | ||
const res = await api.get("/users/search",{params:{q:props.query}}) | ||
setResult(res.data) | ||
console.log(res.data) | ||
} catch (error) { | ||
} | ||
} | ||
props.query && search() | ||
},[props.query]) | ||
return ( | ||
<div className="flex flex-col w-full h-full bg-base-100 z-50"> | ||
{ result.length > 0 && result.map((item : any , index : number) => { | ||
return ( | ||
<Link key={index} to={`Profile/${item.id}`}> | ||
<li className="hover:bg-primary hover:rounded-xl transform duration-500 h-full w-full z-[10000]"> | ||
<div className="flex items-center gap-2"> | ||
<div className="avatar"> | ||
<div className="w-auto rounded-full gap-4 ring ring-primary ring-offset-base-100 ring-offset-2"> | ||
<img alt="" src={item.avatar.thumbnail} /> | ||
</div> | ||
</div> | ||
<span >{item.name.first} {item.name.last}</span> | ||
</div> | ||
</li> | ||
</Link> | ||
) | ||
}) | ||
} | ||
{} | ||
</div> | ||
) | ||
} |
Oops, something went wrong.