### 代碼倉
[https://github.com/WilsonCode1224/Anime-search](https://github.com/WilsonCode1224/Anime-search)
### 待修正事項:
- 11/20 待修正事項:
- [x] isSearch 應該要用 dispatch
- [x] HomePage 用 Map
- [x] AnimaItem map
- [x] Iframe 意義
- [x] Upcoming render() + map問題 (目前合併起來解決。)
- [x] 額外 濃縮成一個 component Airing/Popular/UpComing
### 11/20 工作日誌:
1. 11:30 ~ 12:00 - 調整 網址 URL 結構。
2. 12:00 ~ 12:30 - HomePage 用 Map。
```jsx
// 2. Header Button
const HeaderButtons = (setRendered, getAiringAnime, getUpcomingAnime) => [
{
label: "Popular",
onClick: () => {
setRendered("popular");
},
icon: <i className="fas fa-fire" />,
},
{
label: "Airing",
onClick: () => {
setRendered("airing");
getAiringAnime();
},
},
{
label: "Upcoming",
onClick: () => {
setRendered("upcoming");
getUpcomingAnime();
},
},
];
// render
{buttons.map((button, index) => (
<div key={index} className={button.className}>
<button onClick={button.onClick}>
{button.icon}
{button.label}
</button>
</div>
))}
```
3. 12:30 ~ 13:00 - AnimaItem map
```jsx
const detailsData = [
{ label: "Aired", data: aired?.string },
{ label: "Rating", data: rating },
{ label: "Rank", data: rank },
{ label: "Score", data: score },
{ label: "Scored By", data: scored_by },
{ label: "Popularity", data: popularity },
{ label: "Status", data: status },
{ label: "Source", data: source },
{ label: "Season", data: season },
{ label: "Duration", data: duration },
];
// render
<div className="anime-details">
{detailsData.map((detail, index) => (
<p key={index}>
<span>{detail.label}</span>
<span>{detail.data}</span>
</p>
))}
</div>
```
4. 13:00 ~ 13:30 Iframe 是什麼東西?
- iframe,是一個 HTML 標籤。
用來嵌入其他 HTML 文件或外部網頁。
- 在該專案也有使用到這個 Tag:
使用來嵌入動畫的預告片(trailer)。
這樣的做法使得動畫的預告片可以直接在你的網頁上播放,而不需要跳轉到其他頁面或網站。
```jsx
<div className="trailer-con">
{trailer?.embed_url ? (
<iframe
src={trailer?.embed_url}
title="Inline Frame Example"
width="800"
height="450"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
></iframe>
) : (
<h3>Trailer not available</h3>
)}
</div>
```
5. 13:40 ~ 14:15 isSearch 應該要用 dispatch
```jsx
// add actions
// actions
const LOADING = "LOADING";
const SEARCH = "SEARCH";
const GET_POPULAR_ANIME = "GET_POPULAR_ANIME";
const GET_UPCOMING_ANIME = "GET_UPCOMING_ANIME";
const GET_AIRING_ANIME = "GET_AIRING_ANIME";
const GET_PICTURES = "GET_PICTURES";
const IS_SEARCH = "IS_SEARCH"; // 1
const IS_NOT_SEARCHING = "IS_NOT_SEARCHING"; // 2
// actions type
// reducer
const reducer = (state, action) => {
switch (action.type) {
case LOADING:
return { ...state, loading: true };
case GET_POPULAR_ANIME:
return { ...state, popularAnime: action.payload, loading: false };
case SEARCH:
return { ...state, searchResults: action.payload, loading: false };
case GET_UPCOMING_ANIME:
return { ...state, upcomingAnime: action.payload, loading: false };
case GET_AIRING_ANIME:
return { ...state, airingAnime: action.payload, loading: false };
case GET_PICTURES:
return { ...state, pictures: action.payload, loading: false };
case IS_SEARCH:
return { ...state, isSearch: true };
case IS_NOT_SEARCHING:
return { ...state, isSearch: false };
default:
return state;
}
};
// 不要直接針對屬性控制 , 透過 dispatch 操作
const handleSubmit = (e) => {
e.preventDefault();
if (search) {
searchAnime(search); // 異步函數
dispatch({ type: IS_SEARCH });
} else {
dispatch({ type: IS_NOT_SEARCHING });
alert("Please enter a search term");
}
};
```
6. 14:15 ~ 14:40 中場休息,部署一下網站。
- 自嗨一下(?)

7. 15:00 ~ 17:00 額外濃縮成一個 component **Airing/Popular/UpComing**:
- 1. 建立一個整合邏輯的元件 - AnimatedList.jsx。
- 2. 將 AnimatedList.jsx 導入到 Homepage.jsx。
---
### 11/21 工作日誌:
- 待處理的 bugs、優化網站等細項:
- [x] 用戶搜尋資料以後,無法透過按鈕去取得對應的動漫資訊。
### 11/22 工作日誌:
- [x] - 研究 API 資料,看能不能,找出動漫分類。
```jsx
// 目前 data.data 可以查到的 types:
const getAnimeGenres = async () => {
// genres/anime
const response = await fetch(
`https://api.jikan.moe/v4/top/anime?filter=bypopularity`
);
const data = await response.json();
console.log(data.data[0].genres[0].name);
};
// console.log(item.genres[0].name); -> 11/22 14:05
```
- [x] - 動漫分類過濾,開發元件或新功能。 - (有素材)
```
進度描述:
1. 目前僅能將 popularAnime [] 資料傳進來,
以這邊的資料為準設置了動漫分類,套用到 MUI 素材,並且開立一個分頁。
後續會先以 popular , airing , upcoming 的資料來源來去做分類寫邏輯。
// 日後 api 資料有時間再做一個 Total 的 Filter。
```

#### bug 修改及詠唱反饋:
1. 目前可以透過點擊 radio,type === 取得關聯的動畫。
```
UI 控制,切換 Light、Dark 模式,進度描述:
詠唱出了一段 UI,但真他媽醜 xd
目前還沒辦法控制全局套用。
```
---
### 11/23 工作日誌:
- 螢幕右下方有一個齒輪:
- 點擊以後可以出現:
- [x] - 齒輪設定完成,目前點擊可以產生更多查詢的面板。
- 「查詢更多熱門分類」- popular。
- 「查詢更多上映分類」- aircoming。
- 「查詢更多待上映分類」- upcoming。
---
### 11/24 工作日誌:
- [x] - 透過 context,取得三份 initial State 資料原型。
- [ ] - 將上述功能畫面整合成一個元件:
- 該元件可將三份來源資料整合在該元件「SearchMore.jsx」
- 且點擊路由,就可取得對應的分類 radio,及其對應的動畫。
- [ ] - UI 開發,以 styled 為主要樣式開發工具。
- [x] - 控制 Setting 路由 -> 熱門動畫 -> 取得資料。
---
### 11/25 工作日誌:
- [x] - 點擊 SearchMore 選單,可以取消 AnimatedList。
- 棘手問題:因為一開始需要先載入 popular,有什麼辦法可以取消?
- [X] - 點擊以後,已經可以正確來回切換 AnimatedList。
1.
```jsx
// 修改內容:
// context add State -> 傳遞到:
const [showAnimatedList, setShowAnimatedList] = useState(true); // 控制 AnimatedList View
```
2. 確認哪些元件有相對應的關聯性:
- **Homepage:**
```jsx
// Homepage, HeaderButtons 變數:
const HeaderButtons = (
setRendered,
getAiringAnime,
getUpcomingAnime
// getPopularAnime
) => {
// 沒有這個 setState , 無法接收控制狀態。
const { setShowAnimatedList } = useGlobalContext();
return [
{
label: "Popular",
onClick: () => {
setRendered("popular");
setShowAnimatedList(true); // 显示 AnimatedList
},
icon: <i className="fas fa-fire" />,
},
{
label: "Airing",
onClick: () => {
setRendered("airing");
getAiringAnime();
setShowAnimatedList(true); // 显示 AnimatedList
},
},
{
label: "Upcoming",
onClick: () => {
setRendered("upcoming");
getUpcomingAnime();
setShowAnimatedList(true); // 显示 AnimatedList
},
},
];
};
// Homepage jsx render:
<AnimatedList rendered={rendered} showAnimatedList={showAnimatedList} />
```
3. AnimatedList 需要這個 props:
```jsx
function AnimatedList({ rendered, showAnimatedList }) {
if (!showAnimatedList) {
return null; // 不渲染 AnimatedList (表示不是 true 就 null 掉)
}
const { popularAnime, airingAnime, upcomingAnime, isSearch, searchResults } =
useGlobalContext();
const getAnimeData = (rendered) => {
switch (rendered) {
case "popular":
return popularAnime;
case "airing":
return airingAnime;
case "upcoming":
return upcomingAnime;
default:
return popularAnime;
}
};
```
- [x] - 測試:可以透過路由點擊以後,顯示 MorePopular!
- [x] - 透過點擊 SearchMore - 先去做到切換取得更多分類的「標題」。
- [X] - 標題切換以後,標題去判斷使組件去判別該從 Context 取得什麼「資料」。
```jsx
功能 & 邏輯已經完成,這邊需要在研究一下 MorePopular 組件邏輯。
```
### 11/26 工作日誌:
- [x] 釐清:Homepage、MoreSearch、MorePopular 元件新增語法。
#### 1. 在 Homepage 右下角,設置了一個 Setting Icon:
- 用戶點擊以後,會在左方顯示一下展開的 Box,這邊是如何運作?
```jsx
// 1. 首先要在 Homepage.jsx 設置一個元件,這表示 SearchMore
import SearchMore from "./SearchMore"; -> 導入這塊元件。
// 2. 插入 render 元件 ->
<SearchMore
setShowMorePopular={setShowMorePopular}
handleCategoryClick={handleCategoryClick}
/>
// 3. 在 gobalContext 設置好 控制用的 State:
const [openSetting, setOpenSetting] = useState(false);
// 4. 並且傳入到 Children 給上下文傳遞在為一個使用:
- 這邊範例是直接在 SearchMore 做傳遞了:
const {
openSetting, // 打開樣版的 State
setOpenSetting, // 打開樣版的 setState
// 以下略過 ...
} = useGlobalContext();
```
```jsx
// 5. 為何點擊之後可以產生及關閉搜索更多分類? 原因如下:
<Link>
<FixedSettingsIcon
style={{ width: "40px", height: "40px" }}
// 6. 由於 setOpenSetting 預設為 false 所以點擊之後反向自然會變成 true。
onClick={() => setOpenSetting(!openSetting)}
/>
</Link>
```
```jsx
// 7. 下面則是顯現,當 openSetting true 時則會渲染以下內容:
{openSetting && ( // -> 相對的點擊後 false 則是隱藏
<SettingPanel>
<SearchTitle>
Search More Anime
{/* <SearchIcon className="search-icon" /> */}
</SearchTitle>
<ShowText>
{SearchText.map((item, index) => (
<div key={index}>
<Link to="#" onClick={() => handleLinkClick(item.action)}>
{item.showText}
</Link>
</div>
))}
</ShowText>
</SettingPanel>
)}
// 8. 而項目列表則是由 map method 方法跑出來的。
```
#### 2. 搜尋更多的路由,是怎麼去根據邏輯產生分類搜尋的?
- SearchMore 點擊路由,以後會去關閉 AnimatedList。
- 切換成 MorePopular - 並且根據路由名稱去顯示對應的資料分類。
```jsx
// 1. 我們在前面有使用 map 去渲染路由,並且這些路由都會呼叫一個回調函數在上面。
<ShowText>
{SearchText.map((item, index) => (
<div key={index}>
<Link to="#" onClick={() =>
handleLinkClick(item.action)}> // 在這邊
{item.showText}
</Link>
</div>
))}
</ShowText>
// 2. 用戶點擊連結,呼叫回調函數以後,讓我們來看到回調函數的內容:
// 3. 此時,我們可以根據我們所處的 action.type 去執行對應的 case 內容。
const handleLinkClick = (action) => {
// 根據點擊的連結,調用相應的函數
switch (action) {
case "getPopularAnime":
// 這邊暫時不設置任何東西,因為熱門動畫會在一開始就載入。
handleCategoryClick("popular"); // 告之父元素,現在做了哪些事?
break;
case "getAiringAnime":
getAiringAnime();
handleCategoryClick("airing"); // 告之父元素,現在做了哪些事?
break;
case "getUpcomingAnime":
getUpcomingAnime();
handleCategoryClick("upcoming"); // 告之父元素,現在做了哪些事?
break;
default:
console.log("default case!");
break;
}
setOpenSetting(!openSetting); // 關閉樣版
// ShowAnimatedList 是 context 傳進來的
setShowAnimatedList(false); // 更新 AnimatedList 為 false
setShowMorePopular(true); // 更新 MorePopular 為 true
-> 上面這兩個 setState 則是關鍵了,並將這些更新資訊
作為 props 傳遞到 Homepage 元件
};
// 4. props 怎麼傳遞?
- 從這邊:
function SearchMore({ setShowMorePopular, handleCategoryClick }) {}
```
```jsx
// 5. 回到 Home 父組件:
- 這邊可以看到,子組件 SearchMore 設置了兩個 props
// renoder:
<SearchMore
// 控制點擊分類的分類
handleCategoryClick={handleCategoryClick}
// 顯示 MorePopular
setShowMorePopular={setShowMorePopular}
/>
// 從子元件的 props 傳遞資訊,回到 Homepage 元件這邊的代碼:
-> 這邊傳遞的 category 參數會帶入到 setSelectedCategory
const handleCategoryClick = (category) => {
setSelectedCategory(category);
};
// selectedCategory 的 State
const [selectedCategory, setSelectedCategory] = useState(null); // 這邊是 SearchMore 的部分
-> 根據上面所傳遞進來的資訊,selectedCategory(切換category)
//
-> render , 此時根據傳遞到上面代碼的 category 繼續傳遞到子組件
去做相對應的渲染結果:
{showMorePopular && <MorePopular selectedCategory={selectedCategory} />}
-> 這段代碼表示:
當 showMorePopular true 時,則顯示 MorePopular 組件,
並且將 selectedCategory 狀態藉由 props 的形式傳遞到下個組件使用。
(MorePopular)
```
#### 3. MorePopular 怎麼去決定渲染的分類。
- 根據三個路由的條件,去決定資料來源且顯示更多的 radio 選項:
```jsx
// 1. 根據上述的流程,影響 MorePopular 組件條件就是 Props:
{showMorePopular && <MorePopular selectedCategory={selectedCategory} />}
// 2. 根據傳遞的 props - selectedCategory 決定代碼的走向
oops , 這裏目前遇到了一些不太能理解的 bug , 待修正。 (暫時不影響結果)
```
---
### 11/27 工作日誌:
- [X] 確認一下需要 RWD 開發的部分。
```
// Homepage - 顯示更多搜尋的 Icon fixed 定位。 --- O
// 點擊 Icon fixed 以後,左側欄位顯示。 --- O
// 搜尋結果的圖片位置 - center。 --- O
// 點擊動漫清單,裡面的 RWD 修飾。 --- X
```
- [ ] 設計 UI,'Dark' & 'Light' mode 控制設計。
- [x] RWD 各種修理! --- 目前大概只剩點擊後的 AnimeItem.jsx
- [x] HomePage
- [x] SearchMore
- [x] AnimeItem
### 11/30 工作日誌:
- [ ] - UI 控制,切換 Light、Dark 模式。 ([有素材]
### 12/1 工作日誌:
- [ ] - i18n 繁中化 zh?
### 待處理的任務:
- 該專案目前預計執行的項目:
(https://mui.com/material-ui/react-switch/))
- [ ] 把 className 換成 styled(CSS)
- [ ] i18n (中文化)
- [ ] global getAnime 函數封裝
---
- 未來有機會在修改的東西:
- [ ] - 增設我的最愛,至收藏頁面功能。
- [ ] 網址 URL 結構 / 認識一下。(知識)
- [ ] 瀏覽器引擎 發展史。(知識)
- [ ] build / bundler。(知識)