first commit
This commit is contained in:
3
.eslintrc.json
Normal file
3
.eslintrc.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "next/core-web-vitals"
|
||||||
|
}
|
||||||
36
.gitignore
vendored
Normal file
36
.gitignore
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
.pnpm-debug.log*
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env*.local
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|
||||||
|
# googlekey.json
|
||||||
|
googlekey.json*
|
||||||
5
.vscode/extensions.json
vendored
Normal file
5
.vscode/extensions.json
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"mikestead.dotenv"
|
||||||
|
]
|
||||||
|
}
|
||||||
6
next.config.js
Normal file
6
next.config.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
/** @type {import('next').NextConfig} */
|
||||||
|
const nextConfig = {
|
||||||
|
reactStrictMode: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = nextConfig
|
||||||
6
nodemon.json
Normal file
6
nodemon.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"verbose": true,
|
||||||
|
"ignore": [ "node_modules", ".next" ],
|
||||||
|
"watch": ["server/**/*" , "index.js"],
|
||||||
|
"ext": "js json jsx ts tsx "
|
||||||
|
}
|
||||||
8562
package-lock.json
generated
Normal file
8562
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
29
package.json
Normal file
29
package.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "kurir_server",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "nodemon server/index.js",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start",
|
||||||
|
"lint": "next lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^16.0.0",
|
||||||
|
"express": "^4.17.3",
|
||||||
|
"express-form-data": "^2.0.17",
|
||||||
|
"googleapis": "^100.0.0",
|
||||||
|
"mongoose": "^6.2.11",
|
||||||
|
"next": "12.1.5",
|
||||||
|
"nodemon": "^2.0.15",
|
||||||
|
"react": "18.0.0",
|
||||||
|
"react-dom": "18.0.0",
|
||||||
|
"typescript": "^4.6.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "8.13.0",
|
||||||
|
"eslint-config-next": "12.1.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
7
pages/_app.js
Normal file
7
pages/_app.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import '../styles/globals.css'
|
||||||
|
|
||||||
|
function MyApp({ Component, pageProps }) {
|
||||||
|
return <Component {...pageProps} />
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MyApp
|
||||||
14
pages/index.js
Normal file
14
pages/index.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
function HomePage() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Home Page</h1>
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam
|
||||||
|
doloremque, quidem quisquam, quisquam quisquam quisquam quisquam
|
||||||
|
dignissimos.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HomePage;
|
||||||
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
4
public/vercel.svg
Normal file
4
public/vercel.svg
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
64
server/google/googleapi.js
Normal file
64
server/google/googleapi.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const { google } = require('googleapis');
|
||||||
|
|
||||||
|
// folder id
|
||||||
|
// const pengirim_folder_id = process.env.PENGIRIM_FOLDER_ID;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
uploadFile : async function uploadFile(fileName, filePath,folderId, message) {
|
||||||
|
try {
|
||||||
|
const auth = await new google.auth.GoogleAuth({
|
||||||
|
keyFile: './server/googlekey.json',
|
||||||
|
scopes: ['https://www.googleapis.com/auth/drive']
|
||||||
|
})
|
||||||
|
const drive = google.drive({ version: 'v3', auth });
|
||||||
|
const fileMetadata = {
|
||||||
|
name: fileName ,
|
||||||
|
parents: [folderId]
|
||||||
|
};
|
||||||
|
const media = {
|
||||||
|
mimeType: 'image/jpeg',
|
||||||
|
body: fs.createReadStream(filePath) // file path
|
||||||
|
};
|
||||||
|
|
||||||
|
// check if file exist
|
||||||
|
const file = await drive.files.list({
|
||||||
|
q: `name = '${fileName}' and '${folderId}' in parents`
|
||||||
|
});
|
||||||
|
|
||||||
|
let response
|
||||||
|
if (file.data.files.length > 0) {
|
||||||
|
// delete file
|
||||||
|
await drive.files.delete({
|
||||||
|
fileId: file.data.files[0].id
|
||||||
|
})
|
||||||
|
|
||||||
|
// upload file
|
||||||
|
response = await drive.files.create({
|
||||||
|
resource: fileMetadata,
|
||||||
|
media: media,
|
||||||
|
fields: 'id'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// upload file
|
||||||
|
response = await drive.files.create({
|
||||||
|
resource: fileMetadata,
|
||||||
|
media: media,
|
||||||
|
fields: 'id'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// console.log(filePath)
|
||||||
|
// console.log('ini berjalan '+fileName)
|
||||||
|
console.log(message)
|
||||||
|
return response.data.id;
|
||||||
|
} catch (error) {
|
||||||
|
console.log('ini error')
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
59
server/index.js
Normal file
59
server/index.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
const express = require('express')
|
||||||
|
const next = require('next')
|
||||||
|
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
const formData = require('express-form-data');
|
||||||
|
const cors = require('cors');
|
||||||
|
|
||||||
|
|
||||||
|
const port = parseInt(process.env.PORT) || 3001
|
||||||
|
const dev = process.env.NODE_ENV !== 'production'
|
||||||
|
const app = next({ dev })
|
||||||
|
const handle = app.getRequestHandler()
|
||||||
|
|
||||||
|
// require('../dotenv/config')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
app.prepare().then(() => {
|
||||||
|
const server = express()
|
||||||
|
|
||||||
|
// middleware
|
||||||
|
server.use(formData.parse());
|
||||||
|
server.use(express.json());
|
||||||
|
server.use(express.urlencoded({ extended: true }));
|
||||||
|
server.options('*', cors());
|
||||||
|
server.use(cors());
|
||||||
|
|
||||||
|
// import routes
|
||||||
|
const login_router = require('./routes/login_router');
|
||||||
|
|
||||||
|
// use routes
|
||||||
|
server.use('/login', login_router);
|
||||||
|
|
||||||
|
// connect to mongodb
|
||||||
|
mongoose.connect(process.env.DB_CONNECTION, { useNewUrlParser: true, useUnifiedTopology: true, family: 4})
|
||||||
|
let db = mongoose.connection;
|
||||||
|
db.on('error', console.error.bind(console, 'connection error:'));
|
||||||
|
db.once('open', function() {
|
||||||
|
console.log('connected to mongodb');
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
server.get('/api/shows', (req, res) => {
|
||||||
|
return res.end('Hello World')
|
||||||
|
});
|
||||||
|
|
||||||
|
server.all('*', (req, res) => {
|
||||||
|
return handle(req, res)
|
||||||
|
})
|
||||||
|
|
||||||
|
server.listen(port, (err) => {
|
||||||
|
if (err) throw err
|
||||||
|
|
||||||
|
// console.log(`ini dia ${process.env.DB_CONNECTION}`)
|
||||||
|
console.log(`> Ready on http://localhost:${port}`)
|
||||||
|
})
|
||||||
|
})
|
||||||
131
server/models/users_model.js
Normal file
131
server/models/users_model.js
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
// create mongoose schema
|
||||||
|
|
||||||
|
const mongoose = require('mongoose');
|
||||||
|
|
||||||
|
const pengirimSchema = new mongoose.Schema({
|
||||||
|
email: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
no_telp: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
length: [9, 13],
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
nama: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
alamat: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
photo_url: {
|
||||||
|
type: String,
|
||||||
|
// required: true
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
type: Date,
|
||||||
|
default: Date.now
|
||||||
|
},
|
||||||
|
updated_at: {
|
||||||
|
type: Date,
|
||||||
|
default: Date.now
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const kurirSchema = new mongoose.Schema({
|
||||||
|
nik : {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true,
|
||||||
|
length: [16, 16]
|
||||||
|
},
|
||||||
|
nama: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
email: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
no_telp: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
length: [9, 13],
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
alamat: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
no_kenderaan:{
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
status : {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
default: 'Evaluasi'
|
||||||
|
},
|
||||||
|
photo_url: {
|
||||||
|
type: String,
|
||||||
|
// required: true
|
||||||
|
},
|
||||||
|
kenderaan_url:{
|
||||||
|
type: String,
|
||||||
|
// required: true
|
||||||
|
},
|
||||||
|
ktp_url:{
|
||||||
|
type: String,
|
||||||
|
// required: true
|
||||||
|
},
|
||||||
|
ktp_holding_url:{
|
||||||
|
type: String,
|
||||||
|
// required: true
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
type: Date,
|
||||||
|
default: Date.now
|
||||||
|
},
|
||||||
|
updated_at: {
|
||||||
|
type: Date,
|
||||||
|
default: Date.now
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const loginUserSchema = new mongoose.Schema({
|
||||||
|
username: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
role: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
_idnya :{
|
||||||
|
type: mongoose.Schema.Types.ObjectId,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
type: Date,
|
||||||
|
default: Date.now
|
||||||
|
},
|
||||||
|
updated_at: {
|
||||||
|
type: Date,
|
||||||
|
default: Date.now
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const pengirimModel = mongoose.model('tb_pengirim', pengirimSchema, 'tb_pengirim');
|
||||||
|
const kurirModel = mongoose.model('tb_kurir', kurirSchema, 'tb_kurir');
|
||||||
|
const loginUserModel = mongoose.model('tb_login', loginUserSchema, 'tb_login');
|
||||||
|
|
||||||
|
module.exports = { pengirimModel, kurirModel, loginUserModel };
|
||||||
134
server/routes/login_router.js
Normal file
134
server/routes/login_router.js
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
//create express router
|
||||||
|
const express = require('express');
|
||||||
|
const router = express.Router();
|
||||||
|
|
||||||
|
const { pengirimModel, kurirModel, loginUserModel } = require('../models/users_model');
|
||||||
|
|
||||||
|
let googlenya = require('../google/googleapi.js');
|
||||||
|
const pengirim_folder_id = process.env.PENGIRIM_FOLDER_ID;
|
||||||
|
const kurir_folder_id = process.env.KURIR_FOLDER_ID;
|
||||||
|
const ktp_kurir_folder_id = process.env.KTP_KURIR_FOLDER_ID;
|
||||||
|
const ktp_holding_kurir_folder_id = process.env.KTP_HOLDING_KURIR_FOLDER_ID;
|
||||||
|
const kenderaan_kurir_folder_id = process.env.KENDERAAN_KURIR_FOLDER_ID;
|
||||||
|
|
||||||
|
// crate get
|
||||||
|
router.get('/', async (req, res) => {
|
||||||
|
|
||||||
|
console.log(await googlenya.uploadFile('hehehehhe'))
|
||||||
|
res.send('sini dia');
|
||||||
|
})
|
||||||
|
|
||||||
|
//create get for daftar
|
||||||
|
router.post('/daftar', async (req, res) => {
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
// console.log(req)
|
||||||
|
role = req.body.role;
|
||||||
|
let responsenya;
|
||||||
|
|
||||||
|
if (role == 'pengirim') {
|
||||||
|
// console.log("ini untuk pengirim");
|
||||||
|
// cek if req.body.no_telp is exist on database return true or false
|
||||||
|
let isExist = await pengirimModel.findOne({ no_telp: req.body.no_telp });
|
||||||
|
if (isExist) {
|
||||||
|
res.status(400).send({ message: 'No Telpon Sudah Terdaftar' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if req.body.email is exist on database return true or false
|
||||||
|
let isExistEmail = await pengirimModel.findOne({ email: req.body.email });
|
||||||
|
if (isExistEmail) {
|
||||||
|
res.status(400).send({ message: 'Email Sudah Terdaftar' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_pengirim = new pengirimModel(req.body);
|
||||||
|
// add photo_url to pengirim
|
||||||
|
// check if files.photo exist
|
||||||
|
if (req.files.photo) {
|
||||||
|
let id_photo = await googlenya.uploadFile(new_pengirim._id + ".jpg", req.files.photo.path, pengirim_folder_id ,"ini photo pengirim");
|
||||||
|
new_pengirim.photo_url = `https://drive.google.com/uc?export=view&id=${id_photo}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(new_pengirim);
|
||||||
|
// console.log(pengirim_folder_id)
|
||||||
|
|
||||||
|
await new_pengirim.save();
|
||||||
|
responsenya = new_pengirim;
|
||||||
|
} else if (role == 'kurir') {
|
||||||
|
// check if req.body.nik is exists
|
||||||
|
let isExist = await kurirModel.findOne({ nik: req.body.nik });
|
||||||
|
if (isExist) {
|
||||||
|
res.status(400).send({
|
||||||
|
status: false,
|
||||||
|
message: 'NIK Sudah Terdaftar'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if req.body.no_telp is exists
|
||||||
|
let isExist2 = await kurirModel.findOne({ no_telp: req.body.no_telp });
|
||||||
|
if (isExist2) {
|
||||||
|
res.status(400).send({
|
||||||
|
status: false,
|
||||||
|
message: 'No Telpon Sudah Terdaftar'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if req.body.email is exists
|
||||||
|
let isExist3 = await kurirModel.findOne({ email: req.body.email });
|
||||||
|
if (isExist3) {
|
||||||
|
res.status(400).send({
|
||||||
|
status: false,
|
||||||
|
message: 'Email Sudah Terdaftar'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if req.files.photo and req.files.ktp_photo and req.files.ktp_holding_photo and req.files.kenderaan_photo exist
|
||||||
|
if (!req.files.photo || !req.files.ktp_photo || !req.files.ktp_holding_photo || !req.files.kenderaan_photo) {
|
||||||
|
res.status(400).send({
|
||||||
|
status: false,
|
||||||
|
message: 'File tidak boleh kosong'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_kurir = new kurirModel(req.body);
|
||||||
|
|
||||||
|
// add photo_url to new_kurir
|
||||||
|
let id_photo = googlenya.uploadFile(new_kurir._id + ".jpg", req.files.photo.path, kurir_folder_id, "ini photo kurir");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// add ktp_url to new_kurir
|
||||||
|
let id_ktp = googlenya.uploadFile("ktp_"+new_kurir._id + ".jpg", req.files.ktp_photo.path, ktp_kurir_folder_id, "ini ktp kurir");
|
||||||
|
|
||||||
|
|
||||||
|
// add ktp_holding_url to new_kurir
|
||||||
|
let id_ktp_holding = googlenya.uploadFile("ktp_holding_"+new_kurir._id + ".jpg", req.files.ktp_holding_photo.path, ktp_holding_kurir_folder_id, "ini ktp holding kurir");
|
||||||
|
|
||||||
|
|
||||||
|
// add kenderaan_url to kurir
|
||||||
|
let id_kenderaan = googlenya.uploadFile("kenderaan_"+new_kurir._id + ".jpg", req.files.kenderaan_photo.path, kenderaan_kurir_folder_id, "ini kenderaan kurir");
|
||||||
|
|
||||||
|
new_kurir.photo_url = `https://drive.google.com/uc?export=view&id=${await id_photo}`
|
||||||
|
new_kurir.ktp_url = `https://drive.google.com/uc?export=view&id=${await id_ktp}`
|
||||||
|
new_kurir.ktp_holding_url = `https://drive.google.com/uc?export=view&id=${await id_ktp_holding}`
|
||||||
|
new_kurir.kenderaan_url = `https://drive.google.com/uc?export=view&id=${await id_kenderaan}`
|
||||||
|
|
||||||
|
console.log(new_kurir)
|
||||||
|
await new_kurir.save();
|
||||||
|
responsenya = new_kurir;
|
||||||
|
}
|
||||||
|
res.send({ status: true, data: responsenya });
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).send({ status: false, data: error });
|
||||||
|
}
|
||||||
|
|
||||||
|
// res.send('sini untuk daftar');
|
||||||
|
})
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
16
styles/globals.css
Normal file
16
styles/globals.css
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
html,
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||||
|
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user