File clean up. Refactor header.

This commit is contained in:
Patrick Fic
2020-02-07 17:03:21 -08:00
parent d3bd68d40a
commit a3c66866d3
17 changed files with 181 additions and 248 deletions

View File

@@ -5165,6 +5165,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>manageroot</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>profile</name>
<definition_loaded>false</definition_loaded>
@@ -5304,6 +5325,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>photourl</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
</children>
</folder_node>
</children>

View File

@@ -1,6 +1,7 @@
{
"short_name": "Bodyshop",
"short_name": "Bodyshop.app",
"name": "Bodyshop Management System",
"description": "The ultimate bodyshop management system",
"icons": [
{
"src": "favicon.ico",
@@ -20,6 +21,6 @@
],
"start_url": ".",
"display": "standalone",
"theme_color": "#002366",
"background_color": "#000000"
"theme_color": "#fff",
"background_color": "#fff"
}

View File

@@ -1,79 +0,0 @@
import { Avatar, Col, Dropdown, Icon, Menu, Row } from "antd";
import i18next from "i18next";
import React from "react";
import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { createStructuredSelector } from "reselect";
import UserImage from "../../assets/User.svg";
import { setUserLanguage, signOutStart } from "../../redux/user/user.actions";
import { selectCurrentUser } from "../../redux/user/user.selectors";
import SignOut from "../sign-out/sign-out.component";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser
});
const mapDispatchToProps = dispatch => ({
signOutStart: () => dispatch(signOutStart()),
setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(function CurrentUserDropdown({ currentUser, signOutStart, setUserLanguage }) {
const { t } = useTranslation();
const handleMenuClick = e => {
if (e.item.props.actiontype === "lang-select") {
i18next.changeLanguage(e.key, (err, t) => {
if (err)
return console.log("Error encountered when changing languages.", err);
setUserLanguage(e.key);
console.log("clicking");
});
}
};
const menu = (
<Menu mode="vertical" onClick={handleMenuClick}>
<Menu.Item>
<SignOut signOutStart={signOutStart} />
</Menu.Item>
<Menu.Item>
<Link to="/manage/profile"> {t("menus.currentuser.profile")}</Link>
</Menu.Item>
<Menu.SubMenu
title={
<span>
<Icon type="global" />
<span>{t("menus.currentuser.languageselector")}</span>
</span>
}
>
<Menu.Item actiontype="lang-select" key="en_us">
{t("general.languages.english")}
</Menu.Item>
<Menu.Item actiontype="lang-select" key="fr">
{t("general.languages.french")}
</Menu.Item>
<Menu.Item actiontype="lang-select" key="es">
{t("general.languages.spanish")}
</Menu.Item>
</Menu.SubMenu>
</Menu>
);
return (
<Dropdown overlay={menu}>
<Row>
<Col span={8}>
<Avatar size="large" alt="Avatar" src={UserImage} />
</Col>
<Col span={16} style={{ color: "white" }}>
{currentUser.displayName || t("general.labels.unknown")}
</Col>
</Row>
</Dropdown>
);
});

View File

@@ -4,7 +4,7 @@ import React from "react";
export default function FooterComponent() {
return (
<Row>
<Col span={8} offset={9}>
<Col span={8} offset={8}>
Copyright Snapt Software 2019. All rights reserved.
</Col>
</Row>

View File

@@ -1,79 +0,0 @@
import React from "react";
// import { Icon, Button, Input, AutoComplete } from "antd";
// const { Option } = AutoComplete;
// function onSelect(value) {
// console.log("onSelect", value);
// }
// function getRandomInt(max, min = 0) {
// return Math.floor(Math.random() * (max - min + 1)) + min; // eslint-disable-line no-mixed-operators
// }
// function searchResult(query) {
// return new Array(getRandomInt(5))
// .join(".")
// .split(".")
// .map((item, idx) => ({
// query,
// category: `${query}${idx}`,
// count: getRandomInt(200, 100)
// }));
// }
// function renderOption(item) {
// return (
// <Option key={item.category} text={item.category}>
// <div className='global-search-item'>
// <span className='global-search-item-desc'>
// Found {item.query} on
// <a
// href={`https://s.taobao.com/search?q=${item.query}`}
// target='_blank'
// rel='noopener noreferrer'>
// {item.category}
// </a>
// </span>
// <span className='global-search-item-count'>{item.count} results</span>
// </div>
// </Option>
// );
// }
export default class GlobalSearch extends React.Component {
state = {
dataSource: []
};
// handleSearch = value => {
// this.setState({
// dataSource: value ? searchResult(value) : []
// });
// };
render() {
return (
<div />
// <div style={{ width: 300 }}>
// <AutoComplete
// size="large"
// style={{ width: "100%" }}
// dataSource={dataSource.map(renderOption)}
// onSelect={onSelect}
// onSearch={this.handleSearch}
// placeholder="input here"
// optionLabelProp="text"
// >
// <Input
// suffix={
// <Button style={{ marginRight: -12 }} size="large" type="primary">
// <Icon type="search" />
// </Button>
// }
// />
// </AutoComplete>
// </div>
);
}
}

View File

@@ -1,27 +1,35 @@
import { Col, Icon, Menu, Row } from "antd";
import { Avatar, Col, Icon, Menu, Row } from "antd";
import React from "react";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import CurrentUserDropdown from "../current-user-dropdown/current-user-dropdown.component";
import GlobalSearch from "../global-search/global-search.component";
import UserImage from "../../assets/User.svg";
import { signOutStart } from "../../redux/user/user.actions";
import ManageSignInButton from "../manage-sign-in-button/manage-sign-in-button.component";
export default ({ landingHeader, selectedNavItem }) => {
export default ({
landingHeader,
selectedNavItem,
logo,
handleMenuClick,
currentUser
}) => {
const { t } = useTranslation();
//TODO Add
return (
<Row type="flex" justify="space-around">
<Col span={16}>
<Row type="flex" justify="space-around" align="middle">
{logo ? (
<Col span={4}>
<img alt="Shop Logo" src={logo} style={{ height: "40px" }} />
</Col>
) : null}
<Col span={14}>
<Menu
theme="dark"
className="header"
selectedKeys={selectedNavItem}
mode="horizontal"
onClick={handleMenuClick}
>
<Menu.Item>
<GlobalSearch />
</Menu.Item>
<Menu.Item key="home">
<Link to="/manage">
<Icon type="home" />
@@ -64,16 +72,47 @@ export default ({ landingHeader, selectedNavItem }) => {
</Menu.Item>
</Menu.SubMenu>
{!landingHeader ? null : (
<Menu.Item>
<ManageSignInButton />
<Menu.SubMenu
title={
<div>
<Avatar
size="medium"
alt="Avatar"
src={currentUser.photoURL ? currentUser.photoURL : UserImage}
style={{ margin: "10px" }}
/>
{currentUser.displayName || t("general.labels.unknown")}
</div>
}
>
<Menu.Item onClick={signOutStart()}>
{t("user.actions.signout")}
</Menu.Item>
)}
<Menu.Item>
<Link to="/manage/profile">{t("menus.currentuser.profile")}</Link>
</Menu.Item>
<Menu.SubMenu
title={
<span>
<Icon type="global" />
<span>{t("menus.currentuser.languageselector")}</span>
</span>
}
>
<Menu.Item actiontype="lang-select" key="en_us">
{t("general.languages.english")}
</Menu.Item>
<Menu.Item actiontype="lang-select" key="fr">
{t("general.languages.french")}
</Menu.Item>
<Menu.Item actiontype="lang-select" key="es">
{t("general.languages.spanish")}
</Menu.Item>
</Menu.SubMenu>
</Menu.SubMenu>
</Menu>
</Col>
<Col span={6} offset={2}>
{!landingHeader ? <CurrentUserDropdown /> : null}
</Col>
<Col span={4}>{!landingHeader ? null : <ManageSignInButton />}</Col>
</Row>
);
};

View File

@@ -1,8 +1,52 @@
import React from "react";
import HeaderComponent from "./header.component";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import i18next from "i18next";
import { setUserLanguage, signOutStart } from "../../redux/user/user.actions";
import {
selectCurrentUser,
selectBodyshop
} from "../../redux/user/user.selectors";
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
bodyshop: selectBodyshop
});
const mapDispatchToProps = dispatch => ({
signOutStart: () => dispatch(signOutStart()),
setUserLanguage: language => dispatch(setUserLanguage(language))
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(function HeaderContainer({
landingHeader,
currentUser,
bodyshop,
signOutStart,
setUserLanguage
}) {
const handleMenuClick = e => {
if (e.item.props.actiontype === "lang-select") {
i18next.changeLanguage(e.key, (err, t) => {
if (err)
return console.log("Error encountered when changing languages.", err);
setUserLanguage(e.key);
});
}
};
export default ({ landingHeader, signedIn }) => {
return (
<HeaderComponent landingHeader={landingHeader} selectedNavItem={null} />
<HeaderComponent
handleMenuClick={handleMenuClick}
signOutStart={signOutStart}
landingHeader={landingHeader}
selectedNavItem={null}
currentUser={currentUser}
logo={bodyshop ? bodyshop.logo_img_path : null}
/>
);
};
});

View File

@@ -37,7 +37,10 @@ export default connect(
}
if (!err) {
console.log("values", values);
updateUserDetails({ displayName: values.displayname });
updateUserDetails({
displayName: values.displayname,
photoURL: values.photoURL
});
}
});
};
@@ -59,6 +62,12 @@ export default connect(
rules: [{ required: true }]
})(<Input name="displayname" />)}
</Form.Item>
<Form.Item label={t("user.fields.photourl")}>
{getFieldDecorator("photoURL", {
initialValue: currentUser.photoURL
})(<Input name="photoURL" />)}
</Form.Item>
<Button
type="primary"
key="submit"

View File

@@ -1,8 +0,0 @@
import React from "react";
import { useTranslation } from "react-i18next";
export default function SignoutComponent({ signOutStart }) {
const { t } = useTranslation();
return <div onClick={signOutStart}>{t("user.actions.signout")}</div>;
}

View File

@@ -1,45 +0,0 @@
import React, { useState } from "react";
export default WithInlineEdit = WrappedComponent => props => {
const [editing, setEditing] = useState(false);
const [modified, setModified] = useState(false);
const [originalValue, setOriginalValue] = useState(null);
const toggleEdit = () => {
setEditing(!editing);
if (editing) {
this.input.focus();
}
};
return editing ? (
<Form.Item style={{ margin: 0 }}>
{form.getFieldDecorator(dataIndex, {
rules: [
{
required: true,
message: `${title} is required.`
}
],
initialValue: record[dataIndex]
})(
<Input
ref={node => (this.input = node)}
onPressEnter={this.save}
onBlur={this.save}
/>
)}
</Form.Item>
) : (
<div
className="editable-cell-value-wrap"
style={{ paddingRight: 24 }}
onClick={toggleEdit}
>
{children}
</div>
);
};
export default WithInlineEdit;

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.0 KiB

View File

@@ -1,8 +1,11 @@
import React from 'react'
import ManageRootPageComponent from './manage-root.page.component'
import React, { useEffect } from "react";
import ManageRootPageComponent from "./manage-root.page.component";
import { useTranslation } from "react-i18next";
export default function ManageRootPageContainer() {
return (
<ManageRootPageComponent />
)
const { t } = useTranslation();
useEffect(() => {
document.title = t("titles.manageroot");
}, [t]);
return <ManageRootPageComponent />;
}

View File

@@ -9,7 +9,6 @@ import HeaderContainer from "../../components/header/header.container";
import LoadingSpinner from "../../components/loading-spinner/loading-spinner.component";
import "./manage.page.styles.scss";
const ManageRootPage = lazy(() =>
import("../manage-root/manage-root.page.container")
);

View File

@@ -34,6 +34,7 @@ export function* signInWithEmail({ payload: { email, password } }) {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL,
authorized: true
})
);
@@ -62,6 +63,7 @@ export function* isUserAuthenticated() {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL,
authorized: true
})
);

