Fakultas Ilmu Komputer UI

Commit 8a177f53 authored by M. Reza Qorib's avatar M. Reza Qorib
Browse files

So much things done. Create SupervisorPage, refactor TopMenu and Dashboard,...

So much things done. Create SupervisorPage, refactor TopMenu and Dashboard, add and refactor many testing files.
parent 44903104
import React from 'react';
import TopMenu from './components/TopMenu';
import Server from './lib/Server';
const defaultPicture = 'http://semantic-ui.com/images/avatar/small/elliot.jpg';
import Footer from './components/Footer';
export default class Dashboard extends React.Component {
static propTypes = {
......@@ -16,43 +13,9 @@ export default class Dashboard extends React.Component {
]).isRequired,
};
static getInfo(user) {
const adminRole = {
name: 'admin',
user: {
email: '',
},
photo: null,
};
const role = user.role;
if (role === 'student') {
return user.data.student;
} else if (role === 'company') {
return user.data.company;
}
return adminRole;
}
constructor(props) {
super(props);
/* istanbul ignore next */
const data = Dashboard.getInfo(this.props.user);
this.state = {
id: data.id,
name: data.name,
email: data.user.email,
photo: data.photo,
};
}
render = () => (
<div>
<TopMenu
name={this.state.name} email={this.state.email}
photo={this.state.photo ? this.state.photo : defaultPicture}
/>
<TopMenu user={this.props.user} />
{this.props.children}
</div>
)
......
......@@ -157,7 +157,7 @@ export default class ProfilePage extends React.Component {
<Grid.Column width={7}>
<Header as="h2" icon textAlign="center">
<br />
<Image src={this.state.photo ? this.state.photo : defaultPicture} size="medium" />
<Image src={this.state.photo || defaultPicture} size="medium" />
</Header>
</Grid.Column>
......@@ -219,10 +219,7 @@ export default class ProfilePage extends React.Component {
<Container textAlign="center">
<div className="button-profile">
<a href={this.state.resume ? this.state.resume : '#'} ><Button primary size="small">Resume</Button></a>
{ this.state.show_transcript &&
<Button primary size="small">Transkrip</Button>
}
<a href={this.state.resume || '#'} ><Button primary size="small">Resume</Button></a>
</div>
<div>
<h4> Bagikan Transkrip : { this.state.bagikanTranskrip }</h4>
......
import React from 'react';
import { Header, Icon, Grid } from 'semantic-ui-react';
import Pagination from './components/Pagination';
import Server from './lib/Server';
import ApplicationList from './components/ApplicationList';
const cols = [
{ key: 'StudentName', label: 'Nama' },
{ key: 'StudentID', label: 'NPM' },
{ key: 'Perusahaan', label: 'Perusahaan' },
{ key: 'Posisi', label: 'Posisi' },
{ key: 'Status', label: 'Status' },
];
export default class SupervisorPage extends React.Component {
constructor(props) {
super(props);
/* istanbul ignore next */
this.state = { list: [] };
}
componentDidMount() {
this.UserList();
}
UserList() {
Server.get('/student-applications/', false).then((data) => {
this.setState({ list: data.results });
});
}
render = () => {
return (
<Grid container columns="eleven" doubling>
<Grid.Row>
<br />
</Grid.Row>
<Grid.Row>
<Header as="h2">
<Icon name="list" />
Daftar Mahasiswa
</Header>
</Grid.Row>
<Grid.Row>
<div id="layout-content" className="layout-content-wrapper">
<Pagination url={'/student-applications/'} child={<ApplicationList cols={cols} />} />
</div>
</Grid.Row>
</Grid>
);
}
}
......@@ -3,7 +3,7 @@ import Tabs from './components/Tabs';
import Pane from './components/Pane';
import VacancyList from './components/VacancyList';
import Pagination from './components/Pagination';
import Applicants from './components/SupervisorPage';
import Applicants from './SupervisorPage';
export default class VacancyPage extends React.Component {
......@@ -47,7 +47,6 @@ export default class VacancyPage extends React.Component {
/>
}
/>
<Applicants />
</Pane>
<Pane label="Lamaran saya" >
<Pagination
......
......@@ -90,7 +90,28 @@ describe('Dashboard', () => {
email: '',
is_staff: false,
company: null,
supervisor: null,
supervisor: {
id: 3,
user: {
url: 'http://localhost:8000/api/users/9/',
username: 'muhammad.reza42',
email: 'muhammad.reza42@ui.ac.id',
is_staff: false,
},
name: 'Muhammad R.',
created: '2017-03-28T13:33:46.147241Z',
updated: '2017-03-28T13:33:46.148248Z',
npm: 1406543593,
resume: null,
phone_number: null,
bookmarked_vacancies: [
3,
],
applied_vacancies: [
3,
1,
],
},
student: null,
},
};
......
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import fetchMock from 'fetch-mock';
import SupervisorPage from '../SupervisorPage';
describe('SupervisorPage', () => {
const data = {
count: 5,
next: null,
previous: null,
results: [
{
company_name: 'Tutuplapak',
name: 'Joshua Casey Darian Gunawan',
npm: 1406622616,
vacancy_name: 'Software Engineer',
status: 'accepted',
},
{
company_name: 'Tutuplapak',
name: 'Muhammad Reza Qorib',
npm: 1406543593,
vacancy_name: 'Software Engineer',
status: 'accepted',
},
{
company_name: 'Tutuplapak',
name: 'Muhammad Reza Qorib',
npm: 1406543593,
vacancy_name: 'Kepala Sekolah',
status: 'read',
},
{
company_name: 'company1',
name: 'Farhan Farasdak',
npm: 1406572321,
vacancy_name: 'Data Scientist',
status: 'new',
},
{
company_name: 'company1',
name: 'student2',
npm: 1406527513,
vacancy_name: 'Data Scientist',
status: 'new',
},
],
};
fetchMock.get('*', data);
it('renders for admin without problem', () => {
const supervisorPage = ReactTestUtils.renderIntoDocument(
<SupervisorPage />);
expect(supervisorPage).to.exist;
fetchMock.restore();
});
});
import React from 'react';
import ReactTestUtils from 'react-addons-test-utils';
import Footer from '../../components/Footer';
describe('Footer', () => {
it('renders without problem', () => {
const footer = ReactTestUtils.renderIntoDocument(
<Footer params={{ id: 1 }} />);
expect(footer).to.exist;
});
});
......@@ -119,7 +119,28 @@ describe('TopMenu', () => {
email: '',
is_staff: false,
company: null,
supervisor: null,
supervisor: {
id: 3,
user: {
url: 'http://localhost:8000/api/users/9/',
username: 'muhammad.reza42',
email: 'muhammad.reza42@ui.ac.id',
is_staff: false,
},
name: 'Muhammad R.',
created: '2017-03-28T13:33:46.147241Z',
updated: '2017-03-28T13:33:46.148248Z',
npm: 1406543593,
resume: null,
phone_number: null,
bookmarked_vacancies: [
3,
],
applied_vacancies: [
3,
1,
],
},
student: null,
},
};
......
......@@ -35,7 +35,7 @@ describe('VacancyList', () => {
};
const studentUser = {
role: 'company',
role: 'student',
data: {
url: 'http://localhost:8001/api/users/8/',
username: 'Tutuplapak',
......@@ -69,6 +69,8 @@ describe('VacancyList', () => {
1,
],
},
company: null,
supervisor: null,
},
};
......@@ -215,6 +217,38 @@ describe('VacancyList', () => {
},
];
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: 1,
name: 'Software Engineer',
open_time: '2017-03-28T05:55:38Z',
updated: '2017-03-28T07:34:13.122093Z',
verified: true,
}, {
close_time: '2019-03-28T05:55:42Z',
company: {
address: 'kebayoran baru',
id: 2,
logo: null,
name: 'tutup lapak',
},
created: '2017-03-28T07:05:47.128672Z',
description: 'Lorem ipsum dolbh.',
id: 2,
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: {
......@@ -235,96 +269,45 @@ describe('VacancyList', () => {
it('renders without problem', () => {
const vacancyList = ReactTestUtils.renderIntoDocument(
<VacancyList items={newResponse} userId={1} user={studentUser} />);
vacancyList.generateVacancies();
expect(vacancyList).to.exist;
});
it('renders without problem for company', () => {
const vacancyList = ReactTestUtils.renderIntoDocument(
<VacancyList items={newResponse} userId={1} user={companyUser} />);
vacancyList.generateVacancies();
vacancyList.state.vacancies = newResponse;
expect(vacancyList.generateVacancies()).to.exist;
});
// it('renders with problem for company', () => {
// const vacancyList = ReactTestUtils.renderIntoDocument(
// <VacancyList type="company" userId={1} url="test" />);
// vacancyList.state.vacancies = response;
// expect(vacancyList.generateVacancies()).to.exist;
// });
//
// it('update bookmarks without problem', () => {
// const vacancyList = ReactTestUtils.renderIntoDocument(
// <VacancyList userId={1} url="test" />);
// vacancyList.state.appliedList = [{ id: 1 }, { id: 3 }];
// vacancyList.updateStatusList().then(() => {
// expect(JSON.stringify(vacancyList.state.bookmarkList)).to.be.defined;
// });
// });
//
// it('check applied vacancies without problem', () => {
// const vacancyList = ReactTestUtils.renderIntoDocument(
// <VacancyList userId={1} url="test" />);
// vacancyList.updateStatusList().then(() => {
// expect(JSON.stringify(vacancyList.state.bookmarkList)).to.be.defined;
// });
// });
//
// it('renders marked bookmarked vacancies without problem', (done) => {
// const vacancyList = ReactTestUtils.renderIntoDocument(
// <VacancyList userId={1} url="test" />);
// vacancyList.state.vacancies = response;
// vacancyList.state.bookmarkList = [{ id: 5 }, { id: 3 }, { id: 1 }];
// vacancyList.updateStatusList().then(() => {
// expect(vacancyList.generateVacancies()).to.exist;
// done();
// }, () => done());
// });
//
// it('renders not marked vacancies without problem', () => {
// fetchMock.get('*', response);
// const vacancyList = ReactTestUtils.renderIntoDocument(
// <VacancyList userId={1} url="test" />);
// vacancyList.state.vacancies = response;
// vacancyList.state.bookmarkList = [{ id: 6 }, { id: 4 }, { id: 2 }];
// expect(vacancyList.generateVacancies()).to.exist;
// fetchMock.restore();
// });
//
// it('success calling API', () => {
// fetchMock.get('*', response);
// const vacancyList = ReactTestUtils.renderIntoDocument(
// <VacancyList userId={1} url="test" />);
// vacancyList.state.vacancies = response;
// expect(JSON.stringify(vacancyList.state.vacancies)).to.equal(JSON.stringify(response));
// fetchMock.restore();
// });
//
it('success delete vacancy', () => {
fetchMock.restore();
fetchMock.delete('*', response2);
fetchMock.get('*', newResponse);
const vacancyList = ReactTestUtils.renderIntoDocument(
<VacancyList userId={1} url="test" deleteCallback={() => {}} user={companyUser} />);
<VacancyList items={newResponse} userId={1} deleteCallback={() => {}} user={companyUser} />);
vacancyList.state.vacancies = newResponse;
vacancyList.deleteVacancy(1).then(() => {
expect(JSON.stringify(vacancyList.state.vacancies)).to.equal(JSON.stringify(response));
expect(JSON.stringify(vacancyList.state.vacancies)).to.equal(JSON.stringify(newResponse));
fetchMock.restore();
}, () => {
fetchMock.restore();
});
});
it('fails delete vacancy', () => {
it('fails delete vacancy', (done) => {
fetchMock.restore();
fetchMock.delete('*', 404);
const vacancyList = ReactTestUtils.renderIntoDocument(
<VacancyList userId={1} items={newResponse} user={companyUser} deleteCallback={() => {}} />,
);
vacancyList.state.vacancies = newResponse;
vacancyList.state.vacancies = response;
vacancyList.deleteVacancy(1).then(() => {
fetchMock.restore();
done();
}, () => {
expect(JSON.stringify(vacancyList.state.vacancies)).to.equal(JSON.stringify(newResponse));
expect(JSON.stringify(vacancyList.state.vacancies)).to.equal(JSON.stringify(response));
fetchMock.restore();
done();
});
......
import React from 'react';
import { Table } from 'semantic-ui-react';
export default class Tables extends React.Component {
export default class ApplicationList extends React.Component {
static propTypes = {
cols: React.PropTypes.any.isRequired,
data: React.PropTypes.any.isRequired,
items: React.PropTypes.any,
};
static defaultProps = {
items: [],
};
generateHeaders() {
const cols2 = this.props.cols; // [{key, label}]
// generate our header (th) cell components
return cols2.map(colData => <Table.HeaderCell singleLine key={colData.key}> {colData.label} </Table.HeaderCell>
, error => error.then(() => ('Gagal mendapatkan informasi data')),
);
return cols2.map(colData =>
<Table.HeaderCell singleLine key={colData.key}> {colData.label} </Table.HeaderCell>
);
}
generateRows() {
const cols3 = this.props.cols; // [{key, label}]
const data2 = this.props.data;
return data2.map((item) => {
// handle the column data within each row
const cells = cols3.map(colData =>
// colData.key might be "firstName"
<Table.Cell> {item[colData.key]} </Table.Cell>);
return <Table.Row key={item.id}> {cells} </Table.Row>;
});
return this.props.items.map(item =>
(
<Table.Row key={`${item.npm}_${item.company}_${item.position}_${item.status}_row`}>
<Table.Cell key={`${item.name}_name`}> {item.name} </Table.Cell>
<Table.Cell key={`${item.name}_npm`}> {item.npm} </Table.Cell>
<Table.Cell key={`${item.name}_company`}>
{item.company_name}
</Table.Cell>
<Table.Cell key={`${item.name}_position`}>
{item.vacancy_name}
</Table.Cell>
<Table.Cell key={`${item.name}_status`}>
{item.status}
</Table.Cell>
</Table.Row>
)
);
}
render() {
......
import React from 'react';
import { Header, Icon } from 'semantic-ui-react';
import Tables from './Tables';
import Server from '../lib/Server';
const cols = [
{ key: 'StudentName', label: 'Students Name' },
{ key: 'Perusahaan', label: 'Perusahaan' },
{ key: 'Posisi', label: 'Posisi' },
{ key: 'Status', label: 'Status' },
];
const data2 = [
{ id: 1, StudentName: 'John Doe', Perusahaan: 'Jalanloka', Posisi: 'Software Engineer', Status: 'Melamar' },
{ id: 2, StudentName: 'Clark Kent', Perusahaan: 'Tutuplapak', Posisi: 'Data Scientist', Status: 'Diterima' },
{ id: 3, StudentName: 'Rosamund Pike', Perusahaan: 'Tutuplapak', Posisi: 'System Analyst', Status: 'Diterima' },
{ id: 4, StudentName: 'Melissa Benoist', Perusahaan: 'Blabla', Posisi: 'Data Scientist', Status: 'Melamar' },
];
export default class Applicants extends React.Component {
constructor(props) {
super(props);
this.state = { list: [] };
}
componentDidMount() {
this.UserList();
}
UserList() {
Server.get('/student-applications/', false).then((data) => {
this.setState({ list: data.results });
});
}
render() {
const list = this.state.list.map((item, i) => <div>
<h1>{item.name}</h1>
<span>{item.npm}, {item.email}</span>
</div>);
return (
<div className="home-dosen">
<Header as="h2">
<Icon name="list" />
<Header.Content>
Daftar Mahasiswa
</Header.Content>
</Header>
<div id="layout-content" className="layout-content-wrapper">
<Tables cols={cols} data={data2} />
<div className="panel-list">{ list }</div>
</div>
</div>
);
}
}
......@@ -4,67 +4,96 @@ import { Link, browserHistory } from 'react-router';
import Server from '../lib/Server';
import Storage from '../lib/Storage';
const defaultImage = 'http://semantic-ui.com/images/avatar/small/elliot.jpg';
const defaultPicture = 'http://semantic-ui.com/images/avatar/small/elliot.jpg';
export default class TopMenu extends React.Component {
static getInfo(user) {
const adminRole = {
name: 'admin',
user: {
email: '',
},
photo: null,
};
const role = user.role;
if (role === 'student') {
return user.data.student;
} else if (role === 'company') {
return user.data.company;
} else if (role === 'supervisor') {
return user.data.supervisor;
}