Skip to content

Commit

Permalink
Merge pull request #155 from wakatime/sebas-new-ts-components
Browse files Browse the repository at this point in the history
chore: implement new ts components
  • Loading branch information
jvelezpo authored Jan 16, 2023
2 parents 306a615 + 5486a69 commit 949fff2
Show file tree
Hide file tree
Showing 20 changed files with 1,648 additions and 1,440 deletions.
2,491 changes: 1,117 additions & 1,374 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,18 @@
"jsxhint": "^0.15.1",
"less": "^4.1.3",
"lint-staged": "^13.1.0",
"mocha": "^5.0.0",
"mocha-sinon": "^2.0.0",
"mocha": "^10.2.0",
"mocha-sinon": "^2.1.2",
"node-gyp": "^8.3.0",
"prettier": "^2.8.2",
"prettier-plugin-packagejson": "^2.3.0",
"prettier-plugin-sort-json": "1.0.0",
"remote-redux-devtools": "^0.5.16",
"rimraf": "^3.0.2",
"shelljs": "^0.8.5",
"sinon": "^4.2.2",
"sinon-chai": "^2.8.0",
"sinon-chrome": "^2.2.4",
"sinon": "^15.0.1",
"sinon-chai": "^3.7.0",
"sinon-chrome": "^3.0.1",
"ts-jest": "^29.0.3",
"ts-loader": "^9.4.2",
"ts-node": "^10.9.1",
Expand Down
7 changes: 2 additions & 5 deletions src/components/MainList.test.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
import React from 'react';
import { render } from '@testing-library/react';
import { renderWithProviders } from '../utils/test-utils';
import MainList from './MainList';

