Fakultas Ilmu Komputer UI

Commit 86332029 authored by Joshua Casey's avatar Joshua Casey
Browse files

Merge branch 'UserStory2' of https://gitlab.com/PPL2017csui/PPLA1 into UserStory2

parents 42a42d4c 88e9d391
html, body{
padding: 0;
height: auto;
......@@ -49,42 +51,42 @@ body {
padding: 25px;
}
.halamanLogin{
background-image: url("../img/bw.jpg");
background-size: cover;
background-position: center;
background-attachment: fixed;
height: 700px;
}
.formLogin{
margin: 0 auto;
margin-top: 100px;
width: 430px;
border: 2px solid transparent;
border-radius: 12px;
background-color: transparent;
padding: 10px;
border-color:#e8e8e8;
padding: 20px;
background-color: white;
}
.formLogin span{
font-size: 30px;
}
.formLogin span{
margin-left: 10px;
.bookmark{
float: right;
}
.SsoLogin{
margin: 0 auto;
margin-top: 100px;
width: 430px;
border: 2px solid transparent;
border-radius: 12px;
background-color: transparent;
padding: 10px;
.formLogin img{
height: 70px !important;
margin:5px;
margin-bottom:30px;
}
.SsoLogin span{
font-size: 30px;
.formLogin span{
font-size: 32px;
}
.SsoLogin span{
margin-left: 10px;
.formLogin span{
margin-left: 5px;
}
.LoginPage{
......@@ -156,4 +158,5 @@ card .formRegis{
itemLowongan{
color: black;
}
\ No newline at end of file
}
......@@ -7,7 +7,6 @@ import Login from './Login';
import VacancyPage from './VacancyPage';
import CompanyRegister from './CompanyRegister';
import Server from './lib/Server';
// import Register from './CompanyRegister'
export const Profile = () => (
<Segment>
......@@ -22,12 +21,17 @@ export default class App extends React.Component {
super(props);
/* istanbul ignore next */
this.handleAuth = this.handleAuth.bind(this);
this.handleHome = this.handleHome.bind(this);
}
handleAuth = (nextState, replace) => (
Server.isLoggedIn() || replace({ pathname: '/login' })
);
handleHome= (nextState, replace) => (
Server.isLoggedIn() ? replace({ pathname: '/lowongan' }) : replace({ pathname: '/login' })
);
render = () => (
<Router history={browserHistory}>
......@@ -39,7 +43,8 @@ export default class App extends React.Component {
<Route path="/lowongan" component={VacancyPage} />
<Route path="/users" component={Profile} />
</Route>
<Redirect from="*" to={Server.isLoggedIn() ? '/lowongan' : '/login'} />
<Route path="/home" onEnter={this.handleHome} />
<Redirect from="*" to="/home" />
</Router>
);
}
......
......@@ -16,6 +16,8 @@ export default class Login extends React.Component {
};
render = () => (
<div className="halamanLogin">
<Grid columns={2} relaxed>
<Grid.Column>
<Segment basic>
......@@ -32,6 +34,7 @@ export default class Login extends React.Component {
</Grid.Column>
</Grid>
</div>
)
}
// /* eslint-disable no-unused-expressions */
// import React from 'react';
// import ReactTestUtils from 'react-addons-test-utils';
// import Lowongan from '../components/ComponentRegister';
// import Vacancy from '../components/ComponentRegister';
//
// describe('Lowongan', () => {
// describe('Vacancy', () => {
// it('renders without problem', () => {
// let companyRegister = ReactTestUtils.renderIntoDocument(
// <CompanyRegister />);
......
/* eslint-disable no-unused-expressions */
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import Lowongan from '../../components/Lowongan';
describe('Lowongan', () => {
it('renders without problem', () => {
let lowongan = ReactTestUtils.renderIntoDocument(
<Lowongan />);
expect(lowongan).to.exist;
lowongan = ReactTestUtils.renderIntoDocument(
<Lowongan image="img" header="header" content="content" paragraph="paragraph"/>);
expect(lowongan).to.exist;
});
});
\ No newline at end of file
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import ModalAlert from '../../components/ModalAlert';
describe('ModalAlert', () => {
it('renders without problem', () => {
const modalAlert = ReactTestUtils.renderIntoDocument(
<ModalAlert id={4} coverLetter="letter" onChangeValue={() => {}}/>);
expect(modalAlert).to.exist;
});
});
\ No newline at end of file
......@@ -5,8 +5,17 @@ import ModalPendaftaran from '../../components/ModalPendaftaran';
describe('ModalPendaftaran', () => {
it('renders without problem', () => {
const ModalPendaftaran = ReactTestUtils.renderIntoDocument(
<ModalPendaftaran header="header" buttontTitle="buttonTitle" content="content"/>);
expect(ModalPendaftaran).to.exist;
const modalPendaftaran = ReactTestUtils.renderIntoDocument(
<ModalPendaftaran id={4} data={{key: 'value'}} buttonTitle="submit" />);
expect(modalPendaftaran).to.exist;
});
it('open without problem', () => {
const modalPendaftaran = ReactTestUtils.renderIntoDocument(
<ModalPendaftaran id={4} data={{ key: 'value' }} buttonTitle="submit" />);
const modal = ReactTestUtils.findRenderedDOMComponentWithTag(modalPendaftaran, 'Button');
ReactTestUtils.Simulate.click(modal);
});
});
\ No newline at end of file
});
/* eslint-disable no-unused-expressions */
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import Vacancy from '../../components/Vacancy';
describe('Vacancy', () => {
const response ={
close_time: '2019-03-28T05:55:42Z',
company: {
address: 'kebayoran baru',
id: 1,
logo: null,
name: 'tutup lapak',
},
created: '2017-03-28T07:05:47.128672Z',
description: 'Lorem ipsum dolbh.',
id: 3,
name: 'Software Engineer',
open_time: '2017-03-28T05:55:38Z',
updated: '2017-03-28T07:34:13.122093Z',
verified: true,
};
const response2 ={
close_time: '2019-03-28T05:55:42Z',
company: {
address: 'kebayoran baru',
id: 1,
logo: 'pictures',
name: 'tutup lapak',
},
created: '2017-03-28T07:05:47.128672Z',
description: 'Lorem ipsum dolbh.',
id: 3,
name: 'Software Engineer',
open_time: '2017-03-28T05:55:38Z',
updated: '2017-03-28T07:34:13.122093Z',
verified: true,
};
it('renders null picture without problem', () => {
const lowongan = ReactTestUtils.renderIntoDocument(
<Vacancy data={response} />);
expect(lowongan).to.exist;
});
it('renders with picture without problem', () => {
const lowongan = ReactTestUtils.renderIntoDocument(
<Vacancy data={response2} />);
expect(lowongan).to.exist;
});
});
......@@ -2,21 +2,41 @@
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import VacancyList from '../../components/VacancyList';
import Lowongan from '../../components/Lowongan';
import Server from '../../lib/Server';
describe('VacancyList', () => {
it('created without problem', () => {
const vacancyList = new VacancyList();
expect(vacancyList).to.be.an.instanceof(VacancyList);
});
const fetchMock = require('fetch-mock');
const response = [{
close_time: '2019-03-28T05:55:42Z',
company: {
address: 'kebayoran baru',
id: 1,
logo: null,
name: 'tutup lapak',
},
created: '2017-03-28T07:05:47.128672Z',
description: 'Lorem ipsum dolbh.',
id: 3,
name: 'Software Engineer',
open_time: '2017-03-28T05:55:38Z',
updated: '2017-03-28T07:34:13.122093Z',
verified: true,
}];
const response2 = { hello: 'not-world' };
it('renders without problem', () => {
const vacancyList = ReactTestUtils.renderIntoDocument(
<VacancyList vacancies={[{ key: 'value' }, { key2: 'value2' }]} />);
<VacancyList url="test" />);
expect(vacancyList).to.exist;
});
React.Children.forEach(vacancyList.props.children, (child) => {
expect(child).to.be.an.instanceof(Lowongan);
it('success calling API', () => {
fetchMock.get('*', response);
const vacancyList = ReactTestUtils.renderIntoDocument(
<VacancyList url="test" />);
vacancyList.state.vacancies = response;
expect(JSON.stringify(vacancyList.state.vacancies)).to.equal(JSON.stringify(response));
expect(vacancyList.generateVacancies()).to.exist;
});
});
});
......@@ -24,7 +24,22 @@ import Server from './../../lib/Server';
describe('Server get test', () => {
const fetchMock = require('fetch-mock');
const response = { hello: 'world' };
const response = {
close_time: '2019-03-28T05:55:42Z',
company: {
address: 'kebayoran baru',
id: 1,
logo: null,
name: 'tutup lapak',
},
created: '2017-03-28T07:05:47.128672Z',
description: 'Lorem ipsum dolbh.',
id: 3,
name: 'Software Engineer',
open_time: '2017-03-28T05:55:38Z',
updated: '2017-03-28T07:34:13.122093Z',
verified: true,
};
it('Check Server get right response', () => {
fetchMock.get('*', response);
......@@ -85,6 +100,6 @@ describe('Server get test', () => {
it('Check getcookie method', () => {
document.cookie = ';test=test;';
expect(Server.getCookie('test')).to.not.exist;
expect(Server.getCookie('test')).to.exist;
});
});
import React from 'react';
import { Form, Input, Button, Message, Image } from 'semantic-ui-react';
import { Form, Input, Button, Message, Image, Card } from 'semantic-ui-react';
import { browserHistory } from 'react-router';
import Server from '../lib/Server';
import Storage from '../lib/Storage';
......@@ -48,7 +48,10 @@ export default class LoginForm extends React.Component {
}
render = () => (
<div className="formLogin" >
<Form onSubmit={e => this.handleSubmit(e)} error={this.state.errorFlag}>
<div className="formHeader">
<Image src={`./assets/img/${this.props.imgSrc}`} size={this.props.imgSize} verticalAlign="middle" /> <span>{ this.props.header }</span>
......@@ -74,6 +77,9 @@ export default class LoginForm extends React.Component {
/>
</Form>
</div>
)
}
import React from 'react';
import { Button, Image as ImageComponent, Item, Rating } from 'semantic-ui-react'
import { Button, Image as ImageComponent, Item, Rating, Icon } from 'semantic-ui-react'
import ModalPendaftaran from './ModalPendaftaran';
......@@ -17,9 +17,7 @@ export default class Lowongan extends React.Component {
{image}
<Item.Content verticalAlign="middle">
<Item.Header>
{this.props.header}
</Item.Header>
<Item.Description>{this.props.content}</Item.Description>
<Item.Content>
......
import React from 'react';
import { Modal, Button, Icon } from 'semantic-ui-react';
import Server from '../lib/Server';
import Logger from '../lib/Logger';
export default class ModalAlert extends React.Component {
static propTypes = {
......@@ -25,9 +24,9 @@ export default class ModalAlert extends React.Component {
close = () => this.setState({ open: false });
handleOpen() {
Logger.log(this.state);
const requestData = { coverLetter: this.props.coverLetter };
Server.post(`/students/${this.props.id}/application`, requestData).then((data) => {
let studentId = Storage.post('user-data.student.id');
Server.post(`/students/${studentId}/application`, requestData).then((data) => {
this.setState({
header: 'Pendaftaran Berhasil',
content: this.successResponse + JSON.stringify(data),
......
......@@ -26,7 +26,7 @@ export default class ModalPendaftaran extends React.Component {
}
handleChange(event) {
// this.setState({ coverLetter: event.target.value });
this.setState({ coverLetter: event.target.value });
}
handleOpen() {
......@@ -39,7 +39,8 @@ export default class ModalPendaftaran extends React.Component {
render = () => (
<Modal
trigger={<Button onClick={this.handleOpen} floated='right'>{this.props.buttonTitle}</Button>}
trigger={<Button onClick={this.handleOpen} floated="right">{this.props.buttonTitle}</Button>}
closeIcon="close"
open={this.state.modalOpen}
onClose={this.handleClose}
......
......@@ -6,6 +6,10 @@ import Server from '../lib/Server';
import Storage from '../lib/Storage';
export default class TopMenu extends React.Component {
state = { activeItem: 'home' };
handleItemClick = (e, { name }) => this.setState({ activeItem: name });
constructor(props) {
super(props);
/* istanbul ignore next */
......@@ -20,16 +24,14 @@ export default class TopMenu extends React.Component {
};
render() {
const { activeItem } = this.state;
return (
<Menu color="blue" pointing secondary>
<Image as="a" size="small" src="/assets/img/logo.png" href="/" />
<Menu.Menu position="right">
<Menu.Item as={Link} to="/lowongan" name="home" onClick={this.handleItemClick} />
<Menu.Item as={Link} to="/profile" name="profil" onClick={this.handleItemClick} />
{Server.isLoggedIn() ?
<Menu.Item as={Link} onClick={this.logout} name="logout" /> :
<Menu.Item as={Link} to="/login" name="login" />
}
<Menu.Item as={Link} to="/lowongan" name="home" active={activeItem === 'home'} onClick={this.handleItemClick} />
<Menu.Item as={Link} to="/profile" name="profil" active={activeItem === 'profil'} onClick={this.handleItemClick} />
<Menu.Item as={Link} onClick={this.logout} name="logout" />
</Menu.Menu>
</Menu>
);
......
import React from 'react';
import { Button, Image as ImageComponent, Item, Rating } from 'semantic-ui-react'
import ModalPendaftaran from './ModalPendaftaran';
const defaultImage = "http://semantic-ui.com/images/wireframe/image.png";
export default class Lowongan extends React.Component {
static propTypes = {
data: React.PropTypes.object.isRequired,
};
render() {
return (
<Item >
<Item.Image size="small" src={this.props.data.company.logo ? this.props.data.company.logo: defaultImage} />
<Item.Content verticalAlign="middle">
<Item.Extra>
<h3>{ this.props.data.name }</h3>
<div className="bookmark">
<Rating icon='star' size='massive' defaultRating={0} maxRating={1} />
</div>
<h4>{ this.props.data.company.name }</h4>
<h5>{ this.props.data.company.address }</h5>
<ModalPendaftaran
id={this.props.data.id} data={{ header: this.props.data.name,
description: this.props.data.description }} buttonTitle="Daftar" />
</Item.Extra>
</Item.Content>
</Item>
);
}
}
\ No newline at end of file
import React from 'react';
import { Item } from 'semantic-ui-react';
import Lowongan from './Lowongan';
import Lowongan from './Vacancy';
import Server from '../lib/Server';
export default class VacancyList extends React.Component {
......@@ -11,10 +11,9 @@ export default class VacancyList extends React.Component {
constructor(props) {
super(props);
/* istanbul ignore next */
this.state = { vacancies: [] };
console.log(Server.isLoggedIn());
Server.get(this.props.url).then((data) => {
console.log(data);
Server.get(this.props.url, false).then((data) => {
this.setState({ vacancies: data });
}, () => {
});
......@@ -31,9 +30,7 @@ export default class VacancyList extends React.Component {
render = () => {
return (
<Item.Group relaxed>
{/*<Item.Group relaxed>*/}
{ this.generateVacancies() }
{/*</Item.Group>*/}
</Item.Group>
);
}
......
......@@ -44,7 +44,8 @@ export default class Server {
if (response.status === 204) {
return response;
}
return response;
const contentType = response.headers.get("content-type");
return contentType && contentType.indexOf("application/json") !== -1 ? response.json() : response.text();
});
/* istanbul ignore next */
......
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-03-28 12:04
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('core', '0004_auto_20170328_1417'),
]
operations = [
migrations.CreateModel(
name='Application',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('cover_letter', models.TextField(blank=True, null=True)),
('allow_transcript', models.BooleanField(default=True)),
],
),
migrations.RemoveField(
model_name='student',
name='applied_vacancies',
),
migrations.AddField(
model_name='student',
name='applied_vacancies',
field=models.ManyToManyField(blank=True, related_name='applied_vacancies', through='core.Application', to='core.Vacancy'),
),
migrations.AddField(
model_name='application',
name='student',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Student'),
),
migrations.AddField(
model_name='application',
name='vacancy',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='core.Vacancy'),
),
]
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment