mirror of
https://github.com/SomboChea/ui
synced 2026-01-19 01:25:51 +07:00
initial commit
This commit is contained in:
25
src/pages/detail/detail.scss
Normal file
25
src/pages/detail/detail.scss
Normal file
@@ -0,0 +1,25 @@
|
||||
@import '../../styles/variables';
|
||||
@import '../../styles/mixins';
|
||||
|
||||
.twoColumn {
|
||||
@include container-size;
|
||||
display: flex;
|
||||
|
||||
> div {
|
||||
&:first-child {
|
||||
flex-shrink: 1;
|
||||
min-width: 300px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
> aside {
|
||||
&:last-child {
|
||||
margin-left: auto;
|
||||
|
||||
padding-left: 15px;
|
||||
flex-shrink: 0;
|
||||
width: 285px;
|
||||
}
|
||||
}
|
||||
}
|
||||
87
src/pages/detail/index.jsx
Normal file
87
src/pages/detail/index.jsx
Normal file
@@ -0,0 +1,87 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
import PackageDetail from '../../components/PackageDetail';
|
||||
import NotFound from '../../components/NotFound';
|
||||
import Spinner from '../../components/Spinner';
|
||||
import API from '../../utils/api';
|
||||
|
||||
import classes from './detail.scss';
|
||||
import PackageSidebar from '../../components/PackageSidebar/index';
|
||||
|
||||
export default class Detail extends Component {
|
||||
static propTypes = {
|
||||
match: PropTypes.object,
|
||||
isUserLoggedIn: PropTypes.bool,
|
||||
};
|
||||
|
||||
state = {
|
||||
readMe: '',
|
||||
notFound: false,
|
||||
};
|
||||
|
||||
getPackageName(props = this.props) {
|
||||
const params = props.match.params;
|
||||
return `${(params.scope && '@' + params.scope + '/') || ''}${
|
||||
params.package
|
||||
}`;
|
||||
}
|
||||
|
||||
get packageName() {
|
||||
return this.getPackageName();
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
await this.loadPackageInfo(this.packageName);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { isUserLoggedIn, match } = this.props;
|
||||
const condition1 = prevProps.isUserLoggedIn !== isUserLoggedIn;
|
||||
const condition2 =
|
||||
prevProps.match.params.package !== match.params.package;
|
||||
if (condition1 || condition2) {
|
||||
const packageName = this.getPackageName(this.props);
|
||||
this.loadPackageInfo(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
async loadPackageInfo(packageName) {
|
||||
this.setState({
|
||||
readMe: '',
|
||||
});
|
||||
|
||||
try {
|
||||
const resp = await API.request(`package/readme/${packageName}`, 'GET');
|
||||
this.setState({
|
||||
readMe: resp,
|
||||
notFound: false,
|
||||
});
|
||||
} catch (err) {
|
||||
this.setState({
|
||||
notFound: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { notFound, readMe } = this.state;
|
||||
|
||||
if (notFound) {
|
||||
return (
|
||||
<div className={'container content'}>
|
||||
<NotFound pkg={this.packageName} />
|
||||
</div>
|
||||
);
|
||||
} else if (isEmpty(readMe)) {
|
||||
return <Spinner centered={true} />;
|
||||
}
|
||||
return (
|
||||
<div className={`container content ${classes.twoColumn}`}>
|
||||
<PackageDetail packageName={this.packageName} readMe={readMe} />
|
||||
<PackageSidebar packageName={this.packageName} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
16
src/pages/home/home.scss
Normal file
16
src/pages/home/home.scss
Normal file
@@ -0,0 +1,16 @@
|
||||
@import '../../styles/variables';
|
||||
|
||||
.alertError {
|
||||
background-color: $red !important;
|
||||
min-width: inherit !important;
|
||||
}
|
||||
|
||||
.alertErrorMsg {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.alertIcon {
|
||||
opacity: 0.9;
|
||||
margin-right: 8px;
|
||||
}
|
||||
22
src/pages/home/index.js
Normal file
22
src/pages/home/index.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import React, {Component} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import PackageList from '../../components/PackageList';
|
||||
|
||||
class Home extends Component {
|
||||
static propTypes = {
|
||||
isUserLoggedIn: PropTypes.bool.isRequired,
|
||||
packages: PropTypes.array.isRequired,
|
||||
};
|
||||
|
||||
render() {
|
||||
const {packages} = this.props;
|
||||
return (
|
||||
<div className={'container content'}>
|
||||
<PackageList packages={packages} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Home;
|
||||
135
src/pages/version/index.js
Normal file
135
src/pages/version/index.js
Normal file
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* @prettier
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React, {Component} from 'react';
|
||||
import Grid from '@material-ui/core/Grid/index';
|
||||
import Loading from '../../components/Loading';
|
||||
import DetailContainer from '../../components/DetailContainer';
|
||||
import DetailSidebar from '../../components/DetailSidebar';
|
||||
import {callDetailPage} from '../../utils/calls';
|
||||
import {getRouterPackageName} from '../../utils/package';
|
||||
|
||||
export const DetailContext = React.createContext();
|
||||
|
||||
export const DetailContextProvider = DetailContext.Provider;
|
||||
export const DetailContextConsumer = DetailContext.Consumer;
|
||||
|
||||
class VersionPage extends Component<any, any> {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
readMe: '',
|
||||
packageName: getRouterPackageName(props.match),
|
||||
packageMeta: null,
|
||||
isLoading: true,
|
||||
notFound: false,
|
||||
};
|
||||
}
|
||||
|
||||
async componentDidMount() {
|
||||
await this.loadPackageInfo();
|
||||
}
|
||||
|
||||
/* eslint no-unused-vars: 0 */
|
||||
async componentDidUpdate(nextProps: any, prevState: any) {
|
||||
const {packageName} = this.state;
|
||||
if (packageName !== prevState.packageName) {
|
||||
const {readMe, packageMeta} = await callDetailPage(packageName);
|
||||
this.setState({
|
||||
readMe,
|
||||
packageMeta,
|
||||
packageName,
|
||||
notFound: false,
|
||||
isLoading: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps: any, prevState: any) {
|
||||
const {match} = nextProps;
|
||||
const packageName = getRouterPackageName(match);
|
||||
|
||||
if (packageName !== prevState.packageName) {
|
||||
try {
|
||||
return {
|
||||
packageName,
|
||||
isLoading: false,
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
notFound: true,
|
||||
isLoading: false,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async loadPackageInfo() {
|
||||
const {packageName} = this.state;
|
||||
// FIXME: use utility
|
||||
document.title = `Verdaccio - ${packageName}`;
|
||||
|
||||
this.setState({
|
||||
readMe: '',
|
||||
});
|
||||
|
||||
try {
|
||||
const {readMe, packageMeta} = await callDetailPage(packageName);
|
||||
this.setState({
|
||||
readMe,
|
||||
packageMeta,
|
||||
packageName,
|
||||
notFound: false,
|
||||
isLoading: false,
|
||||
});
|
||||
} catch (err) {
|
||||
this.setState({
|
||||
notFound: true,
|
||||
packageName,
|
||||
isLoading: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
enableLoading = () => {
|
||||
this.setState({
|
||||
isLoading: true,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const {isLoading, packageMeta, readMe, packageName} = this.state;
|
||||
|
||||
if (isLoading === false) {
|
||||
return (
|
||||
<DetailContextProvider value={{packageMeta, readMe, packageName, enableLoading: this.enableLoading}}>
|
||||
<Grid className={'container content'} container={true} spacing={0}>
|
||||
<Grid item={true} xs={8}>
|
||||
{this.renderDetail()}
|
||||
</Grid>
|
||||
<Grid item={true} xs={4}>
|
||||
{this.renderSidebar()}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DetailContextProvider>
|
||||
);
|
||||
} else {
|
||||
return <Loading />;
|
||||
}
|
||||
}
|
||||
|
||||
renderDetail() {
|
||||
return <DetailContainer />;
|
||||
}
|
||||
|
||||
renderSidebar() {
|
||||
return <DetailSidebar />;
|
||||
}
|
||||
}
|
||||
|
||||
export default VersionPage;
|
||||
17
src/pages/version/styles.js
Normal file
17
src/pages/version/styles.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @prettier
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import styled from 'react-emotion';
|
||||
import DialogTitle from '@material-ui/core/DialogTitle/index';
|
||||
import colors from '../../utils/styles/colors';
|
||||
import { fontSize } from '../../utils/styles/sizes';
|
||||
|
||||
export const Title = styled(DialogTitle)`
|
||||
&& {
|
||||
background-color: ${colors.primary};
|
||||
color: ${colors.white};
|
||||
font-size: ${fontSize.lg};
|
||||
}
|
||||
`;
|
||||
0
src/pages/version/types.js
Normal file
0
src/pages/version/types.js
Normal file
Reference in New Issue
Block a user