Skip to content

Commit

Permalink
add changes with app
Browse files Browse the repository at this point in the history
  • Loading branch information
shivamkantival committed Mar 28, 2020
1 parent 3b59b75 commit e97d5b6
Show file tree
Hide file tree
Showing 44 changed files with 790 additions and 250 deletions.
11 changes: 11 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": ["react-app"],
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"arrow-body-style": ["error", "as-needed"],
"no-unused-expressions": "off",
"no-unused-vars": "error",
"no-duplicate-imports": "error"
}
}
7 changes: 2 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,16 @@
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
"@types/jest": "^24.0.0",
"@types/lodash": "^4.14.149",
"@types/node": "^12.0.0",
"@types/react": "^16.9.0",
"@types/react-dom": "^16.9.0",
"@types/react-redux": "^7.1.7",
"@types/styled-components": "^5.0.1",
"configurable-redux-example": "git+ssh://git@github.com:shivamkantival/configurable-redux-example.git#master",
"lodash": "^4.17.15",
"query-string": "^6.11.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-redux": "^7.2.0",
"react-scripts": "3.4.1",
"redux": "^4.0.5",
"redux-saga": "^1.1.3",
"styled-components": "^5.0.1",
"typescript": "~3.7.2"
},
Expand Down
9 changes: 0 additions & 9 deletions src/App.test.tsx

This file was deleted.

22 changes: 0 additions & 22 deletions src/App.tsx

This file was deleted.

17 changes: 17 additions & 0 deletions src/App/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';

//components
import Header from 'components/Header';
import StyledAppContainer from './styles';
import AppContent from 'components/AppContent';

function App() {
return (
<StyledAppContainer>
<Header className="header" />
<AppContent className="appContent" />
</StyledAppContainer>
);
}

export default App;
17 changes: 17 additions & 0 deletions src/App/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import styled from 'styled-components';
import { flexContainer } from 'styles/mixins';

export default styled.div`
.header {
flex: auto 0 0;
}
.appContent {
flex: auto 1 1;
overflow-y: auto;
height: ;
}
height: 100%;
${flexContainer({ flexDirection: 'column', alignItems: 'stretch' })}
`;
20 changes: 20 additions & 0 deletions src/components/AppContent/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { memo } from 'react';

//constants
import { EMPTY_OBJECT_READONLY } from 'config/constants';

//components
import StyledAppContent from './styles';
import UsersList from 'containers/UsersList';

interface AppContentProps {
className?: string;
}

const AppContent: React.FC<AppContentProps> = (props = EMPTY_OBJECT_READONLY) => (
<StyledAppContent aria-label="main app content" className={props.className}>
<UsersList />
</StyledAppContent>
);

export default memo<AppContentProps>(AppContent);
9 changes: 9 additions & 0 deletions src/components/AppContent/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import styled from 'styled-components';
import { COLORS, spacing } from 'styles/theme';

export default styled.section`
max-width: ${spacing(150)};
width: 100%;
background: ${COLORS.WHITE};
align-self: center;
`;
21 changes: 14 additions & 7 deletions src/components/Header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import React, {memo} from 'react';
import React, { memo } from 'react';

//components
import StyledHeader from "./styles"
import StyledHeader from './styles';

interface HeaderProps {}
//constants
import { EMPTY_OBJECT_READONLY } from 'config/constants';

const Header: React.FC<HeaderProps> = () => {
return <StyledHeader><h4>Users</h4></StyledHeader>
};
interface HeaderProps {
className?: string;
}

export default memo(Header);
const Header: React.FC<HeaderProps> = (props = EMPTY_OBJECT_READONLY) => (
<StyledHeader className={props.className}>
<h3>Users</h3>
</StyledHeader>
);

export default memo<HeaderProps>(Header);
8 changes: 4 additions & 4 deletions src/components/Header/styles.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import styled from 'styled-components';
import { COLORS } from 'styles/theme';
import { COLORS, spacing } from 'styles/theme';
import { flexContainer } from 'styles/mixins';

export default styled.header`
position: sticky;
top: 0;
background: ${COLORS.GAINS_BORO};
height: 50px;
background: ${COLORS.ALTO};
height: ${spacing(15)};
border-bottom: ${spacing(0.5)} solid ${COLORS.GAINS_BORO};
${flexContainer({ alignItems: 'center', justifyContent: 'center' })}
`;
19 changes: 7 additions & 12 deletions src/components/Loader/index.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
import React, {memo} from "react";
import React, { memo } from 'react';

//typeDefs
import {LoaderProps} from "./interfaces";
import { LoaderProps } from './interfaces';

//components
import StyledLoader from "./styles"
import StyledLoader from './styles';

const Loader:React.FC<LoaderProps> = (props) => {
return <StyledLoader dimension={props.dimension}>
const Loader: React.FC<LoaderProps> = ({ dimension, className }) => (
<StyledLoader dimension={dimension} className={className}>
<div className="fixedCenter" />
<div className="outerExpandingConcentric" />
<div className="innerExpandingConcentric" />
</StyledLoader>
}
);


Loader.defaultProps = {
dimension: 100
}

export default memo(Loader);
export default memo<LoaderProps>(Loader);
3 changes: 2 additions & 1 deletion src/components/Loader/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export interface LoaderProps {
dimension?: number;
readonly dimension: number;
readonly className?: string;
}
6 changes: 3 additions & 3 deletions src/components/Loader/styles.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//styles
import { circular, centerToParent } from 'styles/mixins';
import { COLORS } from 'styles/theme';
import { COLORS, spacing } from 'styles/theme';

