Skip to content

Commit

Permalink
Merge pull request #18 from kscalelabs/second_milestone_serhii
Browse files Browse the repository at this point in the history
features_frontend_UI_and_backend_basic_APIs_before_integrating
  • Loading branch information
Serhii Ofii authored Sep 5, 2024
2 parents c376bac + 9b3a6b3 commit df07f6c
Show file tree
Hide file tree
Showing 44 changed files with 8,218 additions and 5,562 deletions.
19 changes: 19 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[MASTER]
# Python version to use (default: python3).
python-version= 3.11.9
ignore=venv
[MESSAGES CONTROL]
# Enable specific messages. Disable all warnings except for W0401 and E1101.
disable=E0401, E0015

[FORMAT]
# Maximum number of characters on a single line (default: 100). Increase to 120.
max-line-length=120

[DESIGN]
# Maximum number of arguments for functions or methods (default: 5). Increase to 7.
max-args=7

[IMPORTS]
# List of modules to ignore for import errors (e.g., 'module_that_does_not_exist').
ignored-modules=
11,915 changes: 6,500 additions & 5,415 deletions frontend/package-lock.json

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,15 @@
"@types/node": "^16.18.97",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.3.0",
"clsx": "^2.1.1",
"holderjs": "^2.9.9",
"nth-check": "^2.1.1",
"postcss": "^8.4.38",
"react": "^18.3.1",
"react-bootstrap-icons": "^1.11.4",
"react-dom": "^18.3.1",
"react-icons": "^5.3.0",
"react-scripts": "5.0.1",
"typescript": "^4.9.5",
"typescript": "^4.3.0",
"web-vitals": "^2.1.4"
},
"type": "module",
Expand Down Expand Up @@ -69,7 +70,8 @@
"prettier-plugin-organize-imports": "^3.2.4",
"react-bootstrap": "^2.10.2",
"react-router-dom": "^6.23.1",
"ts-jest": "^29.1.4",
"tailwindcss": "^3.4.10",
"ts-jest": "^26.5.6",
"typescript-eslint": "*"
},
"jest": {
Expand Down
14 changes: 3 additions & 11 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
@import url("https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;700&display=swap");
@tailwind base;
@tailwind components;
@tailwind utilities;

body {
font-family: "Noto Serif SC", serif; /* Use Noto Serif Simplified Chinese font */
}

div.content {
margin-top: 16px;
margin-bottom: 56px;
}

@media (max-width: 768px) {
div.row-two {
gap: 16px;
}
}
19 changes: 16 additions & 3 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import NotFoundRedirect from "components/NotFoundRedirect";
import { AlertQueue, AlertQueueProvider } from "hooks/alerts";
import { AuthenticationProvider, OneTimePasswordWrapper } from "hooks/auth";
import { ThemeProvider } from "hooks/theme";
import CollectionPage from "pages/Collection";
import Collections from "pages/Collections";
import Home from "pages/Home";
import LoginPage from "pages/Login";
import NotFound from "pages/NotFound";
import Test from "pages/Test";
import { Container } from "react-bootstrap";
Expand All @@ -19,16 +22,26 @@ const App = () => {
<AlertQueueProvider>
<AlertQueue>
<OneTimePasswordWrapper>
<TopNavbar />

<Container className="content">
<Container>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/test" element={<Test />} />
<Route path="/404" element={<NotFound />} />
<Route path="/collections" element={<Collections />} />
<Route path="/collection" element={<CollectionPage />} />
<Route
path="/collection/new"
element={<CollectionPage />}
/>
<Route
path="/collection/:id"
element={<CollectionPage />}
/>
<Route path="/login" element={<LoginPage />} />
<Route path="*" element={<NotFoundRedirect />} />
</Routes>
</Container>
<TopNavbar />
</OneTimePasswordWrapper>
</AlertQueue>
</AlertQueueProvider>
Expand Down
74 changes: 74 additions & 0 deletions frontend/src/api/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// src/api/auth.ts
import axios from "axios";
import {
SigninData,
SignupData,
SignupResponse,
SignupResponseBusiness,
} from "types/auth";

const API_URL = process.env.REACT_APP_BACKEND_URL || "https://localhost:8080";

export const signup = async (data: SignupData): Promise<SignupResponse> => {
const response = await axios.post(`${API_URL}/signup`, data);
return response.data;
};
export const read_me = async (token: string): Promise<SignupResponse> => {
const response = await axios.get(`${API_URL}/api/user/me`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return response.data;
};
export const read_me_business = async (
token: string,
): Promise<SignupResponseBusiness> => {
const response = await axios.get(`${API_URL}/api/business/me`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return response.data;
};
export const signin = async (data: SigninData): Promise<SignupResponse> => {
const params = new URLSearchParams();
params.append("username", data.email);
params.append("password", data.password);
const response = await axios.post(`${API_URL}/api/user/token`, params);
console.log(response);
return response.data;
};
export const social_facebook_login = async (
token: string,
): Promise<SignupResponse> => {
console.log(token);
const response = await axios.post(
`${API_URL}/api/facebook/callback`,
{
token: token,
},
{
headers: {
"Content-Type": "application/json",
},
},
);
return response.data;
};
export const social_Instagram_login = async (
token: string,
): Promise<SignupResponse> => {
const response = await axios.post(
`${API_URL}/api/instagram/callback`,
{
token: token,
},
{
headers: {
"Content-Type": "application/json",
},
},
);
return response.data;
};
48 changes: 48 additions & 0 deletions frontend/src/components/card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { useNavigate } from "react-router-dom";
import { Collection } from "types/model";

const CardItem: React.FC<Collection> = (collectionProps) => {
const { id, title, description, images } = collectionProps;
const navigate = useNavigate();

const handleOpen = () => {
navigate(`/collection/${id}`);
};

const handleEdit = () => {
navigate(`/collection/${id}?Action=edit`);
};

return (
<div className="relative m-4 group">
<div className="relative z-10 w-52 h-72 p-3 bg-rose-100 dark:bg-gray-900 border flex flex-col gap-2 opacity-95">
<h3 className="text-lg font-bold">{title}</h3>
<p className="text-sm text-gray-900 dark:text-gray-100">
{description}
</p>
<p className="text-sm text-gray-800 dark:text-gray-200 grow">
{images.length} Images
</p>
<div className="absolute inset-0 flex items-end pb-3 justify-center group-hover:opacity-100 opacity-0 transition-opacity">
<div className="flex gap-2">
<button
className="bg-blue-500 text-white px-3 py-1 rounded"
onClick={handleOpen}
>
Open
</button>
<button
className="bg-slate-700 text-white px-3 py-1 rounded"
onClick={handleEdit}
>
Edit
</button>
</div>
</div>
</div>
<div className="absolute top-5 left-5 w-52 h-72 bg-slate-300 shadow-sm"></div>
</div>
);
};

export default CardItem;
54 changes: 54 additions & 0 deletions frontend/src/components/image.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from "react";
import { CheckCircleFill, LockFill, PencilFill } from "react-bootstrap-icons";
import { Image } from "types/model";

const ImageComponent: React.FC<Image> = ({
// id,
is_translated,
image_url,
// audio_url,
transcript,
}) => {
return (
<div
className="relative w-full h-80 min-w-80 bg-cover bg-center border-1 border-gray-800 dark:border-gray-50"
style={{ backgroundImage: `url(${image_url})` }}
>
<div className="absolute inset-0 flex flex-col items-center justify-center bg-gray-900/30">
{is_translated ? (
<>
<div className="absolute top-2 right-2 flex items-center text-white bg-green-600 py-1 px-3 rounded text-xs">
<CheckCircleFill size={15} className="mr-2" />
<span>The image has been translated</span>
</div>
<div className="absolute bottom-2 text-white bg-gray-800 py-1 px-3 mx-2 rounded">
<span>{transcript}</span>
</div>
</>
) : (
<>
<div className="absolute top-2 right-2 flex items-center text-white bg-red-600 py-1 px-3 rounded text-xs">
<LockFill size={13} className="mr-2" />
<span>It needs to be translated</span>
</div>
</>
)}
{/* Centered Edit Button */}
<div className="absolute inset-x-0 bottom-1/2 transform translate-y-1/2 flex items-center justify-center gap-2">
{is_translated ? (
<button className="bg-yellow-500 text-white py-1 px-3 rounded flex items-center">
<PencilFill className="mr-2" />
Edit
</button>
) : (
<button className="bg-blue-500 text-white py-1 px-3 rounded">
Translate
</button>
)}
</div>
</div>
</div>
);
};

export default ImageComponent;
Loading

0 comments on commit df07f6c

Please sign in to comment.