Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"test": "npm run react:test && npm run lint:test",
"react:test": "react-scripts test --watchAll=false",
"react:test--watch": "react-scripts test --watchAll=true",
"react:test--coverage": "react-scripts test --coverage",
"lint:test": "eslint src && stylelint **/*.scss",
"lint:fix": "eslint src --fix && stylelint **/*.scss --fix",
"eject": "react-scripts eject",
Expand Down
Binary file modified public/favicon.ico
Binary file not shown.
2 changes: 1 addition & 1 deletion public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
content="React && Graphql powered github client"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
Expand Down
Binary file modified public/logo192.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/logo512.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"short_name": "Github Client",
"name": "React && Graphql powered github client",
"icons": [
{
"src": "favicon.ico",
Expand Down
10 changes: 3 additions & 7 deletions src/app/header/index.scss
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
.gc-app .header {
display: flex;
align-items: center;
height: 64px !important;
height: 62px !important;
overflow: hidden;
font-size: var(--fsz);
background-color: var(--clr-text) !important;

&__logo {
height: 32px;
transition: var(--transition);

img {
// FIXME: temp
filter: grayscale(1) contrast(100%) invert(75%) brightness(100%);
}

&:hover {
opacity: 0.6;
opacity: 0.7;
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/app/header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { Layout, Input } from "antd";
import * as qs from "query-string";
import { Auth } from "features";
import ImgLogo from "./logo.png";
import { ReactComponent as IcLogo } from "./logo.svg";
import "./index.scss";

const Header = () => {
Expand All @@ -14,10 +14,9 @@ const Header = () => {

return (
<Layout.Header className="header">
<div className="nav flex-grow">
<a className="header__logo" href="/">
{/* FIXME: Временная иконка, поправить позже */}
<img className="header__logo" src={ImgLogo} alt="logo" width={48} height={48} />
<div className="nav flex flex-grow items-center">
<a className="header__logo flex items-center" href="/">
<IcLogo />
{!isAuth && <span className="gc-app__title text-white m-4">GITHUB-CLIENT</span>}
</a>
{isAuth && (
Expand Down
Binary file removed src/app/header/logo.png
Binary file not shown.
3 changes: 3 additions & 0 deletions src/app/header/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 4 additions & 3 deletions src/app/index.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from "react";
import { render } from "@testing-library/react";
// import App from ".";
import App from ".";

test("renders without crashing", () => {
render(<div>Mock</div>);
test("renders without crashing", async () => {
const screen = render(<App />);
expect(await screen.findByTestId("gc-app")).toBeInTheDocument();
});
2 changes: 1 addition & 1 deletion src/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import "./index.scss";
*/
const App = () => {
return (
<div className="gc-app">
<div className="gc-app" data-testid="gc-app">
<Layout>
<Header />
<Layout.Content className="gc-app-content">
Expand Down
18 changes: 15 additions & 3 deletions src/features/auth/consts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
/** @localStorage Токен авторизации */
export const TOKEN_KEY = "GITHUB-CLIENT__TOKEN";
import { UserCredential } from "./types";

export const getToken = () => JSON.parse(localStorage.getItem(TOKEN_KEY) || "");
/** @localStorage Учетные данные */
export const CREDENTIAL_KEY = "GITHUB-CLIENT__CREDENTIAL";

export const getCredential = () => {
return JSON.parse(localStorage.getItem(CREDENTIAL_KEY) || "") as UserCredential;
};

export const getToken = () => getCredential().accessToken;

export const routes = {
main: "/",
logout: "/",
login: "/auth",
};
23 changes: 16 additions & 7 deletions src/features/auth/firebase/auth-github.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { AuthContext } from "../types";
import firebase from "./init";

type CredentialWithToken = { credential: { accessToken: string } };

const isResultWithToken = (result: any): result is CredentialWithToken => {
return typeof result?.credential?.accessToken === "string";
const isValidAuthContext = (ctx: any): ctx is AuthContext => {
return (
typeof ctx?.credential?.accessToken === "string" &&
typeof ctx?.additionalUserInfo.username === "string"
);
};

export default function authGithub() {
Expand All @@ -12,8 +14,15 @@ export default function authGithub() {
return firebase
.auth()
.signInWithPopup(provider)
.then((result) => {
if (isResultWithToken(result)) return result;
return Promise.reject("Access token is not present");
.then((ctx) => {
if (!isValidAuthContext(ctx)) {
return Promise.reject("Not enough auth context was presented");
}

return {
accessToken: ctx.credential.accessToken,
// FIXME: more strict types
username: ctx.additionalUserInfo!.username!,
};
});
}
21 changes: 11 additions & 10 deletions src/features/auth/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { useLocalStorage } from "shared/hooks";
import { TOKEN_KEY } from "./consts";
import { CREDENTIAL_KEY } from "./consts";
import { UserCredential } from "./types";

export const useAuth = () => {
const [token, setToken] = useLocalStorage(TOKEN_KEY, "");

const isAuth = !!token;
const [viewer, setViewer] = useLocalStorage<UserCredential | null>(CREDENTIAL_KEY, null);
const isAuth = !!viewer;

// FIXME: specify redirect urls?
const login = (token: string) => {
setToken(token);
window.location.href = "/";
// FIXME: prohibit access?
const login = (credential: UserCredential) => {
setViewer(credential);
window.location.href = `/${credential.username}`;
};
// FIXME: prohibit access?
const logout = () => {
setToken("");
window.location.href = "/auth";
setViewer(null);
};

return { isAuth, token, login, logout };
return { isAuth, viewer, login, logout };
};
2 changes: 1 addition & 1 deletion src/features/auth/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { default as Router } from "./router";
export { default as Page } from "./page";
export { default as User } from "./user";
export * from "./consts";
// FIXME: temp?
Expand Down
5 changes: 2 additions & 3 deletions src/features/auth/page/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@ import "./index.scss";
const AuthPage = () => {
const { login } = useAuth();
const authorize = () => {
authorizeGithub().then((result) => {
login(result.credential.accessToken);
});
authorizeGithub().then(login);
// TODO: add catch handling!
};

return (
Expand Down
38 changes: 0 additions & 38 deletions src/features/auth/router/index.tsx

This file was deleted.

13 changes: 13 additions & 0 deletions src/features/auth/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export type CredentialWithToken = {
credential: {
accessToken: string;
};
};

export type AuthContext = import("firebase").default.auth.UserCredential & CredentialWithToken;

export type UserCredential = {
accessToken: string;
username: string;
// NOTE: Возможно список хранимых полей будет расширяться позднее
};
18 changes: 10 additions & 8 deletions src/features/auth/user/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import React from "react";
import { Button } from "antd";
import { useAuth } from "../hooks";
import { useViewerQuery } from "./queries.gen";
import { routes } from "../consts";

const User = () => {
const { isAuth, logout } = useAuth();
const { data } = useViewerQuery();
const { login } = data?.viewer || {};
const { isAuth, logout, viewer } = useAuth();

/**
* FIXME: Использовать Link?
Expand All @@ -17,15 +15,19 @@ const User = () => {
{isAuth && (
<>
{/* FIXME: use h3 instead */}
<a className="m-4 text-white" href={`/${login}`}>
{login}
<a className="m-4 text-white" href={`/${viewer?.username}`}>
{viewer?.username}
</a>
<Button className="m-4" onClick={logout}>
<Button className="m-4" href={routes.logout} onClick={logout}>
Logout
</Button>
</>
)}
{!isAuth && <Button className="m-4">Sign In</Button>}
{!isAuth && (
<Button className="m-4" href={routes.login}>
Sign In
</Button>
)}
</span>
);
};
Expand Down
43 changes: 0 additions & 43 deletions src/features/auth/user/queries.gen.ts

This file was deleted.

5 changes: 0 additions & 5 deletions src/features/auth/user/queries.gql

This file was deleted.

2 changes: 1 addition & 1 deletion src/features/home-hero/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const HomeHero = () => {
Github in minimalistic design. Built for developers.
</h1>
<p className="home-hero__description">Welcome to our GithubClient!</p>
{/* FIXME: redirect to other page if user isAuth*/}
{/* FIXME: specify link from Auth.feature (but on page or another level - without hardcoding) */}
<a className="home-hero__button" href="/auth">
START NOW
</a>
Expand Down
Loading