Fakultas Ilmu Komputer UI

Commit 1a17638c authored by M. Reza Qorib's avatar M. Reza Qorib
Browse files

Merge branch 'UserStory3' of https://gitlab.com/PPL2017csui/PPLA1 into Features/react-routing

# Conflicts:
#	assets/js/index.jsx
parents 5f81b015 b8438bad
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
"func-names": ["error", "never"], "func-names": ["error", "never"],
"react/prefer-stateless-function": [0, { "ignorePureComponents": true }], "react/prefer-stateless-function": [0, { "ignorePureComponents": true }],
"react/forbid-prop-types": [0], "react/forbid-prop-types": [0],
"react/no-multi-comp": [0, { "ignoreStateless": 1 }],
"import/extensions": ["off", "never"], "import/extensions": ["off", "never"],
"import/no-unresolved": 0, "import/no-unresolved": 0,
"no-underscore-dangle" : 0, "no-underscore-dangle" : 0,
......
...@@ -12,3 +12,4 @@ test/* ...@@ -12,3 +12,4 @@ test/*
.coverage .coverage
.tmp/ .tmp/
npm-debug.log npm-debug.log
debug.log
body{
padding: 0;
height: auto;
width: auto;
background-color: black;
}
.center{ .center{
text-align: center; text-align: center;
} }
* { * {
box-sizing: border-box; box-sizing: border-box;
-webkit-box-sizing: border-box; -webkit-box-sizing: border-box;
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
} }
body {
font: 300 14px/1.4 'Helvetica Neue', Helvetica, Arial, sans-serif; .applicant{
margin: 0; margin-left: 150px;
padding: 0; margin-right: 150px;
}
.ui.inverted.segment.header{
background-color: #EEEEEE;
color:black;
} }
.halamanLowongan{
.ui.card.register{
background-color: #EEEEEE;
} }
.create-lowongan{
margin: 60px 19% 100px;
}
.ui.segment.form-segment{
padding-bottom: 50px;
}
.tabs { .tabs {
margin-top: 100px;
margin-left: 150px;
margin-right: 150px;
background: #fff; background: #fff;
border: 1px solid #e5e5e5; border: 1px solid #e5e5e5;
border-radius: 3px; border-radius: 3px;
margin-bottom: 30px; margin: 100px 100px 30px;
} }
.tabs__labels { .tabs__labels {
margin: 0; margin: 0;
...@@ -59,29 +59,23 @@ body { ...@@ -59,29 +59,23 @@ body {
} }
.halamanLogin{ .halamanLogin{
background-image: url("../img/bw.jpg");
background-size: cover; background-size: cover;
background-position: center; background: url("../img/background.png")no-repeat center center fixed;
background-attachment: fixed; -webkit-background-size: cover;
height: 700px; -moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
padding-bottom: 80px;
} }
.register{
margin-left:180px;
margin-right:110px;
.headerLoginform{
background-color: #2e6da4;
} }
.formLogin{ .formLogin{
margin: 0 auto; margin: 30px auto 0;
margin-top: 100px; width: 430px;
width: 430px;
border: 2px solid transparent;
border-radius: 12px;
border-color:#e8e8e8;
padding: 20px;
background-color: white;
} }
.registerModal{ .registerModal{
...@@ -95,7 +89,6 @@ padding: 20px; ...@@ -95,7 +89,6 @@ padding: 20px;
.formLogin img{ .formLogin img{
height: 70px !important; height: 70px !important;
margin:5px; margin:5px;
margin-bottom:30px;
} }
.formLogin span{ .formLogin span{
...@@ -115,7 +108,7 @@ font-size: 32px; ...@@ -115,7 +108,7 @@ font-size: 32px;
} }
.daftar{ .daftar{
float: right; float: right;
margin-top:10px; margin-top:10px;
} }
.coverLetter{ .coverLetter{
...@@ -129,23 +122,24 @@ font-size: 32px; ...@@ -129,23 +122,24 @@ font-size: 32px;
margin-bottom: 10px; margin-bottom: 10px;
} }
.registerForm{ .registerForm{
margin: 0 auto; margin: 0 auto;
padding:50px; /*padding:50px;*/
background-color: #3B8686; background-color: #3B8686;
} }
item{ h3{
color:black; color:black;
} }
textarea{ h4{
width: 800px !important; color: black;
height: 160px !important;
} }
h5{
color: black;
}
.note { .note {
color: gray; color: gray;
...@@ -170,7 +164,19 @@ card .formRegis{ ...@@ -170,7 +164,19 @@ card .formRegis{
margin-top: 100px; margin-top: 100px;
} }
itemLowongan{ .itemLowongan{
color: black;
}
.ui.pointing.secondary.menu{
background-color: #ffffff;
}
.extra.extra-company h3{
padding-top:10px;
}
.extra.extra-company h2{
color: black; color: black;
} }
import React from 'react';
import Tabs from './components/Tabs';
import Pane from './components/Pane';
import Storage from './lib/Storage';
import VacancyList from './components/VacancyList';
export default class VacancyPage extends React.Component {
constructor(props) {
super(props);
/* istanbul ignore next */
this.state = {
email: '',
password: '',
errorFlag: false,
vacancies: [],
};
this.handleItemClick = this.handleItemClick.bind(this);
}
handleItemClick = (e, { name }) => this.setState({ activeItem: name });
render() {
const student = Storage.get('user-data').student;
return (
<div className="halamanPendaftar">
<Tabs selected={0}>
<Pane label="Lamaran Baru" >
<VacancyList key={1} studentId={student.id} url="/vacancies/" />
</Pane>
<Pane label="Bintangi" >
<VacancyList key={2} status="Batal" studentId={student.id} url={`/students/${student.id}/applied-vacancies/`} />
</Pane>
<Pane label="Semua Lamaran" >
<VacancyList key={3} studentId={student.id} url={`/students/${student.id}/bookmarked-vacancies/`} />
</Pane>
</Tabs>
</div>
);
}
}
import React from 'react';
import { Segment, Button, Form, Header, Icon, Input } from 'semantic-ui-react';
import { browserHistory } from 'react-router';
import DatePicker from 'react-datepicker';
import moment from 'moment';
import ModalAlert from './components/ModalAlert';
import Server from './lib/Server';
import Storage from './lib/Storage';
import Dumper from './lib/Dumper';
export default class CreateVacancy extends React.Component {
static propTypes = {
params: React.PropTypes.object.isRequired,
};
constructor(props) {
super(props);
/* istanbul ignore next */
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {
formLoading: false,
company: Storage.get('user-data').company,
vacancyId: this.props.params.id,
open_time: moment(),
close_time: moment(),
name: '',
description: '',
};
this.state.vacancyId && Server.get(`/vacancies/${this.state.vacancyId}/`).then((r) => {
this.setState({
description: r.description,
name: r.name,
open_time: moment(r.open_time),
close_time: moment(r.close_time),
});
});
}
handleChange = (e) => {
this.setState({ [e.target.name]: e.target.value });
};
handleSubmit = (e) => {
e.preventDefault();
this.setState({ formLoading: true });
const data = Object.assign({}, this.state);
data.open_time = data.open_time.format();
data.close_time = data.close_time.format();
data.company = this.state.company.id;
const url = this.state.vacancyId ? `/vacancies/${this.state.vacancyId}/` : '/vacancies/';
const method = this.state.vacancyId ? 'PATCH' : 'POST';
Server.sendRequest(url, method, data).then(() => {
browserHistory.push('/lowongan');
}, error => error.then((r) => {
this.modalAlert.open('Gagal Membuat Lowongan', Dumper.dump(r, ' '));
this.setState({ formLoading: false });
}));
};
render = () => (
<div className="create-lowongan" >
<ModalAlert ref={(modal) => { this.modalAlert = modal; }} />
<Segment className="form-segment">
<Header as="h2" icon textAlign="center">
<Icon name="briefcase" circular />
<Header.Content>
Lowongan KP
</Header.Content>
</Header>
<Form loading={this.state.formLoading} onSubmit={this.handleSubmit}>
<Form.Field label="Posisi" name="name" control={Input} onChange={this.handleChange} value={this.state.name} required />
<Form.TextArea
name="description"
label="Deskripsi"
placeholder="Deskripsi Lowongan..."
onChange={this.handleChange}
value={this.state.description} required
/>
<Form.Group widths="equal">
<Form.Field
className="open-time-field"
control={DatePicker}
label="Waktu Buka Lowongan"
selected={this.state.open_time}
onChange={date => this.setState({ open_time: date })}
required
/>
<Form.Field
className="close-time-field"
control={DatePicker}
label="Waktu Tutup Lowongan"
selected={this.state.close_time}
onChange={date => this.setState({ close_time: date })}
required
/>
</Form.Group>
<Button type="submit" primary floated="right">Submit</Button>
</Form>
</Segment>
</div>
);
}
import React from 'react'; import React from 'react';
import { Grid, Segment, Card } from 'semantic-ui-react'; import { Grid, Segment, Header, Card, Image } from 'semantic-ui-react';
import LoginForm from './components/LoginForm'; import LoginForm from './components/LoginForm';
import RegisterModal from './components/RegisterModal'; import CompanyRegisterModal from './components/CompanyRegisterModal';
export default class Login extends React.Component { export default class Login extends React.Component {
...@@ -17,26 +17,37 @@ export default class Login extends React.Component { ...@@ -17,26 +17,37 @@ export default class Login extends React.Component {
}; };
render = () => ( render = () => (
<div className="halamanLogin"> <div className="halamanLogin">
<Grid columns={2} relaxed> <div className="headerLogin">
<Header as="h2" icon textAlign="center" >
<Image src="/assets/img/logo.png" size="medium" centered />
<Header.Content >
Kanal Akses Pendaftaran KP Elektronik
</Header.Content>
</Header>
</div>
<Grid stackable columns={2} relaxed>
<Grid.Column> <Grid.Column>
<Segment basic> <Segment basic>
<LoginForm type="company" header="Company Login" imgSrc="logo.png" imgSize="small" /> <LoginForm type="company" header="Company Login" imgSrc="logo.png" imgSize="small" />
{this.props.children} {this.props.children}
</Segment > </Segment >
<div className="register"> <div className="register">
<Card> <Card centered className="register" >
<Card.Content> <Card.Content>
<Card.Header> <Grid columns={2} relaxed>
New to us ? <Grid.Column>
</Card.Header> <Header as="h3">New to us ?</Header>
<RegisterModal /> </Grid.Column>
<Grid.Column>
<CompanyRegisterModal />
</Grid.Column>
</Grid>
</Card.Content> </Card.Content>
</Card> </Card>
</div> </div>
</Grid.Column> </Grid.Column>
<Grid.Column> <Grid.Column>
...@@ -45,7 +56,6 @@ export default class Login extends React.Component { ...@@ -45,7 +56,6 @@ export default class Login extends React.Component {
{this.props.children} {this.props.children}
</Segment> </Segment>
</Grid.Column> </Grid.Column>
</Grid> </Grid>
</div> </div>
) )
......
...@@ -6,38 +6,78 @@ import VacancyList from './components/VacancyList'; ...@@ -6,38 +6,78 @@ import VacancyList from './components/VacancyList';
export default class VacancyPage extends React.Component { export default class VacancyPage extends React.Component {
static getRole() {
const student = Storage.get('user-data').student;
const company = Storage.get('user-data').company;
if (student) {
return { id: student.id, type: 'student' };
} else if (company) {
return { id: company.id, type: 'company' };
}
return { id: '0', type: 'error' };
}
constructor(props) { constructor(props) {
super(props); super(props);
/* istanbul ignore next */ /* istanbul ignore next */
const role = VacancyPage.getRole();
this.state = { this.state = {
email: '',
password: '',
errorFlag: false,
vacancies: [], vacancies: [],
student: false, id: role.id,
role: role.type,
}; };
Storage.getUserData().then(r => this.setState({ student: r.student }));
this.handleItemClick = this.handleItemClick.bind(this);
} }
handleItemClick = (e, { name }) => this.setState({ activeItem: name }); generateVacancies() {
if (this.state.role === 'student') {
render = () => ( return (
this.state.student && (
<div className="halamanLowongan">
<Tabs selected={0}> <Tabs selected={0}>
<Pane label="Semua Lowongan" > <Pane label="Semua Lowongan" >
<VacancyList key={1} studentId={this.state.student.id} url="/vacancies/" /> <VacancyList
key={1}
userId={this.state.id}
url="/vacancies/"
/>
</Pane> </Pane>
<Pane label="Lamaran saya" > <Pane label="Lamaran saya" >
<VacancyList key={2} status="Batal" studentId={this.state.student.id} url={`/students/${this.state.student.id}/applied-vacancies/`} /> <VacancyList
key={2}
status="Batal"
userId={this.state.id}
url={`/students/${this.state.id}/applied-vacancies/`}
/>
</Pane> </Pane>
<Pane label="Lamaran Ditandai" > <Pane label="Lamaran Ditandai" >
<VacancyList key={3} studentId={this.state.student.id} url={`/students/${this.state.student.id}/bookmarked-vacancies/`} /> <VacancyList
key={3}
userId={this.state.id}
url={`/students/${this.state.id}/bookmarked-vacancies/`}
/>
</Pane> </Pane>
</Tabs> </Tabs>
);
} else if (this.state.role === 'company') {
return (
<VacancyList key={1} userId={this.state.id} url={`/companies/${this.state.id}/vacancies/`} type="company" />
);
}
return (
<div>
<h3>
Anda tidak terautentifikasi. Harap logout dan login
kembali dengan akun yang benar
</h3>
</div> </div>
) );
); }
render() {
return (
<div className="applicant">
{ this.generateVacancies() }
</div>
);
}
} }
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import fetchMock from 'fetch-mock';
import CreateVacancy from '../CreateVacancy';
import Storage from '../lib/Storage';
describe('CreateVacancy', () => {
const companySession = {
url: 'http://localhost:8001/api/users/8/',
username: 'Tutuplapak',
email: '',
is_staff: false,
company: {
id: 3,
user: {
url: 'http://localhost:8001/api/users/8/',
username: 'Tutuplapak',
email: '',