Skip to content

Commit

Permalink
[๐Ÿฅ : feat] ํฌ์ŠคํŒ… ๊ฒ€์ƒ‰ํ•˜๊ธฐ (๋ฏธ์™„)
Browse files Browse the repository at this point in the history
  • Loading branch information
sryung1225 committed Dec 14, 2023
1 parent ed4848b commit aed21a1
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 7 deletions.
5 changes: 5 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { auth } from './firebase.ts';
import ProtectedRoute from './components/protected-route.tsx';
import Home from './routes/home.tsx';
import Profile from './routes/profile.tsx';
import SearchResult from './routes/search-result.tsx';
import Auth from './routes/auth.tsx';
import Layout from './components/layout.tsx';
import LoadingScreen from './components/loading-screen.tsx';
Expand All @@ -26,6 +27,10 @@ const router = createBrowserRouter([
path: '/profile',
element: <Profile />,
},
{
path: `/search/:searchKeyword`,
element: <SearchResult />,
},
],
},
{
Expand Down
3 changes: 3 additions & 0 deletions src/assets/images/i-search.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/atoms.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { atom } from 'recoil';

export const searchKeywordAtom = atom({
key: 'searchKeyword',
default: '',
});

export const tmp = '';
54 changes: 54 additions & 0 deletions src/components/search-timeline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { useEffect, useState } from 'react';
import {
collection,
getDocs,
limit,
orderBy,
query,
where,
} from 'firebase/firestore';
import { useRecoilValue } from 'recoil';
import { db } from '../firebase.ts';
import Tweet from './tweet.tsx';
import TimelineWrapper from '../styles/timeline.ts';
import ITweet from '../interfaces/ITweet.ts';
import { searchKeywordAtom } from '../atoms.tsx';

export default function SearchTimeline() {
const [tweets, setTweets] = useState<ITweet[]>([]);
const searchKeyword = useRecoilValue(searchKeywordAtom);
const fetchTweets = async () => {
const tweetsQuery = query(
collection(db, 'tweets'),
orderBy('tweet'),
where('tweet', '>=', searchKeyword),
orderBy('createdAt', 'desc'),
limit(25),
);
const snapshot = await getDocs(tweetsQuery);
const tweetList = snapshot.docs.map((doc) => {
const { userId, userName, tweet, createdAt, photo } = doc.data();
return {
userId,
userName,
tweet,
createdAt,
photo,
id: doc.id,
};
});
setTweets(tweetList);
};
useEffect(() => {
fetchTweets();
}, [searchKeyword]);
return (
<TimelineWrapper>
{tweets.length !== 0 ? (
tweets.map((tweet) => <Tweet key={tweet.id} {...tweet} />)
) : (
<p>๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.</p>
)}
</TimelineWrapper>
);
}
24 changes: 19 additions & 5 deletions src/components/search.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
import React, { useState } from 'react';
import React from 'react';
import { useRecoilState } from 'recoil';
import { useNavigate } from 'react-router-dom';
import { searchKeywordAtom } from '../atoms.tsx';
import WindowTop from './window-top.tsx';
import * as W from '../styles/window.ts';
import * as S from '../styles/search.ts';
import { ReactComponent as IconSearch } from '../assets/images/i-search.svg';

export default function Search() {
const [searchKeyword, setSearchKeyword] = useState('');
const navigate = useNavigate();
const [searchKeyword, setSearchKeyword] = useRecoilState(searchKeywordAtom);
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearchKeyword(e.target.value);
};
const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (searchKeyword === '') return;
setSearchKeyword(searchKeyword);
navigate(`/search/searchKeyword=${searchKeyword}`);
};
return (
<W.Window>
<WindowTop />
<S.Form>
<S.Form onSubmit={onSubmit}>
<S.FormInput
onChange={onChange}
name="searchKeyword"
value={searchKeyword}
placeholder="๊ฒ€์ƒ‰ํ•˜๊ธฐ"
placeholder="๊ฒ€์ƒ‰์–ด ์ž…๋ ฅ"
type="text"
required
></S.FormInput>
<button type="submit">๊ฒ€์ƒ‰</button>
<S.FormButton type="submit">
<span className="a11yHidden">๊ฒ€์ƒ‰ํ•˜๊ธฐ</span>
<IconSearch />
</S.FormButton>
</S.Form>
</W.Window>
);
Expand Down
11 changes: 10 additions & 1 deletion src/routes/search-result.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import SearchTimeline from '../components/search-timeline.tsx';
import WindowTop from '../components/window-top.tsx';
import * as W from '../styles/window.ts';

export default function SearchResult() {
return null;
return (
<W.Window>
<WindowTop />
<SearchTimeline />
</W.Window>
);
}
21 changes: 20 additions & 1 deletion src/styles/search.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
import { styled } from 'styled-components';
import { Input } from './button.ts';
import { grayColor } from './global.ts';

export const Form = styled.form`
position: relative;
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
max-width: 500px;
`;

export const FormInput = styled(Input)``;
export const FormInput = styled(Input)`
padding-right: 50px;
`;

export const FormButton = styled.button`
position: absolute;
top: 3px;
right: 3px;
bottom: 3px;
height: 37px;
width: 37px;
background-color: transparent;
border-radius: 50%;
border: none;
svg {
stroke: ${grayColor};
}
`;

0 comments on commit aed21a1

Please sign in to comment.