import styled from 'styled-components';
import { LoaderProps } from './interfaces';
Expand All @@ -20,8 +20,8 @@ const ANIMATION_NAME = 'slowExpand',
LOADER_COLOR: string = COLORS.PARROT_GREEN;

export default styled.div`
width: ${(props: LoaderProps) => `${props.dimension}px`};
height: ${(props: LoaderProps) => `${props.dimension}px`};
width: ${(props: LoaderProps) => `${spacing(props.dimension)}`};
height: ${(props: LoaderProps) => `${spacing(props.dimension)}`};
position: relative;
@keyframes ${ANIMATION_NAME} {
Expand Down
1 change: 0 additions & 1 deletion src/config/constants/actionTypes.ts

This file was deleted.

8 changes: 3 additions & 5 deletions src/config/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
export * from './actionTypes';

export const STATE_KEYS = {
USERS: 'users',
};
export const EMPTY_OBJECT_READONLY = Object.freeze({});
export const EMPTY_ARRAY_READONLY = Object.freeze([]);
export const BASE_API_DOMAIN = 'https://reqres.in';
16 changes: 3 additions & 13 deletions src/config/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
export interface UserData {
name: string;
profileImage: string;
}

export interface UserDataState {
data: Array<UserData>;
error: boolean;
hasError: boolean;
hasMore: boolean;
isLoading: boolean;
loaded: boolean;
total: number;
export interface Action<T, B extends object> {
type: T;
payload: B;
}
24 changes: 24 additions & 0 deletions src/containers/UsersList/components/UserCard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React, { memo } from 'react';

//components
import StyledUserCard from './styles';

//typeDefs
import { User } from '../../interfaces';

type UserCardProps = {
readonly user: User;
readonly className: string;
};

const UserCard: React.FC<UserCardProps> = ({ user, className }) => (
<StyledUserCard role="listitem" className={`userCard ${className}`}>
<div className="userDetailsContainer">
<img src={user.avatar} alt="user profile" className="userImage" />
<h4 className="userName">{user.name}</h4>
</div>
<div className="divider" />
</StyledUserCard>
);

export default memo<UserCardProps>(UserCard);
34 changes: 34 additions & 0 deletions src/containers/UsersList/components/UserCard/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import styled from 'styled-components';
import { circular, flexContainer } from 'styles/mixins';
import { COLORS, spacing } from 'styles/theme';

const TOTAL_CARD_HEIGHT = 24,
SIDE_PADDING = 4,
CONTENT_HEIGHT = TOTAL_CARD_HEIGHT - 2 * SIDE_PADDING;

export default styled.div`
.userDetailsContainer {
padding: ${spacing(SIDE_PADDING)};
height: ${spacing(TOTAL_CARD_HEIGHT)};
${flexContainer({ alignItems: 'center' })}
}
.userImage {
height: ${spacing(CONTENT_HEIGHT)};
width: ${spacing(CONTENT_HEIGHT)};
background: ${COLORS.GAINS_BORO};
${circular()};
}
.divider {
margin: 0 ${spacing(SIDE_PADDING)};
border-bottom: ${spacing(0.25)} solid ${COLORS.ALTO};
}
.userName {
margin-left: ${spacing(6)};
color: ${COLORS.DARK_OUTER_SPACE};
}
${flexContainer({ alignItems: 'stretch', flexDirection: 'column' })}
`;
46 changes: 46 additions & 0 deletions src/containers/UsersList/components/UsersListView/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React, { forwardRef, memo, ReactElement, RefAttributes } from 'react';

//typeDefs
import { User, UsersStore } from '../../interfaces';

//utils
import map from 'lodash/map';
import isEmpty from 'lodash/isEmpty';

//constants
import { EMPTY_ARRAY_READONLY } from 'config/constants';

//components
import StyledUsersListView from './styles';
import Loader from 'components/Loader';
import UserCard from '../UserCard';

interface UsersListViewProps extends Pick<UsersStore, 'isLoading'> {
users: Array<User>;
}

const UsersListView = forwardRef<HTMLDivElement, UsersListViewProps>((props, ref) => {
const { users = EMPTY_ARRAY_READONLY, isLoading } = props,
isLoadingForFirstTime = isLoading && isEmpty(users);

return (
<StyledUsersListView
role="list"
ref={ref}
className={isLoadingForFirstTime ? 'fullPageLoad' : ''}
>
{isLoadingForFirstTime ? (
<Loader dimension={40} className="loader" />
) : (
<>
{map<User, ReactElement>(users, user => (
<UserCard key={user.id} user={user} className="listItem" />
))}
{isLoading && <Loader dimension={10} className="loader listItem" />}
</>
)}
</StyledUsersListView>
);
});

export default memo<RefAttributes<HTMLDivElement> & UsersListViewProps>(UsersListView);
24 changes: 24 additions & 0 deletions src/containers/UsersList/components/UsersListView/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import styled from 'styled-components';
import { flexContainer } from 'styles/mixins';

export default styled.div`
.listItem {
flex: auto 0 0;
}
.loader {
align-self: center;
}
&.fullPageLoad {
justify-content: center;
}
height: 100%;
overflow-y: auto;
${flexContainer({
flexDirection: 'column',
alignItems: 'stretch',
justifyContent: 'flex-start',
})}
`;
Loading

0 comments on commit e97d5b6

Please sign in to comment.