Skip to content
This repository was archived by the owner on Mar 13, 2025. It is now read-only.

Commit 723b97a

Browse files
Merge pull request #69 from topcoder-platform/dev
Release self-service on prod
2 parents cd1bbc3 + 39b5869 commit 723b97a

19 files changed

+434
-35
lines changed

config/dev.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module.exports = {
55
TC_NOTIFICATION_URL: "https://api.topcoder-dev.com/v5/notifications",
66
CONNECT_DOMAIN: "https://connect.topcoder-dev.com",
77
COMMUNITY_DOMAIN: "https://www.topcoder-dev.com",
8+
PLATFORM_DOMAIN: "https://platform.topcoder-dev.com",
89
TAAS_APP: "https://platform.topcoder-dev.com/taas/myteams",
910
},
1011
API: {

config/prod.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module.exports = {
55
TC_NOTIFICATION_URL: "https://api.topcoder.com/v5/notifications",
66
CONNECT_DOMAIN: "https://connect.topcoder.com",
77
COMMUNITY_DOMAIN: "https://www.topcoder.com",
8+
PLATFORM_DOMAIN: "https://platform.topcoder.com",
89
TAAS_APP: "https://platform.topcoder.com/taas/myteams",
910
},
1011
API: {

src/App.jsx

+13-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,19 @@ const App = () => {
5454

5555
return (
5656
<>
57-
<NavBar hideSwitchTools={isNavigationDisabled} />
57+
<Router>
58+
<NavBar
59+
default
60+
noThrow
61+
profileUrl={
62+
location.pathname.includes("/self-service")
63+
? "/self-service/profile/"
64+
: `/profile/${_.get(auth, "profile.handle", "")}`
65+
}
66+
hideSwitchTools={isNavigationDisabled}
67+
path="/*"
68+
/>
69+
</Router>
5870
{!isSideBarDisabled && (
5971
<div className="main-menu-wrapper">
6072
<Router>

src/assets/icons/icon-cross.svg

+3
Loading
+11
Loading

src/components/Button/index.jsx

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* Button
3+
*
4+
* Supports:
5+
* - size - see BUTTON_SIZE values
6+
* - type - see BUTTON_TYPE values
7+
*
8+
* If `routeTo` is set, then button works as React Router Link
9+
*
10+
* if `href` is set, then button is rendered as a link `<a>`
11+
*/
12+
import { Link } from "@reach/router";
13+
import cn from "classnames";
14+
import { BUTTON_SIZE, BUTTON_TYPE } from "constants";
15+
import PT from "prop-types";
16+
import React from "react";
17+
import styles from "./styles.module.scss";
18+
19+
const Button = ({
20+
children,
21+
size = BUTTON_SIZE.SMALL,
22+
type = BUTTON_TYPE.PRIMARY,
23+
onClick,
24+
className,
25+
innerRef,
26+
disabled,
27+
routeTo,
28+
href,
29+
target,
30+
isSubmit,
31+
}) => {
32+
if (href) {
33+
return (
34+
<a
35+
href={href}
36+
target={target}
37+
onClick={onClick}
38+
className={cn(
39+
styles.button,
40+
styles[`type-${type}`],
41+
styles[`size-${size}`],
42+
className
43+
)}
44+
ref={innerRef}
45+
>
46+
{children}
47+
</a>
48+
);
49+
} else {
50+
const button = (
51+
<button
52+
onClick={onClick}
53+
className={cn(
54+
styles.button,
55+
styles[`type-${type}`],
56+
styles[`size-${size}`],
57+
className
58+
)}
59+
ref={innerRef}
60+
disabled={disabled}
61+
type={isSubmit ? "submit" : "button"}
62+
>
63+
{children}
64+
</button>
65+
);
66+
67+
return routeTo ? <Link to={routeTo}>{button}</Link> : button;
68+
}
69+
};
70+
71+
Button.propTypes = {
72+
children: PT.node,
73+
size: PT.oneOf(Object.values(BUTTON_SIZE)),
74+
type: PT.oneOf(Object.values(BUTTON_TYPE)),
75+
onClick: PT.func,
76+
className: PT.string,
77+
innerRef: PT.func,
78+
disabled: PT.bool,
79+
routeTo: PT.string,
80+
href: PT.string,
81+
isSubmit: PT.bool,
82+
};
83+
84+
export default Button;
+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
@import "styles/variables";
2+
@import "styles/mixins";
3+
4+
.button {
5+
@include font-roboto;
6+
background: transparent;
7+
border: 0;
8+
box-sizing: border-box;
9+
cursor: pointer;
10+
align-items: center;
11+
display: flex;
12+
margin: 0;
13+
padding: 0;
14+
text-decoration: none;
15+
outline: none;
16+
white-space: nowrap;
17+
18+
&[disabled] {
19+
cursor: default;
20+
}
21+
}
22+
23+
.size-medium {
24+
border-radius: 20px;
25+
font-size: 14px;
26+
font-weight: 700;
27+
letter-spacing: 0.8px;
28+
line-height: 38px;
29+
height: 40px;
30+
padding: 0 19px;
31+
text-transform: uppercase;
32+
}
33+
34+
.size-small {
35+
border-radius: 15px;
36+
font-size: 12px;
37+
font-weight: 700;
38+
line-height: 28px;
39+
letter-spacing: 0.8px;
40+
height: 30px;
41+
padding: 0 14px;
42+
text-transform: uppercase;
43+
}
44+
45+
.size-tiny {
46+
border-radius: 12px;
47+
padding: 6px 15px;
48+
height: 24px;
49+
font-size: 10px;
50+
font-weight: 700;
51+
line-height: 22px;
52+
letter-spacing: 0.8px;
53+
text-transform: uppercase;
54+
}
55+
56+
.type-primary {
57+
border: 1px solid $green1;
58+
background-color: $green1;
59+
color: #fff;
60+
}
61+
62+
.type-warning {
63+
border: 1px solid #ef476f;
64+
background-color: #ef476f;
65+
color: #fff;
66+
}
67+
68+
.type-secondary {
69+
background-color: #fff;
70+
border: 1px solid $green1;
71+
color: #229174;
72+
}
73+
74+
.type-secondary[disabled] {
75+
border-color: #b5b5b5;
76+
color: #b5b5b5;
77+
}
78+
79+
.type-rounded {
80+
position: relative;
81+
width: 22px;
82+
border-radius: 50%;
83+
background-color: #fff;
84+
border: 1px solid $green1;
85+
color: #229174;
86+
87+
svg {
88+
position: absolute;
89+
left: 37%;
90+
}
91+
}
92+
93+
.type-text {
94+
background-color: #fff;
95+
border: 1px solid #fff;
96+
color: $green1;
97+
}
98+
99+
.type-text-inverted {
100+
background-color: transparent;
101+
border: 1px solid transparent;
102+
color: #fff;
103+
}
104+
105+
.type-rounded[disabled] {
106+
border-radius: 50%;
107+
border-color: #b5b5b5;
108+
color: #b5b5b5;
109+
}
110+
111+
.type-primary[disabled],
112+
.type-warning[disabled] {
113+
background-color: #b5b5b5;
114+
border-color: #b5b5b5;
115+
}

src/components/NavBar/index.jsx

+50-17
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,19 @@ import AllAppsMenu from "../AllAppsMenu";
1717
import { useSelector } from "react-redux";
1818
import { Link, useLocation } from "@reach/router";
1919
import TCLogo from "../../assets/images/tc-logo.svg";
20-
import { getLoginUrl } from "../../utils";
20+
import {
21+
getLoginUrl,
22+
getSelfServiceLoginUrl,
23+
getSelfServiceSignupUrl,
24+
} from "../../utils";
25+
import { BUTTON_TYPE } from "constants/";
2126
import "./styles.css";
2227
import { useMediaQuery } from "react-responsive";
2328
import NotificationsMenu from "../NotificationsMenu";
29+
import Button from "../Button";
2430

25-
const NavBar = ({ hideSwitchTools }) => {
31+
const NavBar = ({ hideSwitchTools, profileUrl }) => {
32+
const [isSelfService, setIsSelfService] = useState(false);
2633
// all menu options
2734
const menu = useSelector((state) => state.menu.categories);
2835
// flat list of all apps
@@ -35,13 +42,19 @@ const NavBar = ({ hideSwitchTools }) => {
3542
});
3643

3744
const routerLocation = useLocation();
45+
46+
const loginUrl = isSelfService ? getSelfServiceLoginUrl() : getLoginUrl();
47+
const signupUrl = isSelfService ? getSelfServiceSignupUrl() : "";
48+
3849
// Check app title with route activated
3950
useEffect(() => {
4051
const activeApp = apps.find(
4152
(f) => routerLocation.pathname.indexOf(f.path) !== -1
4253
);
4354
setActiveApp(activeApp);
44-
}, [routerLocation]);
55+
56+
setIsSelfService(routerLocation.pathname.indexOf("/self-service") !== -1);
57+
}, [routerLocation, apps]);
4558

4659
// Change micro-app callback
4760
const changeApp = useCallback(
@@ -51,13 +64,14 @@ const NavBar = ({ hideSwitchTools }) => {
5164
[setActiveApp]
5265
);
5366

54-
const renderTopcoderLogo = hideSwitchTools ? (
55-
<img src={TCLogo} alt="Topcoder Logo" />
56-
) : (
57-
<Link to="/">
67+
const renderTopcoderLogo =
68+
hideSwitchTools && !isSelfService ? (
5869
<img src={TCLogo} alt="Topcoder Logo" />
59-
</Link>
60-
);
70+
) : (
71+
<Link to={isSelfService ? "/self-service" : "/"}>
72+
<img src={TCLogo} alt="Topcoder Logo" />
73+
</Link>
74+
);
6175

6276
return (
6377
<div className="navbar">
@@ -91,38 +105,55 @@ const NavBar = ({ hideSwitchTools }) => {
91105
(auth.tokenV3 ? (
92106
auth.profile && (
93107
<Fragment>
94-
{hideSwitchTools ? null : <NotificationsMenu />}
108+
<NotificationsMenu />
95109
<UserMenu
110+
profileUrl={profileUrl}
96111
profile={auth.profile}
97112
hideSwitchTools={hideSwitchTools}
98113
/>
99114
</Fragment>
100115
)
101116
) : (
102-
<a href={getLoginUrl()} className="navbar-login">
117+
<a href={loginUrl} className="navbar-login">
103118
Login
104119
</a>
105120
))}
106121
</Fragment>
107122
) : (
108123
<Fragment>
109-
{hideSwitchTools ? null : <AllAppsMenu appChange={changeApp} />}
110-
<div className="navbar-divider"></div>
124+
{hideSwitchTools ? null : (
125+
<Fragment>
126+
<AllAppsMenu appChange={changeApp} />
127+
<div className="navbar-divider" />
128+
</Fragment>
129+
)}
111130
{auth.isInitialized &&
112131
(auth.tokenV3 ? (
113132
auth.profile && (
114133
<Fragment>
115-
{hideSwitchTools ? null : <NotificationsMenu />}
134+
{!isSelfService && <NotificationsMenu />}
116135
<UserMenu
136+
profileUrl={profileUrl}
117137
profile={auth.profile}
118138
hideSwitchTools={hideSwitchTools}
119139
/>
120140
</Fragment>
121141
)
122142
) : (
123-
<a href={getLoginUrl()} className="navbar-login">
124-
Login
125-
</a>
143+
<Fragment>
144+
<a href={loginUrl} className="navbar-login">
145+
Login
146+
</a>
147+
{isSelfService && (
148+
<Button
149+
href={signupUrl}
150+
className="navbar-signup"
151+
type={BUTTON_TYPE.SECONDARY}
152+
>
153+
SIGN UP
154+
</Button>
155+
)}
156+
</Fragment>
126157
))}
127158
</Fragment>
128159
)}
@@ -133,9 +164,11 @@ const NavBar = ({ hideSwitchTools }) => {
133164

134165
NavBar.defaultProps = {
135166
hideSwitchTools: false,
167+
profileUrl: '/profile/',
136168
};
137169

138170
NavBar.propTypes = {
171+
profileUrl: PropTypes.string,
139172
hideSwitchTools: PropTypes.boolean,
140173
};
141174

0 commit comments

Comments
 (0)