Fakultas Ilmu Komputer UI

Commit 72109fb4 authored by Puti Larasati's avatar Puti Larasati

Merge branch 'develop' into 'master'

Develop

See merge request !26
parents 796f7798 6c2791ac
......@@ -11,6 +11,7 @@
"func-names": ["error", "never"],
"react/prefer-stateless-function": [0, { "ignorePureComponents": true }],
"react/forbid-prop-types": [0],
"react/no-multi-comp": [0, { "ignoreStateless": 1 }],
"import/extensions": ["off", "never"],
"import/no-unresolved": 0,
"no-underscore-dangle" : 0,
......
......@@ -12,3 +12,4 @@ test/*
.coverage
.tmp/
npm-debug.log
debug.log
......@@ -10,6 +10,8 @@ test:
- export CHROME_BIN=/usr/bin/google-chrome
- curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
- sudo apt-get install -y nodejs
- sudo apt-get install -y build-essential
- npm install npm -g
- npm install
- npm run build-production
- service postgresql start
......
# How To Build
# How To Deploy to Production Server
## Deployment
* Clone this repository
* Install docker, you can do this manually or using command `bash /provision/setup-docker.sh`
* Deploy using command `bash /provision/run-docker.sh DOCKERNAME APP_PORT SSH_PORT` for example `bash /provision/run-docker.sh staging 8000 8022`
* Profit :)
## HTTPS Server and Domain Name
* Add your domain name on the `ALLOWED_HOSTS` field on `kape/settings.py`
* Add these server blocks on yout NGINX setting (change `DOMAIN_NAME` and `APP_PORT`)
```
server {
listen 80;
listen [::]:80;
server_name your.DOMAIN_NAME.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
include snippets/ssl-your.DOMAIN_NAME.sslconfiguration.conf;
server_name your.DOMAIN_NAME.com;
location / {
proxy_pass http://localhost:APP_PORT;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
## Git push on the production server
* You can push directly to production git if SSH port is not blocked
* In the repo directory, run `git remote add production ssh://kape@DOMAIN_NAME:SSH_PORT/home/kape.git`
* To push to production server, run `git push production master` (default docker ssh password : yukcarikape)
# How To Build for Development Environment
## Requirements
* Node + Npm (https://nodejs.org/dist/v6.9.5/node-v6.9.5-x64.msi)
* Python + Pip (https://www.python.org/ftp/python/3.6.0/python-3.6.0-embed-amd64.zip and https://pip.pypa.io/en/stable/installing/)
* postgreSQL
* NodeJS + Npm Package Manager
* Python + Pip Package Manager
* PostgreSQL
## Installation
......@@ -15,20 +54,18 @@
* `psql` insert these queries:
* `create user kape password 'kape';` to create user.
* `create database kape;` to create database.
* if you want to create another database user, please update the setting file `kape/settings.py`
* `python manage.py migrate` To migrate all the database
## Run Development Mode App
* `npm run webpack`
* on a different terminal, run `python manage.py runserver`
* `npm run webpack` to run webpack server. (if you don't want live update run `npm run build`, if you want the uglified+zipped+production ready version run `npm run build-production`)
* on a different terminal window, run `python manage.py runserver` to run API server
### Now go to localhost:8000 and you'll see the App running!
# Deployment
* Clone this repository
* Install docker, you can do this manually or using `bash /provision/setup-docker.sh`
* Deploy using `bash /provision/run-docker.sh DOCKERNAME APP_PORT SSH_PORT` for example `bash /provision/run-docker.sh staging 8000 8022`
* Profit
## Run Unit Test
This project uses [Django Webpack Loader](https://github.com/owais/django-webpack-loader).
* Frontend test, run `npm run webpack`
* Backend test, run `python manage.py test`
body{
padding: 0;
height: auto;
width: auto;
background-color: black;
}
.center{
text-align: center;
}
img {
max-width: 100%;
height: auto;
}
* {
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
body {
font: 300 14px/1.4 'Helvetica Neue', Helvetica, Arial, sans-serif;
margin: 0;
padding: 0;
.ui.inverted.segment.header{
background-color: #EEEEEE;
color:black;
}
.halamanLowongan{
.item-list {
word-wrap: break-word;
width: 100%;
}
.ui.card.register{
background-color: #EEEEEE;
}
.create-lowongan{
padding-bottom: 7%;
padding-left:15%;
padding-right:15%;
}
.ui.segment.form-segment{
padding-bottom: 50px;
}
.tabs {
margin-top: 100px;
margin-left: 150px;
margin-right: 150px;
background: #fff;
border: 1px solid #e5e5e5;
border-radius: 3px;
margin-bottom: 30px;
margin: 0 7%;
display: block;
}
.tabs__labels {
margin: 0;
......@@ -59,29 +66,23 @@ body {
}
.halamanLogin{
background-image: url("../img/bw.jpg");
background-size: cover;
background-position: center;
background-attachment: fixed;
height: 700px;
background: url("../img/background.png")no-repeat center center fixed;
-webkit-background-size: cover;
-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{
margin: 0 auto;
margin-top: 100px;
width: 430px;
border: 2px solid transparent;
border-radius: 12px;
border-color:#e8e8e8;
padding: 20px;
background-color: white;
/*margin: auto;*/
/*width: 430px;*/
}
.registerModal{
......@@ -95,7 +96,6 @@ padding: 20px;
.formLogin img{
height: 70px !important;
margin:5px;
margin-bottom:30px;
}
.formLogin span{
......@@ -115,37 +115,26 @@ font-size: 32px;
}
.daftar{
float: right;
margin-top:10px;
}
.coverLetter{
margin-top:30px;
}
.linkCV{
float: right;
margin-top: 30px;
margin-bottom: 10px;
margin-top:10px;
}
.registerForm{
margin: 0 auto;
padding:50px;
/*padding:50px;*/
background-color: #3B8686;
}
item{
h3{
color:black;
}
textarea{
width: 800px !important;
height: 160px !important;
h4{
color: black;
}
h5{
color: black;
}
.note {
color: gray;
......@@ -170,7 +159,134 @@ card .formRegis{
margin-top: 100px;
}
itemLowongan{
.itemLowongan{
color: black;
}
.ui.pointing.secondary.menu{
background-color: #ffffff;
margin-bottom: 10px;
margin-top: 0px;
}
.extra.extra-company h3{
padding-top:10px;
}
.extra.extra-company h2{
color: black;
}
.biodata h5{
line-height: 30%;
}
.biodataCompany h4{
color: grey;
}
.buttonProfile{
margin-top:30px;
}
.ui.segment.profile-form{
padding-bottom: 37px;
margin-top:4%;
}
.profilePage {
margin-bottom: 40px;
margin-left: 5%;
margin-right: 5%;
}
#react-app{
position: relative; /* needed for footer positioning*/
/*height: 100% !important; !* real browsers *!*/
min-height: 100%; /* real browsers */
background-color: #EEEEEE;
}
.content{
padding-bottom: 5%;
}
.mainContent{
padding-bottom: 40px;
}
.footer{
background-color: #031634;
position: absolute;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 30px;
padding: 6px;
}
.footer h5{
color:white;
}
.profilePage{
margin-left:5%;
margin-right:5%;
margin-bottom: auto;
}
.ui.segment.segmentProfileCompany{
margin-left: 10%;
margin-right: 10%;
padding: 5%;
}
.ui.segment.profileFormCompany{
margin-top:4%;
margin-left: 10%;
margin-right: 10%;
padding-bottom:3%;
}
.companyProfile{
padding-bottom:5%;
}
.ui.segment.vacancyListCompany{
margin-left: 10%;
margin-right: 10%;
}
.ui.segment.paginationCompany{
margin: 2% 7%;
}
.admin-bar{
margin: 0;
padding: 10px;
width: 100%;
text-align: right;
background-color: #304D8A;
color: white;
}
.dropdownApplicant{
margin-left:7%;
margin-top:2%;
margin-bottom: 0;
}
.administrationButtons {
margin-left:7%;
margin-top:2%;
margin-bottom: 2%;
}
.ui.segment.transkrip{
margin-left:7%;
margin-right:7%;
}
.ui.segment.kop {
line-height: 5px;
}
\ No newline at end of file
import React from 'react';
import Tabs from './components/Tabs';
import Pane from './components/Pane';
import AdminVacancy from './components/AdminVacancy';
import { Item } from 'semantic-ui-react';
export default class AdminVacancyPage extends React.Component {
render() {
return (
<Tabs selected={0}>
<Pane label="Lowongan Belum Terferivikasi" >
<Item.Group>
<AdminVacancy />
</Item.Group>
</Pane>
<Pane label=" Semua Lamaran" />
</Tabs>
);
}
}
import React from 'react';
import { Dropdown } from 'semantic-ui-react';
import Tabs from './components/Tabs';
import ApplicantList from './components/ApplicantList';
import Applicant from './components/Applicant';
import Pagination from './components/Pagination';
import Server from './lib/Server';
export default class ApplicantPage extends React.Component {
static propTypes = {
user: React.PropTypes.object.isRequired,
};
constructor(props) {
super(props);
/* istanbul ignore next */
this.state = {
email: '',
password: '',
errorFlag: false,
company: { id: 1 },
urls: [],
selected: `/companies/${this.props.user.data.company.id}/applications/`,
refresh: 0,
};
this.getVacancyList = this.getVacancyList.bind(this);
this.handleChange = this.handleChange.bind(this);
this.getVacancyList();
}
getVacancyList= () => Server.get(`/companies/${this.props.user.data.company.id}/vacancies/`, false).then((data) => {
const results = data.results;
const names = ['Semua Lowongan'];
const urls = [{
key: 0,
value: `/companies/${this.props.user.data.company.id}/applications/`,
text: 'Semua Lowongan',
}];
results.map((vacancy) => {
names.push(vacancy.name);
const url = `/companies/${this.props.user.data.company.id}/applications/${vacancy.id}/by_vacancy/`;
const info = {
key: vacancy.id,
value: url,
text: vacancy.name,
};
urls.push(info);
return urls;
});
this.setState({ urls });
}, error => error.then((r) => {
this.modalAlert.open('Gagal mendapatkan daftar lowongan', r.detail);
}));
handleChange = (e, data) => {
this.setState({ selected: data.value, refresh: this.state.refresh + 5 });
};
render() {
const company = this.props.user.data.company;
return (
<div>
<div className="dropdownApplicant">
<Dropdown placeholder="Semua Lowongan" search selection options={this.state.urls} onChange={this.handleChange} />
</div>
<Tabs selected={0}>
<Pagination
key={1 + this.state.refresh}
url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.NEW}`}
label="Lamaran Baru"
child={
<ApplicantList companyId={company.id} status={Applicant.APPLICATION_STATUS.NEW} />
}
/>
<Pagination
key={2 + this.state.refresh}
url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.READ}`}
label="Lamaran Dibaca"
child={
<ApplicantList companyId={company.id} status={Applicant.APPLICATION_STATUS.READ} />
}
/>
<Pagination
key={3 + this.state.refresh}
url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.BOOKMARKED}`}
label="Lamaran Ditandai"
child={
<ApplicantList
companyId={company.id}
status={Applicant.APPLICATION_STATUS.BOOKMARKED}
/>
}
/>
<Pagination
key={4 + this.state.refresh}
url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.ACCEPTED}`}
label="Lamaran Diterima"
child={
<ApplicantList
companyId={company.id}
status={Applicant.APPLICATION_STATUS.ACCEPTED}
/>
}
/>
<Pagination
key={5 + this.state.refresh}
url={`${this.state.selected}?status=${Applicant.APPLICATION_STATUS.REJECTED}`}
label="Lamaran Ditolak"
child={
<ApplicantList
companyId={company.id}
status={Applicant.APPLICATION_STATUS.REJECTED}
/>
}
/>
</Tabs>
</div>
);
}
}
import React from 'react';
import { Button } from 'semantic-ui-react';
import Tabs from './components/Tabs';
import CompanyList from './components/CompanyList';
import Company from './components/Company';
import Pagination from './components/Pagination';
export default class CompanyPage extends React.Component {
static propTypes = {
user: React.PropTypes.object.isRequired,
};
handleClick = () => window.open('/admin/');
render() {
return (
<div>
<div className="administrationButtons">
<Button onClick={this.handleClick} icon="dashboard" labelPosition="left" color="facebook" content="Buka Menu Administrasi" />
</div>
<Tabs selected={0}>
<Pagination
key={1}
url={`/companies/?status=${Company.COMPANY_STATUS.NEW}`}
label="Belum Diverifikasi"
child={
<CompanyList status={Company.COMPANY_STATUS.NEW} />
}
/>
<Pagination
key={2}
url={`/companies/?status=${Company.COMPANY_STATUS.VERIFIED}`}
label="Terverifikasi"
child={
<CompanyList status={Company.COMPANY_STATUS.VERIFIED} />
}
/>
<Pagination
key={3}
url={`/companies/?status=${Company.COMPANY_STATUS.UNVERIFIED}`}
label="Ditolak"
child={
<CompanyList status={Company.COMPANY_STATUS.UNVERIFIED} />
}
/>
<Pagination
key={4}
url={'/companies/'}
label="Semua Perusahaan"
child={
<CompanyList status={Company.COMPANY_STATUS.ALL} />
}
/>
</Tabs>
</div>
);
}
}