- {folderLinks.map((key) => (
-
-
+ {userFolder.folder.links.map((link) => (
+
+
))}
diff --git a/src/CardList/FolderItem.js b/src/CardList/FolderItem.tsx
similarity index 82%
rename from src/CardList/FolderItem.js
rename to src/CardList/FolderItem.tsx
index 9594207f3..f999fc862 100644
--- a/src/CardList/FolderItem.js
+++ b/src/CardList/FolderItem.tsx
@@ -1,8 +1,18 @@
-import format from "date-fns/format";
+import { format } from "date-fns/format";
import { getElapsedTime } from "../util/getClapsedTime";
import { useState } from "react";
+import React from "react";
-function FolderItem({ item }) {
+interface ItemProps {
+ item: {
+ createdAt: string;
+ imageSource?: string;
+ url: string;
+ description: string;
+ };
+}
+
+function FolderItem({ item }: ItemProps) {
const createdAd = getElapsedTime(item.createdAt);
const DEFAULT_IMAGE = "../assets/card-default.png";
const [isHovered, setIsHovered] = useState(false);
diff --git a/src/CardList/SearchIcon.js b/src/CardList/SearchIcon.ts
similarity index 100%
rename from src/CardList/SearchIcon.js
rename to src/CardList/SearchIcon.ts
diff --git a/src/Footer/Footer.js b/src/Footer/Footer.tsx
similarity index 98%
rename from src/Footer/Footer.js
rename to src/Footer/Footer.tsx
index 7e12285a3..fd0ed869c 100644
--- a/src/Footer/Footer.js
+++ b/src/Footer/Footer.tsx
@@ -5,6 +5,7 @@ import {
YOUTUBE_ICON,
} from "./Icon";
import "./Footer.css";
+import React from "react";
function Footer() {
return (
diff --git a/src/Footer/Icon.js b/src/Footer/Icon.ts
similarity index 100%
rename from src/Footer/Icon.js
rename to src/Footer/Icon.ts
diff --git a/src/NavigationBar/NavProfile.js b/src/NavigationBar/NavProfile.tsx
similarity index 96%
rename from src/NavigationBar/NavProfile.js
rename to src/NavigationBar/NavProfile.tsx
index faf577f25..c8bc5446e 100644
--- a/src/NavigationBar/NavProfile.js
+++ b/src/NavigationBar/NavProfile.tsx
@@ -1,4 +1,5 @@
import { useAsync } from "../api/useAsync";
+import React from "react";
function NavProfile() {
const { userInfo, userFolder, loading, error } = useAsync();
diff --git a/src/NavigationBar/NavigationBar.js b/src/NavigationBar/NavigationBar.tsx
similarity index 91%
rename from src/NavigationBar/NavigationBar.js
rename to src/NavigationBar/NavigationBar.tsx
index f753d87df..1f8a738df 100644
--- a/src/NavigationBar/NavigationBar.js
+++ b/src/NavigationBar/NavigationBar.tsx
@@ -1,8 +1,9 @@
import { useAsync } from "../api/useAsync";
import NavProfile from "./NavProfile";
import "./NavigationBar.css";
+import React from "react";
-function NavigationBar({ position }) {
+function NavigationBar({ position }: any) {
const { userInfo, userFolder, loading, error } = useAsync();
return (
diff --git a/src/Profile/Profile.js b/src/Profile/Profile.tsx
similarity index 93%
rename from src/Profile/Profile.js
rename to src/Profile/Profile.tsx
index 40005375f..57908d57f 100644
--- a/src/Profile/Profile.js
+++ b/src/Profile/Profile.tsx
@@ -3,6 +3,7 @@ import { useAsync } from "../api/useAsync";
import { useState, useEffect } from "react";
import "./Profile.css";
import { getUserFolder } from "../api/getUserFolder";
+import React from "react";
function Profile() {
const { userInfo, userFolder, loading, error } = useAsync();
@@ -18,7 +19,7 @@ function Profile() {
}
// 사용자 정보가 없을 때
- if (!userInfo) {
+ if (!userInfo || !userFolder) {
return null;
}
// 사용자 정보 출력
diff --git a/src/SearchBar/SearchBar.js b/src/SearchBar/SearchBar.tsx
similarity index 82%
rename from src/SearchBar/SearchBar.js
rename to src/SearchBar/SearchBar.tsx
index f8fa2511d..ad3ec1ea4 100644
--- a/src/SearchBar/SearchBar.js
+++ b/src/SearchBar/SearchBar.tsx
@@ -1,5 +1,6 @@
-import { SEARCH_ICON } from "../SearchBar/SearchIcon";
+import { SEARCH_ICON } from "./SearchIcon";
import "./SearchBar.css";
+import React from "react";
function SearchBar() {
return (
diff --git a/src/SearchBar/SearchIcon.js b/src/SearchBar/SearchIcon.ts
similarity index 100%
rename from src/SearchBar/SearchIcon.js
rename to src/SearchBar/SearchIcon.ts
diff --git a/src/api/getUserFolder.js b/src/api/getUserFolder.js
deleted file mode 100644
index e58b22f50..000000000
--- a/src/api/getUserFolder.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const BASE_URL = "https://bootcamp-api.codeit.kr/api";
-
-export const getUserFolder = async () => {
- const response = await fetch(`${BASE_URL}/sample/folder`, {
- method: "GET",
- });
- if (!response.ok) {
- throw new Error("폴더정보 불러오기 실패");
- }
- const { folder } = await response.json();
- return { folder };
-};
-
-export const getFolderList = async () => {
- const response = await fetch(`${BASE_URL}/users/1/folders`, {
- method: "GET",
- });
- if (!response.ok) {
- throw new Error("폴더정보 불러오기 실패");
- }
- const folder = await response.json();
- return folder;
-};
-
-export const getAllFolderList = async () => {
- const response = await fetch(`${BASE_URL}/users/1/links`, {
- method: "GET",
- });
- if (!response.ok) {
- throw new Error("폴더정보 불러오기 실패");
- }
- const folder = await response.json();
- return folder;
-};
-
-export const getFolderListById = async (folderId) => {
- const response = await fetch(
- `${BASE_URL}/users/1/links?folderId=${folderId}`,
- {
- method: "GET",
- }
- );
- if (!response.ok) {
- throw new Error("폴더정보 불러오기 실패");
- }
- const folder = await response.json();
- console.log("ddddddddddd:" + { folder });
- return folder;
-};
diff --git a/src/api/getUserFolder.ts b/src/api/getUserFolder.ts
new file mode 100644
index 000000000..6606a3010
--- /dev/null
+++ b/src/api/getUserFolder.ts
@@ -0,0 +1,101 @@
+const BASE_URL = "https://bootcamp-api.codeit.kr/api";
+
+interface LinksProps {
+ id: number;
+ createdAt: string;
+ url: string;
+ title: string;
+ description: string;
+ imageSource?: string;
+}
+interface Folder {
+ id: number;
+ count: number;
+ links: LinksProps[];
+ name: string;
+ owner: {
+ id: number;
+ name: string;
+ profileImageSource: string;
+ };
+}
+export interface GetUserFolderProps {
+ folder: Folder;
+}
+
+interface LinkCountProps {
+ count: number;
+}
+interface FolderDataProps {
+ id: number;
+ created_at: string;
+ name: string;
+ user_id: number;
+ favorite: boolean;
+ links: LinkCountProps[];
+}
+export interface GetFolderListProps {
+ data: FolderDataProps[];
+}
+
+interface LinksProps2 {
+ id: number;
+ created_at: string;
+ description: string;
+ folder_id: number;
+ image_source: string;
+ title: string;
+ updated_at: string | null;
+ url: string;
+}
+export interface GetAllFolderListProps {
+ data: LinksProps2[];
+}
+
+export const getUserFolder = async (): Promise
=> {
+ const response = await fetch(`${BASE_URL}/sample/folder`, {
+ method: "GET",
+ });
+ if (!response.ok) {
+ throw new Error("폴더정보 불러오기 실패");
+ }
+ const { folder } = await response.json();
+
+ return { folder };
+};
+
+export const getFolderList = async (): Promise => {
+ const response = await fetch(`${BASE_URL}/users/1/folders`, {
+ method: "GET",
+ });
+ if (!response.ok) {
+ throw new Error("폴더정보 불러오기 실패");
+ }
+ const folder = await response.json();
+ return folder;
+};
+
+export const getAllFolderList = async (): Promise => {
+ const response = await fetch(`${BASE_URL}/users/1/links`, {
+ method: "GET",
+ });
+ if (!response.ok) {
+ throw new Error("폴더정보 불러오기 실패");
+ }
+ const folder = await response.json();
+ return folder;
+};
+
+export const getFolderListById = async (folderId: number) => {
+ const response = await fetch(
+ `${BASE_URL}/users/1/links?folderId=${folderId}`,
+ {
+ method: "GET",
+ }
+ );
+ if (!response.ok) {
+ throw new Error("폴더정보 불러오기 실패");
+ }
+ const folder = await response.json();
+ return folder;
+};
diff --git a/src/api/getUserInfo.js b/src/api/getUserInfo.ts
similarity index 67%
rename from src/api/getUserInfo.js
rename to src/api/getUserInfo.ts
index 7076bac43..1b8acb03f 100644
--- a/src/api/getUserInfo.js
+++ b/src/api/getUserInfo.ts
@@ -1,6 +1,13 @@
const BASE_URL = "https://bootcamp-api.codeit.kr/api";
-export const getUserInfo = async () => {
+export interface UserInfo {
+ name: string;
+ id: string;
+ email: string;
+ profileImageSource?: string;
+}
+
+export const getUserInfo = async (): Promise => {
const response = await fetch(`${BASE_URL}/sample/user`, {
method: "GET",
});
diff --git a/src/api/useAsync.js b/src/api/useAsync.ts
similarity index 54%
rename from src/api/useAsync.js
rename to src/api/useAsync.ts
index f11c8cd8f..8ca65b621 100644
--- a/src/api/useAsync.js
+++ b/src/api/useAsync.ts
@@ -1,12 +1,12 @@
import { useState, useEffect } from "react";
-import { getUserInfo } from "./getUserInfo";
-import { getUserFolder } from "./getUserFolder";
+import { getUserInfo, UserInfo } from "./getUserInfo";
+import { getUserFolder, GetUserFolderProps } from "./getUserFolder";
export function useAsync() {
const [loading, setLoading] = useState(true);
- const [error, setError] = useState(null);
- const [userInfo, setUserInfo] = useState(null);
- const [userFolder, setUserFolder] = useState(null);
+ const [error, setError] = useState(null);
+ const [userInfo, setUserInfo] = useState(null);
+ const [userFolder, setUserFolder] = useState(null);
useEffect(() => {
const fetchData = async () => {
@@ -18,10 +18,13 @@ export function useAsync() {
setUserInfo(userInfo);
setUserFolder(userFolder);
setLoading(false); // 로딩 상태 변경
- } catch (error) {
- // 에러 발생 시 에러 상태 업데이트
- setError(error);
- setLoading(false); // 로딩 상태 변경
+ } catch (error: unknown) {
+ if (error instanceof Error) {
+ setError(error);
+ } else {
+ setError(new Error("Unknown error occurred"));
+ }
+ setLoading(false);
}
};
diff --git a/src/api/useFolderAsync.js b/src/api/useFolderAsync.ts
similarity index 53%
rename from src/api/useFolderAsync.js
rename to src/api/useFolderAsync.ts
index 3be8c0e70..de3b755a6 100644
--- a/src/api/useFolderAsync.js
+++ b/src/api/useFolderAsync.ts
@@ -1,12 +1,18 @@
import { useState, useEffect } from "react";
-import { getFolderList, getAllFolderList } from "./getUserFolder";
+import {
+ getFolderList,
+ getAllFolderList,
+ GetFolderListProps,
+ GetAllFolderListProps,
+} from "./getUserFolder";
const BASE_URL = "https://bootcamp-api.codeit.kr/api";
export function useFolderAsync() {
const [loading, setLoading] = useState(true);
- const [error, setError] = useState(null);
- const [folderList, setFolderList] = useState(null);
- const [allFolderList, setAllFolderList] = useState(null);
+ const [error, setError] = useState(null);
+ const [folderList, setFolderList] = useState(null);
+ const [allFolderList, setAllFolderList] =
+ useState(null);
useEffect(() => {
const fetchData = async () => {
@@ -17,10 +23,13 @@ export function useFolderAsync() {
setFolderList(folderList);
setAllFolderList(allFolderList);
setLoading(false); // 로딩 상태 변경
- } catch (error) {
- // 에러 발생 시 에러 상태 업데이트
- setError(error);
- setLoading(false); // 로딩 상태 변경
+ } catch (error: unknown) {
+ if (error instanceof Error) {
+ setError(error);
+ } else {
+ setError(new Error("Unknown error occurred"));
+ }
+ setLoading(false);
}
};
diff --git a/src/components/FolderCardList.js b/src/components/FolderCardList.tsx
similarity index 73%
rename from src/components/FolderCardList.js
rename to src/components/FolderCardList.tsx
index 902eaffb7..a9828a269 100644
--- a/src/components/FolderCardList.js
+++ b/src/components/FolderCardList.tsx
@@ -1,9 +1,28 @@
import "../CardList/CardList.css";
import { useState, useEffect } from "react";
import FolderCardListItem from "./FolderCardListItem";
+import React from "react";
-export const FolderCardList = ({ folderId }) => {
- const [folderInfo, setFolderInfo] = useState(null); // 폴더 정보 상태
+interface FolderIdProps {
+ folderId: number;
+}
+
+interface Folder {
+ id: number;
+ created_at: string;
+ description: string;
+ folder_id: number;
+ image_source: string;
+ title: string;
+ updated_at: string | null;
+ url: string;
+}
+interface FolderListResponse {
+ data: Folder[];
+}
+
+export const FolderCardList = ({ folderId }: FolderIdProps) => {
+ const [folderInfo, setFolderInfo] = useState(null); // 폴더 정보 상태
const BASE_URL = "https://bootcamp-api.codeit.kr/api";
useEffect(() => {
@@ -26,19 +45,13 @@ export const FolderCardList = ({ folderId }) => {
setFolderInfo(folderData); // 폴더 정보 상태 업데이트
} catch (error) {
console.error(error);
- setFolderInfo([]); // 에러 발생 시 폴더 정보를 빈 배열로 초기화
+ setFolderInfo(null); // 에러 발생 시 폴더 정보를 빈 배열로 초기화
}
};
// 폴더 정보 가져오는 함수 호출
getFolderListById();
}, [folderId]); // folderId가 변경될 때마다 호출
- useEffect(() => {
- if (folderInfo) {
- console.log("폴더 정보:", folderInfo);
- }
- }, [folderInfo]);
-
if (!folderInfo) {
return 로딩 중...
;
}
diff --git a/src/components/FolderCardListItem.js b/src/components/FolderCardListItem.tsx
similarity index 79%
rename from src/components/FolderCardListItem.js
rename to src/components/FolderCardListItem.tsx
index 5acc80ff5..666f2a2c0 100644
--- a/src/components/FolderCardListItem.js
+++ b/src/components/FolderCardListItem.tsx
@@ -1,9 +1,25 @@
-import format from "date-fns/format";
+import { format } from "date-fns/format";
import { getElapsedTime } from "../util/getClapsedTime";
import { useState } from "react";
import KebabButton from "./KebabButton";
+import React from "react";
-function FolderCardListItem({ item }) {
+interface ItemProps {
+ created_at: string;
+ description: string;
+ folder_id: number;
+ id: number;
+ image_source: string;
+ title: string;
+ updated_at: string | null;
+ url: string;
+}
+
+interface ItemResponse {
+ item: ItemProps;
+}
+
+function FolderCardListItem({ item }: ItemResponse) {
const DEFAULT_IMAGE = "../assets/card-default.png";
const createdAd = getElapsedTime(item.created_at);
const [isHovered, setIsHovered] = useState(false);
diff --git a/src/components/FolderCardListItemStyled.js b/src/components/FolderCardListItemStyled.ts
similarity index 100%
rename from src/components/FolderCardListItemStyled.js
rename to src/components/FolderCardListItemStyled.ts
diff --git a/src/components/FolderList.js b/src/components/FolderList.tsx
similarity index 80%
rename from src/components/FolderList.js
rename to src/components/FolderList.tsx
index 5d96d67f8..5507485cd 100644
--- a/src/components/FolderList.js
+++ b/src/components/FolderList.tsx
@@ -5,25 +5,30 @@ import FolderListMenu from "./FolderListMenu";
import "./FolderList.css";
import { CardList } from "../CardList/CardList";
import { FolderCardList } from "./FolderCardList";
+import React from "react";
+
+interface FolderProps {
+ id: number;
+ name: string;
+}
+
function FolderList() {
const { folderList, allFolderList, loading, error } = useFolderAsync();
- const [selectedFolder, setSelectedFolder] = useState(null);
+ const [selectedFolder, setSelectedFolder] = useState(
+ null
+ );
const [curFolder, setCurFolder] = useState(null);
- const [folderId, setFolderId] = useState(null);
+ const [folderId, setFolderId] = useState(0);
- const handleFolderClick = (folder) => {
+ const handleFolderClick = (folder: any) => {
setSelectedFolder(folder);
if (folder) {
setFolderId(folder.id);
} else {
- setFolderId(null);
+ setFolderId(0);
}
};
- useEffect(() => {
- console.log(selectedFolder);
- }, [selectedFolder][folderId]);
-
return (
diff --git a/src/components/FolderListMenu.js b/src/components/FolderListMenu.tsx
similarity index 72%
rename from src/components/FolderListMenu.js
rename to src/components/FolderListMenu.tsx
index b28506ba9..a7a80b2d2 100644
--- a/src/components/FolderListMenu.js
+++ b/src/components/FolderListMenu.tsx
@@ -1,7 +1,18 @@
import React from "react";
+import { GetFolderListProps } from "../api/getUserFolder";
-function FolderListMenu({ folderList, onFolderClick, selectedFolder }) {
- const handleMenuButtonClick = (folder) => {
+interface FolderListMenuProps {
+ folderList: GetFolderListProps | null;
+ onFolderClick: any;
+ selectedFolder: any;
+}
+
+function FolderListMenu({
+ folderList,
+ onFolderClick,
+ selectedFolder,
+}: FolderListMenuProps) {
+ const handleMenuButtonClick = (folder: any) => {
onFolderClick(folder);
};
diff --git a/src/components/InputAddLink.js b/src/components/InputAddLink.tsx
similarity index 95%
rename from src/components/InputAddLink.js
rename to src/components/InputAddLink.tsx
index ca105f4d8..e9c3149de 100644
--- a/src/components/InputAddLink.js
+++ b/src/components/InputAddLink.tsx
@@ -1,5 +1,6 @@
import "./InputAddLink.css";
import { LINK_ICON } from "./LinkIcon";
+import React from "react";
function InputAddLink() {
return (
diff --git a/src/components/KebabButton.js b/src/components/KebabButton.tsx
similarity index 87%
rename from src/components/KebabButton.js
rename to src/components/KebabButton.tsx
index 7fc033572..c9890420a 100644
--- a/src/components/KebabButton.js
+++ b/src/components/KebabButton.tsx
@@ -2,11 +2,17 @@ import { useState } from "react";
import * as S from "./FolderCardListItemStyled";
import styled from "styled-components";
import DeleteModal from "./modal/DeleteModal";
+import React from "react";
-function KebabButton({ onAddToFolder, linkUrl }) {
+interface KebabButtonProps {
+ onAddToFolder: () => void;
+ linkUrl: string;
+}
+
+function KebabButton({ onAddToFolder, linkUrl }: KebabButtonProps) {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [isModalOpen, setIsModalOpen] = useState(false);
- const togleMenu = (event) => {
+ const togleMenu = (event: React.MouseEvent
) => {
event.stopPropagation(); // 이벤트 전파 중단
setIsMenuOpen(!isMenuOpen);
};
diff --git a/src/components/LinkIcon.js b/src/components/LinkIcon.ts
similarity index 100%
rename from src/components/LinkIcon.js
rename to src/components/LinkIcon.ts
diff --git a/src/components/LinkList.js b/src/components/LinkList.js
deleted file mode 100644
index e69de29bb..000000000
diff --git a/src/components/Test.js b/src/components/Test.js
deleted file mode 100644
index 4c93da411..000000000
--- a/src/components/Test.js
+++ /dev/null
@@ -1,51 +0,0 @@
-import "../CardList/CardList.css";
-import { useFolderAsync } from "../api/useFolderAsync";
-// import FolderItem from "../CardList/FolderItem";
-import { getFolderListById } from "../api/getUserFolder";
-import { useState, useEffect } from "react";
-export const FolderCardList = ({ folderId }) => {
- const [folderInfo, setFolderInfo] = useState({}); // 폴더 정보 상태
- const BASE_URL = "https://bootcamp-api.codeit.kr/api";
-
- useEffect(() => {
- const getFolderListById = async () => {
- try {
- let response;
- if (folderId) {
- response = await fetch(
- `${BASE_URL}/users/1/links?folderId=${folderId}`
- );
- } else {
- response = await fetch(`${BASE_URL}/users/1/links`);
- }
-
- if (!response.ok) {
- throw new Error("폴더 정보를 가져오는데 실패했습니다.");
- }
-
- const folderData = await response.json();
- setFolderInfo({ folderData }); // 폴더 정보 상태 업데이트
- } catch (error) {
- console.error(error);
- }
- };
- // 폴더 정보 가져오는 함수 호출
- getFolderListById();
- }, [folderId]); // folderId가 변경될 때마다 호출
-
- useEffect(() => {
- console.log("폴더 정보:", folderInfo.folderData);
- }, [folderInfo]);
- return (
-
- {folderInfo.folderData &&
- folderInfo.folderData.map((item, index) => (
-
-
{item.title}
-
{item.description}
- {/* 다른 정보들을 렌더링하는 코드를 추가하세요 */}
-
- ))}
-
- );
-};
diff --git a/src/components/Testt.js b/src/components/Testt.js
deleted file mode 100644
index b8edd03cd..000000000
--- a/src/components/Testt.js
+++ /dev/null
@@ -1,49 +0,0 @@
-import React from "react";
-
-function Testt({ folderList, onFolderClick }) {
- const handleMenuButtonClick = (folderId) => {
- onFolderClick(folderId);
- };
-
- return (
- <>
- {folderList && folderList.data && folderList.data.length > 0 ? (
-
- handleMenuButtonClick(null)}
- >
- 전체
-
- {folderList.data.map((folder) => (
- handleMenuButtonClick(folder.id)}
- >
- {folder.name}
-
- ))}
-
- ) : (
- 저장된 폴더가 없습니다.
- )}
- >
- );
-}
-
-// if (Array.isArray(folderInfo)) {
-// // 폴더 정보가 배열인 경우, 바로 렌더링합니다.
-// return (
-//
-// {folderInfo.map((item, index) => (
-//
-//
{item.title}
-//
{item.description}
-//
-// ))}
-//
-// );
-// }
-
-export default Testt;
diff --git a/src/components/modal/DeleteModal.js b/src/components/modal/DeleteModal.tsx
similarity index 75%
rename from src/components/modal/DeleteModal.js
rename to src/components/modal/DeleteModal.tsx
index 9fb0be58e..577d5fd74 100644
--- a/src/components/modal/DeleteModal.js
+++ b/src/components/modal/DeleteModal.tsx
@@ -1,6 +1,12 @@
import * as S from "./DeleteModalStyled";
+import React from "react";
-function DeleteModal({ linkUrl, onClose }) {
+interface DeleteModalProps {
+ linkUrl: string;
+ onClose: () => void;
+}
+
+function DeleteModal({ linkUrl, onClose }: DeleteModalProps) {
const handleModalBackgroundClick = () => {
onClose();
};
diff --git a/src/components/modal/DeleteModalStyled.js b/src/components/modal/DeleteModalStyled.tsx
similarity index 98%
rename from src/components/modal/DeleteModalStyled.js
rename to src/components/modal/DeleteModalStyled.tsx
index a73802f19..b32835f79 100644
--- a/src/components/modal/DeleteModalStyled.js
+++ b/src/components/modal/DeleteModalStyled.tsx
@@ -1,3 +1,4 @@
+import React from "react";
import styled from "styled-components";
export const ModalOverlay = styled.div`
diff --git a/src/index.js b/src/index.tsx
similarity index 72%
rename from src/index.js
rename to src/index.tsx
index 3531aebce..439e95cd2 100644
--- a/src/index.js
+++ b/src/index.tsx
@@ -2,13 +2,17 @@ import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
+import reportWebVitals from "./reportWebVitals";
-const root = ReactDOM.createRoot(document.getElementById("root"));
+const root = ReactDOM.createRoot(
+ document.getElementById("root") as HTMLElement
+);
root.render(
);
+reportWebVitals();
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
diff --git a/src/page/Folder.js b/src/page/Folder.tsx
similarity index 93%
rename from src/page/Folder.js
rename to src/page/Folder.tsx
index b5ef27895..a551c8567 100644
--- a/src/page/Folder.js
+++ b/src/page/Folder.tsx
@@ -2,6 +2,7 @@ import Footer from "../Footer/Footer";
import NavigationBar from "../NavigationBar/NavigationBar";
import FolderList from "../components/FolderList";
import InputAddLink from "../components/InputAddLink";
+import React from "react";
function Folder() {
return (
diff --git a/src/page/Shared.js b/src/page/Shared.tsx
similarity index 93%
rename from src/page/Shared.js
rename to src/page/Shared.tsx
index 05de4874e..fc388cdd1 100644
--- a/src/page/Shared.js
+++ b/src/page/Shared.tsx
@@ -3,6 +3,7 @@ import NavigationBar from "../NavigationBar/NavigationBar.js";
import Profile from "../Profile/Profile.js";
import { CardList } from "../CardList/CardList.js";
import Footer from "../Footer/Footer.js";
+import React from "react";
function Shared() {
return (
diff --git a/src/react-app-env.d copy.ts b/src/react-app-env.d copy.ts
new file mode 100644
index 000000000..6970dbc1c
--- /dev/null
+++ b/src/react-app-env.d copy.ts
@@ -0,0 +1,2 @@
+export {};
+///
diff --git a/src/react-app-env.d.ts b/src/react-app-env.d.ts
new file mode 100644
index 000000000..5e977f7b3
--- /dev/null
+++ b/src/react-app-env.d.ts
@@ -0,0 +1,74 @@
+
+///
+///
+
+declare namespace NodeJS {
+ interface Process{
+ env: ProcessEnv
+ }
+ interface ProcessEnv {
+ /**
+ * By default, there are two modes in Vite:
+ *
+ * * `development` is used by vite and vite serve
+ * * `production` is used by vite build
+ *
+ * You can overwrite the default mode used for a command by passing the --mode option flag.
+ *
+ */
+ readonly NODE_ENV: 'development' | 'production'
+ }
+}
+
+declare var process: NodeJS.Process
+
+declare module '*.gif' {
+ const src: string
+ export default src
+}
+
+declare module '*.jpg' {
+ const src: string
+ export default src
+}
+
+declare module '*.jpeg' {
+ const src: string
+ export default src
+}
+
+declare module '*.png' {
+ const src: string
+ export default src
+}
+
+declare module '*.webp' {
+ const src: string
+ export default src
+}
+
+declare module '*.svg' {
+ import * as React from 'react'
+
+ export const ReactComponent: React.FunctionComponent & { title?: string }>
+
+ const src: string;
+ export default src
+}
+
+declare module '*.module.css' {
+ const classes: { readonly [key: string]: string }
+ export default classes
+}
+
+declare module '*.module.scss' {
+ const classes: { readonly [key: string]: string }
+ export default classes
+}
+
+declare module '*.module.sass' {
+ const classes: { readonly [key: string]: string }
+ export default classes
+}
diff --git a/src/reportWebVitals.js b/src/reportWebVitals.ts
similarity index 75%
rename from src/reportWebVitals.js
rename to src/reportWebVitals.ts
index 5253d3ad9..49a2a16e0 100644
--- a/src/reportWebVitals.js
+++ b/src/reportWebVitals.ts
@@ -1,4 +1,6 @@
-const reportWebVitals = onPerfEntry => {
+import { ReportHandler } from 'web-vitals';
+
+const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
diff --git a/src/setupTests.ts b/src/setupTests.ts
new file mode 100644
index 000000000..8f2609b7b
--- /dev/null
+++ b/src/setupTests.ts
@@ -0,0 +1,5 @@
+// jest-dom adds custom jest matchers for asserting on DOM nodes.
+// allows you to do things like:
+// expect(element).toHaveTextContent(/react/i)
+// learn more: https://github.com/testing-library/jest-dom
+import '@testing-library/jest-dom';
diff --git a/src/util/getClapsedTime.js b/src/util/getClapsedTime.ts
similarity index 70%
rename from src/util/getClapsedTime.js
rename to src/util/getClapsedTime.ts
index b36a97225..a7ef8b6d5 100644
--- a/src/util/getClapsedTime.js
+++ b/src/util/getClapsedTime.ts
@@ -1,11 +1,11 @@
-const second = 1000;
-const minute = second * 60;
-const hour = minute * 60;
-const day = hour * 24;
-const month = day * 31;
-const year = month * 12;
+const second: number = 1000;
+const minute: number = second * 60;
+const hour: number = minute * 60;
+const day: number = hour * 24;
+const month: number = day * 31;
+const year: number = month * 12;
-const TIME_IN_MILLISECONDS = {
+const TIME_IN_MILLISECONDS: { [key: string]: number } = {
second,
minute,
hour,
@@ -14,10 +14,10 @@ const TIME_IN_MILLISECONDS = {
year,
};
-export const getElapsedTime = (createdAt) => {
+export const getElapsedTime = (createdAt: string): string => {
const now = new Date();
const createdAtDate = new Date(createdAt);
- const elapsedTime = now - createdAtDate;
+ const elapsedTime: number = now.getTime() - createdAtDate.getTime();
const { minute, hour, day, month, year } = TIME_IN_MILLISECONDS;
if (year * 2 <= elapsedTime) {
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 000000000..bf321c3eb
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "ESNext",
+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
+ "types": ["react"],
+ "allowJs": false,
+ "skipLibCheck": false,
+ "esModuleInterop": false,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "module": "ESNext",
+ "moduleResolution": "Node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react"
+ },
+ "include": ["src"]
+}
diff --git a/vite.config.ts b/vite.config.ts
new file mode 100644
index 000000000..823633f7f
--- /dev/null
+++ b/vite.config.ts
@@ -0,0 +1,9 @@
+import * as reactPlugin from "vite-plugin-react";
+import type { UserConfig } from "vite";
+
+const config: UserConfig = {
+ jsx: "react",
+ plugins: [reactPlugin],
+};
+
+export default { config };