View File

@@ -327,6 +327,7 @@
"jobsavailable": "Available Jobs | $t(titles.app)",
"jobsdetail": "Job {{ro_number}} | $t(titles.app)",
"jobsdocuments": "Job Documents {{ro_number}} | $t(titles.app)",
"manageroot": "Home | $t(titles.app)",
"profile": "My Profile | $t(titles.app)",
"schedule": "Schedule | $t(titles.app)",
"vehicledetail": "Vehicle Details {{vehicle}} | $t(titles.app)"
@@ -337,7 +338,8 @@
"updateprofile": "Update Profile"
},
"fields": {
"displayname": "Display Name"
"displayname": "Display Name",
"photourl": "Avatar URL"
}
},
"vehicles": {

View File

@@ -327,6 +327,7 @@
"jobsavailable": "Empleos disponibles | $t(titles.app)",
"jobsdetail": "Trabajo {{ro_number}} | $t(titles.app)",
"jobsdocuments": "Documentos de trabajo {{ro_number}} | $ t (títulos.app)",
"manageroot": "Casa | $t(titles.app)",
"profile": "Mi perfil | $t(titles.app)",
"schedule": "Horario | $t(titles.app)",
"vehicledetail": "Detalles del vehículo {{vehicle}} | $t(titles.app)"
@@ -337,7 +338,8 @@
"updateprofile": "Actualización del perfil"
},
"fields": {
"displayname": "Nombre para mostrar"
"displayname": "Nombre para mostrar",
"photourl": "URL de avatar"
}
},
"vehicles": {

View File

@@ -327,6 +327,7 @@
"jobsavailable": "Emplois disponibles | $t(titles.app)",
"jobsdetail": "Travail {{ro_number}} | $t(titles.app)",
"jobsdocuments": "Documents de travail {{ro_number}} | $ t (titres.app)",
"manageroot": "Accueil | $t(titles.app)",
"profile": "Mon profil | $t(titles.app)",
"schedule": "Horaire | $t(titles.app)",
"vehicledetail": "Détails du véhicule {{vehicle} | $t(titles.app)"
@@ -337,7 +338,8 @@
"updateprofile": "Mettre à jour le profil"
},
"fields": {
"displayname": "Afficher un nom"
"displayname": "Afficher un nom",
"photourl": "URL de l'avatar"
}
},
"vehicles": {