type onClick = (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void;
describe('MainList', () => {
let disableLogging: onClick;
let enableLogging: onClick;
let loggedIn: boolean;
let loggingEnabled: boolean;
let logoutUser: onClick;
let totalTimeLoggedToday: string;
beforeEach(() => {
disableLogging = jest.fn();
enableLogging = jest.fn();
loggingEnabled = false;
loggedIn = false;
logoutUser = jest.fn();
totalTimeLoggedToday = '1/1/1999';
});
it('should render properly', () => {
const { container } = render(
const { container } = renderWithProviders(
<MainList
disableLogging={disableLogging}
enableLogging={enableLogging}
loggingEnabled={loggingEnabled}
loggedIn={loggedIn}
logoutUser={logoutUser}
totalTimeLoggedToday={totalTimeLoggedToday}
/>,
Expand Down
19 changes: 12 additions & 7 deletions src/components/MainList.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { ReduxSelector } from '../types/store';
import { User } from '../types/user';

export interface MainListProps {
disableLogging: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void;
enableLogging: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void;
loggedIn: boolean;
loggingEnabled: boolean;
logoutUser: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void;
totalTimeLoggedToday?: string;
Expand All @@ -15,14 +17,17 @@ const openOptionsPage = async (): Promise<void> => {
export default function MainList({
disableLogging,
enableLogging,
loggedIn,
loggingEnabled,
logoutUser,
totalTimeLoggedToday,
}: MainListProps): JSX.Element {
const user: User | undefined = useSelector(
(selector: ReduxSelector) => selector.currentUser.user,
);

return (
<div>
{loggedIn && (
{user && (
<div className="row">
<div className="col-xs-12">
<blockquote>
Expand All @@ -34,7 +39,7 @@ export default function MainList({
</div>
</div>
)}
{loggingEnabled && loggedIn && (
{loggingEnabled && user && (
<div className="row">
<div className="col-xs-12">
<p>
Expand All @@ -45,7 +50,7 @@ export default function MainList({
</div>
</div>
)}
{!loggingEnabled && loggedIn && (
{!loggingEnabled && user && (
<div className="row">
<div className="col-xs-12">
<p>
Expand All @@ -61,15 +66,15 @@ export default function MainList({
<i className="fa fa-fw fa-cogs"></i>
Options
</a>
{loggedIn && (
{user && (
<div>
<a href="#" className="list-group-item" onClick={logoutUser}>
<i className="fa fa-fw fa-sign-out"></i>
Logout
</a>
</div>
)}
{!loggedIn && (
{!user && (
<a
target="_blank"
rel="noreferrer"
Expand Down
180 changes: 180 additions & 0 deletions src/components/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { configLogout, setApiKey } from '../reducers/configReducer';
import { userLogout } from '../reducers/currentUser';
import { ReduxSelector } from '../types/store';
import { User } from '../types/user';
import config from '../config/config';
import apiKeyInvalid from '../utils/apiKey';
import { fetchUserData } from '../utils/user';

export default function NavBar(): JSX.Element {
const [state, setState] = useState({
apiKey: '',
apiKeyError: '',
loading: false,
});
useEffect(() => {
const fetch = async () => {
const { apiKey } = await browser.storage.sync.get({ apiKey: config.apiKey });
setState({ ...state, apiKey });
};

fetch();
}, []);

const dispatch = useDispatch();
const user: User | undefined = useSelector(
(selector: ReduxSelector) => selector.currentUser.user,
);

const signedInAs = () => {
if (user) {
return (
<p className="navbar-text">
Signed in as <b>{user.full_name}</b>
</p>
);
} else {
return <div />;
}
};

const customRules = () => {
if (user) {
return (
<li>
<a target="_blank" href="https://wakatime.com/settings/rules" rel="noreferrer">
<i className="fa fa-fw fa-filter"></i>
Custom Rules
</a>
</li>
);
} else {
return <div />;
}
};

const dashboard = () => {
if (user) {
return (
<li>
<a target="_blank" href="https://wakatime.com/dashboard" rel="noreferrer">
<i className="fa fa-fw fa-tachometer"></i>
Dashboard
</a>
</li>
);
} else {
return <div />;
}
};

return (
<nav className="navbar navbar-default" role="navigation">
<div className="container-fluid">
<div className="navbar-header">
<button
type="button"
className="navbar-toggle collapsed"
data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1"
>
<span className="sr-only">Toggle navigation</span>
<i className="fa fa-fw fa-cogs"></i>
</button>
<a target="_blank" className="navbar-brand" href="https://wakatime.com" rel="noreferrer">
WakaTime
<img src="graphics/wakatime-logo-48.png" />
</a>
</div>
<div className="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
{signedInAs()}
<ul className="nav navbar-nav">
{customRules()}
{dashboard()}
<li className="dropdown">
<a
href="#"
className="dropdown-toggle"
data-toggle="dropdown"
role="button"
aria-expanded="false"
>
<i className="fa fa-fw fa-info"></i>
About
<span className="caret"></span>
</a>
<ul className="dropdown-menu" role="menu">
<li>
<a
target="_blank"
href="https://github.com/wakatime/chrome-wakatime/issues"
rel="noreferrer"
>
<i className="fa fa-fw fa-bug"></i>
Report an Issue
</a>
</li>
<li>
<a
target="_blank"
href="https://github.com/wakatime/chrome-wakatime"
rel="noreferrer"
>
<i className="fa fa-fw fa-github"></i>
View on GitHub
</a>
</li>
</ul>
</li>
<li>
<div className="container-fluid">
{state.apiKeyError && (
<div className="alert alert-danger" role="alert">
{state.apiKeyError}
</div>
)}
<div className="input-group">
<input
type="text"
className="form-control"
placeholder="API key"
value={state.apiKey}
onChange={(e) => {
const key = e.target.value;
const isApiKeyInvalid = apiKeyInvalid(key);
setState({ ...state, apiKey: key, apiKeyError: isApiKeyInvalid });
}}
/>
<span className="input-group-btn">
<button
className={`btn btn-default ${state.loading ? 'disabled' : ''}`}
disabled={state.loading}
type="button"
data-loading-text="Loading..."
onClick={async () => {
if (state.apiKeyError === '' && state.apiKey !== '') {
setState({ ...state, loading: true });
await browser.storage.sync.set({ apiKey: state.apiKey });
dispatch(configLogout());
dispatch(userLogout());
dispatch(setApiKey(state.apiKey));

await fetchUserData(state.apiKey, dispatch);
setState({ ...state, loading: false });
}
}}
>
Save
</button>
</span>
</div>
</div>
</li>
</ul>
</div>
</div>
</nav>
);
}
80 changes: 80 additions & 0 deletions src/components/WakaTime.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import React, { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { ApiKeyReducer, ReduxSelector } from '../types/store';
import config from '../config/config';
import { fetchUserData } from '../utils/user';
import changeExtensionState from '../utils/changeExtensionState';
import NavBar from './NavBar';
import MainList from './MainList';

export default function WakaTime(): JSX.Element {
const dispatch = useDispatch();

const defaultState = {
loggingEnabled: config.loggingEnabled,
totalTimeLoggedToday: '0 minutes',
};
const [state, setState] = useState(defaultState);
const {
apiKey: apiKeyFromRedux,
loggingEnabled,
totalTimeLoggedToday,
}: ApiKeyReducer = useSelector((selector: ReduxSelector) => selector.config);

useEffect(() => {
fetchUserData(apiKeyFromRedux, dispatch);
}, []);

const disableLogging = async () => {
setState({
...state,
loggingEnabled: false,
});

await changeExtensionState('notLogging');

await browser.storage.sync.set({
loggingEnabled: false,
});
};

const enableLogging = async () => {
setState({
...state,
loggingEnabled: true,
});

await changeExtensionState('allGood');

await browser.storage.sync.set({
loggingEnabled: true,
});
};

const logoutUser = async () => {
await browser.storage.sync.set({ apiKey: '' });

setState(defaultState);

await changeExtensionState('notSignedIn');
};

return (
<div>
<NavBar />
<div className="container">
<div className="row">
<div className="col-md-12">
<MainList
disableLogging={disableLogging}
enableLogging={enableLogging}
loggingEnabled={loggingEnabled}
totalTimeLoggedToday={totalTimeLoggedToday}
logoutUser={logoutUser}
/>
</div>
</div>
</div>
</div>
);
}
1 change: 1 addition & 0 deletions src/config/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('wakatime config', () => {
"type": "success",
},
},
"apiKey": "",
"colors": {
"allGood": "",
"lightTheme": "white",
Expand Down
Loading

0 comments on commit 949fff2

Please sign in to comment.