diff --git a/.env b/.env new file mode 100644 index 0000000000000000000000000000000000000000..aa2e3a98d266a53b6b4f1c54569ecf04c2b75ba4 --- /dev/null +++ b/.env @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +# See https://docs.docker.com/compose/environment-variables/#the-env-file + +MYSQL_HOST=mysql +MYSQL_PORT=8989 +MYSQL_DATABASE=motaraido +MYSQL_ROOT_USER=root +MYSQL_ROOT_PASSWORD=root +MYSQL_USER=datafreaks +MYSQL_PASSWORD=datafreaks \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..190b629cdda006348f5415b87822962d1221ff13 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.DS_Store +Thumbs.db +npm-debug.log +/data +/bower_components +/node_modules +/vendor \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000000000000000000000000000000000..2675219a8b14a68656b72cd0d5c1d59b6726e20a --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 (Winarto, Ray Andrew, Adrian HP) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..7e25ab124ebdf843e169b408388f143c8223852c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,55 @@ +version: '3' +services: + web: + image: nginx:latest + ports: + - "8000:80" + - "3000:443" + restart: always + env_file: + - ".env" + environment: + - MYSQL_DATABASE=${MYSQL_DATABASE} + - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} + - MYSQL_USER=${MYSQL_USER} + - MYSQL_PASSWORD=${MYSQL_PASSWORD} + volumes: + - "./etc/nginx/default.conf:/etc/nginx/conf.d/default.conf" + - "./etc/ssl:/etc/ssl" + - "./src:/var/www/html" + depends_on: + - php + - mysqldb + php: + image: nanoninja/php-fpm + restart: always + volumes: + - "./etc/php/php.ini:/usr/local/etc/php/conf.d/php.ini" + - "./src:/var/www/html" + myadmin: + image: phpmyadmin/phpmyadmin + container_name: phpmyadmin + ports: + - "8080:80" + environment: + - PMA_ARBITRARY=1 + - PMA_HOST=${MYSQL_HOST} + restart: always + depends_on: + - mysqldb + mysqldb: + image: mysql + user: "1000:50" + container_name: ${MYSQL_HOST} + restart: always + env_file: + - ".env" + environment: + - MYSQL_DATABASE=${MYSQL_DATABASE} + - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} + - MYSQL_USER=${MYSQL_USER} + - MYSQL_PASSWORD=${MYSQL_PASSWORD} + ports: + - "8989:3306" + volumes: + - "./data/db/mysql:/var/lib/mysql" \ No newline at end of file diff --git a/etc/nginx/default.conf b/etc/nginx/default.conf new file mode 100755 index 0000000000000000000000000000000000000000..e0d7dadaca23760880b39a3ed0b0416e278489ba --- /dev/null +++ b/etc/nginx/default.conf @@ -0,0 +1,87 @@ +# Nginx configuration + +server { + listen 80 default_server; + listen [::]:80 default_server; + server_name localhost; + + index index.php index.html; + error_log /var/log/nginx/error.log; + access_log /var/log/nginx/access.log; + root /var/www/html; + sendfile off; + + location / { + try_files $uri $uri/ /index.php?$args; + include /etc/nginx/mime.types; + } + + location ~ \.php$ { + try_files $uri =404; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_pass php:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $fastcgi_path_info; + } + + # Adding the cache control header for js and css files + # Make sure it is BELOW the PHP block + location ~* \.(?:css|js)$ { + try_files $uri /index.php$uri$is_args$args; + add_header Cache-Control "public, max-age=7200"; + # Add headers to serve security related headers (It is intended to + # have those duplicated to the ones above) + # Before enabling Strict-Transport-Security headers please read into + # this topic first. + # add_header Strict-Transport-Security "max-age=15768000; + # includeSubDomains; preload;"; + # + # WARNING: Only add the preload option once you read about + # the consequences in https://hstspreload.org/. This option + # will add the domain to a hardcoded list that is shipped + # in all major browsers and getting removed from this list + # could take several months. + add_header X-Content-Type-Options nosniff; + add_header X-Frame-Options "SAMEORIGIN"; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Robots-Tag none; + add_header X-Download-Options noopen; + add_header X-Permitted-Cross-Domain-Policies none; + # Optional: Don't log access to assets + access_log off; + } + + location ~* \.(?:svg|gif|png|html|ttf|woff|ico|jpg|jpeg)$ { + try_files $uri /index.php$uri$is_args$args; + # Optional: Don't log access to other assets + access_log off; + } +} + +# server { +# server_name localhost; + +# listen 443 ssl; +# fastcgi_param HTTPS on; + +# ssl_certificate /etc/ssl/server.pem; +# ssl_certificate_key /etc/ssl/server.key; +# ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; + +# index index.php index.html; +# error_log /var/log/nginx/error.log; +# access_log /var/log/nginx/access.log; +# root /var/www/html/public; + +# location ~ \.php$ { +# try_files $uri =404; +# fastcgi_split_path_info ^(.+\.php)(/.+)$; +# fastcgi_pass php:9000; +# fastcgi_index index.php; +# include fastcgi_params; +# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; +# fastcgi_param PATH_INFO $fastcgi_path_info; +# } +# } diff --git a/etc/php/php.ini b/etc/php/php.ini new file mode 100755 index 0000000000000000000000000000000000000000..1647620ec35b26a249a094d6cd08a967cbafc56a --- /dev/null +++ b/etc/php/php.ini @@ -0,0 +1,15 @@ +;PHPStorm +[xdebug] +xdebug.remote_enable=1 +xdebug.idekey=PHPSTORM +xdebug.profiler_enable=0 +xdebug.max_nesting_level=700 +xdebug.remote_host=192.168.0.1 # your ip + +;Netbeans +;[xdebug] +;xdebug.remote_enable=1 +;xdebug.remote_handler=dbgp +;xdebug.remote_mode=req +;xdebug.remote_host=192.168.0.1 # your ip +;xdebug.remote_port=9000 \ No newline at end of file diff --git a/mocks/complete-order.PNG b/mocks/complete-order.PNG new file mode 100755 index 0000000000000000000000000000000000000000..7f3c47746862149b4ac05621f6ecb786defa672a Binary files /dev/null and b/mocks/complete-order.PNG differ diff --git a/mocks/edit-preferred-location.PNG b/mocks/edit-preferred-location.PNG new file mode 100755 index 0000000000000000000000000000000000000000..3a1245395848b84d28ac9a5ee4eb61e4ae5fd1b3 Binary files /dev/null and b/mocks/edit-preferred-location.PNG differ diff --git a/mocks/edit-profile.PNG b/mocks/edit-profile.PNG new file mode 100755 index 0000000000000000000000000000000000000000..6244a5536e70d01c9bf5f11d5a3c5b5869fe6a38 Binary files /dev/null and b/mocks/edit-profile.PNG differ diff --git a/mocks/history-driver.PNG b/mocks/history-driver.PNG new file mode 100755 index 0000000000000000000000000000000000000000..a9e6921d1a9b8e522ccb32efa4ef447ce46caf8c Binary files /dev/null and b/mocks/history-driver.PNG differ diff --git a/mocks/history-penumpang.PNG b/mocks/history-penumpang.PNG new file mode 100755 index 0000000000000000000000000000000000000000..2c64011fba6a6279957f04f1c5eb01bd0f4465a0 Binary files /dev/null and b/mocks/history-penumpang.PNG differ diff --git a/mocks/login.PNG b/mocks/login.PNG new file mode 100755 index 0000000000000000000000000000000000000000..988463962dd113ae33998f2f8e8b238fc7e5eaf9 Binary files /dev/null and b/mocks/login.PNG differ diff --git a/mocks/order-ojek.PNG b/mocks/order-ojek.PNG new file mode 100755 index 0000000000000000000000000000000000000000..6a8d6cc01a948c346df9016068907f4388c9ff3a Binary files /dev/null and b/mocks/order-ojek.PNG differ diff --git a/mocks/profile.PNG b/mocks/profile.PNG new file mode 100755 index 0000000000000000000000000000000000000000..923086d315b8666a87550614af0cd2332c20cfdb Binary files /dev/null and b/mocks/profile.PNG differ diff --git a/mocks/register.PNG b/mocks/register.PNG new file mode 100755 index 0000000000000000000000000000000000000000..67ed0b9deaf392584d5ffd20e7057d07581e1e02 Binary files /dev/null and b/mocks/register.PNG differ diff --git a/mocks/select-driver.PNG b/mocks/select-driver.PNG new file mode 100755 index 0000000000000000000000000000000000000000..7e3808ddb97f7fde6db4758861d29d68557ae9f0 Binary files /dev/null and b/mocks/select-driver.PNG differ diff --git a/motaraido.sql b/motaraido.sql new file mode 100644 index 0000000000000000000000000000000000000000..0ffd75c1f8e337d1510cde5b9f40a9e0fdfa973a --- /dev/null +++ b/motaraido.sql @@ -0,0 +1,136 @@ +-- phpMyAdmin SQL Dump +-- version 4.7.4 +-- https://www.phpmyadmin.net/ +-- +-- Host: mysql +-- Generation Time: Oct 03, 2017 at 02:49 AM +-- Server version: 5.7.19 +-- PHP Version: 7.0.21 + +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET AUTOCOMMIT = 0; +START TRANSACTION; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; + +-- +-- Database: `motaraido` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `history` +-- + +CREATE TABLE `history` ( + `usernameUser` varchar(32) NOT NULL, + `usernameDriver` varchar(32) NOT NULL, + `rating` int(11) NOT NULL, + `comment` text, + `dateOrder` date NOT NULL, + `pickup` text NOT NULL, + `destination` text NOT NULL, + `ishide` boolean NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `preferredloc` +-- + +CREATE TABLE `preferredloc` ( + `username` varchar(32) NOT NULL, + `location` varchar(50) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `rating` +-- + +CREATE TABLE `rating` ( + `username` varchar(32) NOT NULL, + `rating` int(11) NOT NULL, + `votes` varchar(50) NOT NULL, + `numrat` int(11) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `user` +-- + +CREATE TABLE `user` ( + `username` varchar(32) NOT NULL, + `password` varchar(32) NOT NULL, + `fullname` varchar(50) NOT NULL, + `phone` varchar(15) NOT NULL, + `isdriver` tinyint(1) NOT NULL, + `email` varchar(100) NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `history` +-- +ALTER TABLE `history` + ADD KEY `usernameUser` (`usernameUser`), + ADD KEY `usernameDriver` (`usernameDriver`); + +-- +-- Indexes for table `preferredloc` +-- +ALTER TABLE `preferredloc` + ADD KEY `username` (`username`); + +-- +-- Indexes for table `rating` +-- +ALTER TABLE `rating` + ADD KEY `username` (`username`); + +-- +-- Indexes for table `user` +-- +ALTER TABLE `user` + ADD PRIMARY KEY (`username`); + +-- +-- Constraints for dumped tables +-- + +-- +-- Constraints for table `history` +-- +ALTER TABLE `history` + ADD CONSTRAINT `history_ibfk_1` FOREIGN KEY (`usernameUser`) REFERENCES `user` (`username`) ON DELETE CASCADE, + ADD CONSTRAINT `history_ibfk_2` FOREIGN KEY (`usernameDriver`) REFERENCES `user` (`username`) ON DELETE CASCADE; + +-- +-- Constraints for table `preferredloc` +-- +ALTER TABLE `preferredloc` + ADD CONSTRAINT `preferredloc_ibfk_1` FOREIGN KEY (`username`) REFERENCES `user` (`username`) ON DELETE CASCADE; + +-- +-- Constraints for table `rating` +-- +ALTER TABLE `rating` + ADD CONSTRAINT `rating_ibfk_1` FOREIGN KEY (`username`) REFERENCES `user` (`username`) ON DELETE CASCADE; +COMMIT; + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/src/app/Core/Config.php b/src/app/Core/Config.php new file mode 100644 index 0000000000000000000000000000000000000000..dec3ba72c0c5008d03abdb182cc1360272cab82e --- /dev/null +++ b/src/app/Core/Config.php @@ -0,0 +1,39 @@ +<?php + +namespace MotaRaido\Core; + +if (!defined('MOTAFW')) { + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} +$host = 'mysql'; +$db = 'motaraido'; +$un = 'datafreaks'; +$pass = 'datafreaks'; + +class Config { + protected static $data = array( + 'database' => array ( + 'driver' => 'mysql', + 'host' => 'mysql', + 'port' => '8989', + 'db' => 'motaraido', + 'username' => 'datafreaks', + 'password' => 'datafreaks' + ), + 'template' => array ( + 'header' => APPDIR . '/Menu/Header.php', + 'headerWithMenu' => APPDIR . '/Menu/HeaderWithMenu.php', + 'footer' => APPDIR . '/Menu/Footer.php' + ), + 'base_url' => '', + 'secret-key' => '\x8f\xc6\xe8\x5e\xcd\x3f\x0a\x96\xf7\x62\x14\xc2\x74\xfb\x23\x54' + ); + + public static function get($name) + { + if (array_key_exists($name, self::$data)) { + return self::$data[$name]; + } + } +} \ No newline at end of file diff --git a/src/app/Core/Database/Connector.php b/src/app/Core/Database/Connector.php new file mode 100644 index 0000000000000000000000000000000000000000..025c26e175034eb743e15db58266ee1aba4e1ccc --- /dev/null +++ b/src/app/Core/Database/Connector.php @@ -0,0 +1,48 @@ +<?php + +namespace MotaRaido\Core\Database; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +use \PDO; +use \Closure; + +class Connector extends PDO +{ + private $forcedRollBack = false; + + public function __construct($config) { + parent::__construct($config['driver'] . ':dbname=' . $config['db'] . ';' . 'host=' . $config['host'], $config['username'], $config['password']); + } + + public function createTransaction(Closure $func) + { + $this->beginTransaction(); + try + { + $func($this); + if ($this->forcedRollBack) + { + $this->rollback(); + } + else + { + $this->commit(); + } + } + catch (Exception $e) + { + $this->rollback(); + throw $e; + } + } + + public function forceRollback() + { + $this->forcedRollback = true; + } +} \ No newline at end of file diff --git a/src/app/Core/Database/Encryption.php b/src/app/Core/Database/Encryption.php new file mode 100644 index 0000000000000000000000000000000000000000..527dd031fca3cf32773eff7bd27f339a9d2dca0a --- /dev/null +++ b/src/app/Core/Database/Encryption.php @@ -0,0 +1,25 @@ +<?php + +namespace MotaRaido\Core\Database; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +use \MotaRaido\Core\Config; + +class Encryption +{ + public static function encrypt($password) + { + $hash = password_hash($password . Config::get('secret-key'), PASSWORD_DEFAULT); + return base64_encode($hash); + } + + public static function verify($password, $text) + { + return password_verify($password . Config::get('secret-key'), base64_decode($text)); + } +} \ No newline at end of file diff --git a/src/app/Core/Database/Query.php b/src/app/Core/Database/Query.php new file mode 100644 index 0000000000000000000000000000000000000000..8e91ccbfc3588862694efad8ffeed0f7da536039 --- /dev/null +++ b/src/app/Core/Database/Query.php @@ -0,0 +1,111 @@ +<?php + +namespace MotaRaido\Core\Database; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +use \MotaRaido\Core\Database\Connector; +use \Closure; + +class Query +{ + private $dbh; + + public function __construct(Connector $dbh) + { + $this->dbh = $dbh; + $this->dbh->setAttribute(Connector::ATTR_ERRMODE, Connector::ERRMODE_EXCEPTION); + $this->dbh->forceRollback(); + } + + public function transaction(Closure $func) { + $this->dbh->createTransaction($func); + } + + public function select($tableName, $where) + { + $sql = $this->createSelectQuery($tableName, $where); + $whereParams = $this->getWhereParameters($where); + $stmp = $this->dbh->prepare($sql); + $stmp->execute($whereParams); + return $stmp->fetchAll(); + } + + public function insert($tableName, $values) + { + $sql = $this->createInsertQuery($tableName, $values); + $stmp = $this->dbh->prepare($sql); + $out = $stmp->execute($values); + return $out; + } + + public function update($tableName, $values, $where) + { + $sql = $this->createUpdateQuery($tableName, $values, $where); + $whereParams = $this->getWhereParameters($where); + $stmp = $this->dbh->prepare($sql); + $out = $stmp->execute(array_merge($values, $whereParams)); + return $out; + } + + public function delete($tableName, $where) + { + $sql = $this->createDeleteQuery($tableName, $where); + $whereParams = $this->getWhereParameters($where); + $stmp = $this->dbh->prepare($sql); + $out = $stmp->execute($whereParams); + return $out; + } + + protected function getWhereParameters($where) + { + $whereParams = array(); + foreach ($where as $key => $value) { + $whereParams[":W_{$key}"] = $value; + } + return $whereParams; + } + + protected function createSelectQuery($table, $where) + { + return "SELECT * FROM " . $table . $this->createSqlWhere($where); + } + + protected function createUpdateQuery($table, $values, $where) + { + $sqlValues = array(); + foreach (array_keys($values) as $key) { + $sqlValues[] = "{$key} = :{$key}"; + } + return "UPDATE {$table} SET " . implode(', ', $sqlValues) . $this->createSqlWhere($where); + } + + protected function createInsertQuery($table, $values) + { + $sqlValues = array(); + foreach (array_keys($values) as $key) { + $sqlValues[] = ":{$key}"; + } + return "INSERT INTO {$table} (" . implode(', ', array_keys($values)) . ") VALUES (" . implode(', ', $sqlValues) . ")"; + } + + protected function createDeleteQuery($table, $where) + { + return "DELETE FROM {$table}" . $this->createSqlWhere($where); + } + + protected function createSqlWhere($where) + { + if (count((array) $where) == 0) return null; + + $whereSql = array(); + foreach ($where as $key => $value) { + $whereSql[] = "{$key} = :W_{$key}"; + } + return ' WHERE ' . implode(' AND ', $whereSql); + } +} \ No newline at end of file diff --git a/src/app/Core/ErrorMessage.php b/src/app/Core/ErrorMessage.php new file mode 100644 index 0000000000000000000000000000000000000000..9a8572813b20d02ee03e078e3652a904f1a30a75 --- /dev/null +++ b/src/app/Core/ErrorMessage.php @@ -0,0 +1,72 @@ +<?php + +namespace MotaRaido\Core; + +if (!defined('MOTAFW')) { + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +class ErrorMessage +{ + public static function get($code = null) + { + $text = 'OK'; + if ($code !== null) { + switch ($code) { + case 100: $text = 'Continue'; break; + case 101: $text = 'Switching Protocols'; break; + case 200: $text = 'OK'; break; + case 201: $text = 'Created'; break; + case 202: $text = 'Accepted'; break; + case 203: $text = 'Non-Authoritative Information'; break; + case 204: $text = 'No Content'; break; + case 205: $text = 'Reset Content'; break; + case 206: $text = 'Partial Content'; break; + case 300: $text = 'Multiple Choices'; break; + case 301: $text = 'Moved Permanently'; break; + case 302: $text = 'Moved Temporarily'; break; + case 303: $text = 'See Other'; break; + case 304: $text = 'Not Modified'; break; + case 305: $text = 'Use Proxy'; break; + case 400: $text = 'Bad Request'; break; + case 401: $text = 'Unauthorized'; break; + case 402: $text = 'Payment Required'; break; + case 403: $text = 'Forbidden'; break; + case 404: $text = 'Not Found'; break; + case 405: $text = 'Method Not Allowed'; break; + case 406: $text = 'Not Acceptable'; break; + case 407: $text = 'Proxy Authentication Required'; break; + case 408: $text = 'Request Time-out'; break; + case 409: $text = 'Conflict'; break; + case 410: $text = 'Gone'; break; + case 411: $text = 'Length Required'; break; + case 412: $text = 'Precondition Failed'; break; + case 413: $text = 'Request Entity Too Large'; break; + case 414: $text = 'Request-URI Too Large'; break; + case 415: $text = 'Unsupported Media Type'; break; + case 500: $text = 'Internal Server Error'; break; + case 501: $text = 'Not Implemented'; break; + case 502: $text = 'Bad Gateway'; break; + case 503: $text = 'Service Unavailable'; break; + case 504: $text = 'Gateway Time-out'; break; + case 505: $text = 'HTTP Version not supported'; break; + default: + exit('Unknown http status code "' . htmlentities($code) . '"'); + break; + } + + $protocol = (isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0'); + // header($protocol . ' ' . $code . ' ' . $text); + $GLOBALS['http_response_code'] = $code; + $GLOBALS['http_response_code_message'] = $text; + } else { + $code = (isset($GLOBALS['http_response_code']) ? $GLOBALS['http_response_code'] : 200); + } + + return [ + 'code' => $code, + 'message' => $text + ]; + } +} diff --git a/src/app/Core/Route.php b/src/app/Core/Route.php new file mode 100644 index 0000000000000000000000000000000000000000..3ab04f6988dc030e2d3a5a37990bd940b500d1d6 --- /dev/null +++ b/src/app/Core/Route.php @@ -0,0 +1,70 @@ +<?php + +namespace MotaRaido\Core; + +use \MotaRaido\Core\ErrorMessage; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} +class Route { + + private static $httpAction; + + public static function setHttpAction($action) { + self::$httpAction = $action; + } + + public static function get_uri() { + if (isset($_SERVER['REQUEST_URI'])) { + $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); + } else { + return ""; + } + return '/' . ltrim($uri, '/'); + } + + public static function add($pattern_uri, $action = null, $middleware = null) { + self::setHttpAction(function($action) { + echo $action['code'] . ' - ' . $action['message']; + }); + + $request_uri = self::get_uri(); + + preg_match_all('/#([0-9a-zA-Z_]+)/', $pattern_uri, $names, PREG_PATTERN_ORDER); + $names = $names[0]; + + $pattern_uri_regex = preg_replace_callback('/#[[0-9a-zA-Z_]+/', array(__CLASS__, 'uri_regex'), $pattern_uri); + $pattern_uri_regex .= '/?'; + + $params = array(); + + if (preg_match('@^' . $pattern_uri_regex . '$@', $request_uri, $values)) { + array_shift($values); + + foreach($names as $index => $value) { + $params[substr($value, 1)] = urldecode($values[$index]); + } + + if (is_callable($action)) { + if(is_callable($middleware)) { + if(call_user_func($middleware)) { + call_user_func_array($action, array_values($params)); + } else { + call_user_func_array(self::$httpAction, [ErrorMessage::get('401')]); + } + } else { + call_user_func_array($action, array_values($params)); + } + } + } + + return $params; + } + + public static function uri_regex($matches) { + return '([a-zA-Z0-9_\+\-%]+)'; + } +} \ No newline at end of file diff --git a/src/app/Core/View.php b/src/app/Core/View.php new file mode 100644 index 0000000000000000000000000000000000000000..4706debcceb6425153067e8775a502ba0bc00402 --- /dev/null +++ b/src/app/Core/View.php @@ -0,0 +1,48 @@ +<?php + +namespace MotaRaido\Core; + + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +use \MotaRaido\Core\Config; + +class View +{ + + protected $data = array(); + + function render($view, $template = true) { + ob_start(); + include_once $template ? Config::get('template')['headerWithMenu'] : Config::get('template')['header']; + include_once $view; + if($template) include_once Config::get('template')['footer']; + $str = ob_get_contents(); + ob_end_clean(); + echo $str; + } + + public function __get($name) + { + if (array_key_exists($name, $this->data)) { + return $this->data[$name]; + } + } + + function include($key, $val) { + ob_start(); + require_once $val; + $str = ob_get_contents(); + ob_end_clean(); + $this->data[$key] = $str; + } + + function assign($key, $val) { + if(!is_array($val)) $val = \htmlspecialchars($val); + $this->data[$key] = $val; + } +} \ No newline at end of file diff --git a/src/app/Login/Login.routes.php b/src/app/Login/Login.routes.php new file mode 100644 index 0000000000000000000000000000000000000000..04ba8740bf13e03c723d0b6d449b1da2ce0cad81 --- /dev/null +++ b/src/app/Login/Login.routes.php @@ -0,0 +1,50 @@ +<?php + +namespace MotaRaido\Login; + +use \MotaRaido\Core\View; +use \MotaRaido\Core\Route; + +if (!defined('MOTAFW')) { + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +Route::add('/', function () { + $view = new View(); + $view->assign('style', CSS . "style.css"); + $view->assign('title', 'Login'); + $view->assign('script', JS . "app.js"); + $view->render(__DIR__ . '/Login.view.php', false); +}); + +Route::add('/login', function () { + $view = new View(); + $view->assign('style', CSS . "style.css"); + $view->assign('title', 'Login'); + $view->assign('script', JS . "app.js"); + $view->render(__DIR__ . '/Login.view.php', false); +}); + +Route::add('/login/validation', function() use ($query) { + $query->transaction(function() use ($query) { + $username = $_POST['username']; + $password = $_POST['password']; + $usrData = $query->select('user', []); + $pwdData = $query->select('user', []); + $found = false; + + foreach($usrData as $record) { + if($record[0] == $username && $record[1] == $password){ + $found = true; + break; + } + } + + if ($found) { + header('Location: /profile/' . $username); + } else { + header('Location: /login'); + } + }); +}); \ No newline at end of file diff --git a/src/app/Login/Login.view.php b/src/app/Login/Login.view.php new file mode 100644 index 0000000000000000000000000000000000000000..957d852d758920181016f55cd23f69e38b6a1b87 --- /dev/null +++ b/src/app/Login/Login.view.php @@ -0,0 +1,39 @@ +<?php + +namespace MotaRaido\Login; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + +<section class="content-layout"> + <header class="title"> + <div> + <hr> + <h1><?php echo $this->title; ?></h1> + <hr> + </div> + </header> + <section class="form-layout"> + <form action="/login/validation" method="post" name="loginform" onsubmit="return loginValidation();"> + <div class="form-input"> + <div>Username</div> + <input id="username" type="text" name="username"> + </div> + <div class="form-input"> + <div>Password</div> + <input type="password" name="password"> + </div> + <div id="button-layout"> + <div> + <a href="/signup">Don't have an account?</a> + </div> + <input id="register-button" type="submit" value="GO!"> + </div> + </form> + </section> +</section> \ No newline at end of file diff --git a/src/app/Menu/Footer.php b/src/app/Menu/Footer.php new file mode 100644 index 0000000000000000000000000000000000000000..34d9b3448c4f5ee601f9bd54f0721b8524a76a27 --- /dev/null +++ b/src/app/Menu/Footer.php @@ -0,0 +1,19 @@ +<?php + +namespace MotaRaido\Menu; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + +<div class="footer"> + <div>Winarto <br /> 13515061</div> + <div>Ray Andrew <br /> 13515073</div> + <div>Adrian HP <br /> 13515091</div> +</div> +</body> +</html> \ No newline at end of file diff --git a/src/app/Menu/Header.php b/src/app/Menu/Header.php new file mode 100644 index 0000000000000000000000000000000000000000..badd527732909e3e2284bc0ac708acfdeb05488c --- /dev/null +++ b/src/app/Menu/Header.php @@ -0,0 +1,21 @@ +<?php + +namespace MotaRaido\Menu; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + +<!DOCTYPE html> +<head> + <title><?php echo $this->title; ?></title> + <link rel="stylesheet" type="text/css" href=<?php echo CSS . 'style.css?time=' . date("H:i:s"); ?>></link> + <link rel="stylesheet" type="text/css" href=<?php echo CSS . 'profile.css?time=' . date("H:i:s"); ?>></link> + <script type='text/javascript' src=<?php echo JS . 'app.js?time=' . date("H:i:s"); ?>></script> + <script type='text/javascript' src=<?php echo JS . 'signup.js?time=' . date("H:i:s"); ?>></script> +</head> +<body> \ No newline at end of file diff --git a/src/app/Menu/HeaderWithMenu.php b/src/app/Menu/HeaderWithMenu.php new file mode 100644 index 0000000000000000000000000000000000000000..7d411c55acd8c5a115e79a55865c7babf702265d --- /dev/null +++ b/src/app/Menu/HeaderWithMenu.php @@ -0,0 +1,47 @@ +<?php + +namespace MotaRaido\Menu; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + +<!DOCTYPE html> +<head> + <title><?php echo $this->title; ?></title> + <link rel="stylesheet" type="text/css" href=<?php echo CSS . 'style.css?time=' . date("H:i:s"); ?>></link> + <link rel="stylesheet" type="text/css" href=<?php echo CSS . 'profile.css?time=' . date("H:i:s"); ?>></link> + <script type='text/javascript' src=<?php echo JS . 'app.js'; ?>></script> + +</head> +<body> +<div> + <header class="header-box"> + <div class="col-header-left"> + <div> + <span class='logo-title'>MotoRaido</span><br /> + <span class='tagline'>Anata to issho ni noru mÅtÄ</span> + </div> + </div> + <div class="col-header-right"> + <div> + Hi, <b><?php echo $this->user; ?></b> ! + </div> + <div> + <a href="/login">Logout</a> + </div> + </div> + </header> + <div class='menu'> + <div class="menu-column"></div> + <div class="menu-column"></div> + <div class="menu-column"></div> + <div id="orderheader" class="menu-cell"><a href="/order/<?php echo $this->user; ?>" class="text-link">ORDER</a></div> + <div id="historyheader" class="menu-cell"><a href="/history/<?php echo $this->user; ?>" class="text-link">HISTORY</a></div> + <div id="profileheader" class="menu-cell"><a href="/profile/<?php echo $this->user; ?>" class="text-link">MY PROFILE</a></div> + </div> +</div> \ No newline at end of file diff --git a/src/app/Menu/History/History.routes.php b/src/app/Menu/History/History.routes.php new file mode 100644 index 0000000000000000000000000000000000000000..8dacc3dc0c1cff1fb232202140212b2a3b0ba0d8 --- /dev/null +++ b/src/app/Menu/History/History.routes.php @@ -0,0 +1,34 @@ +<?php + +namespace MotaRaido\Menu\History; + +use \MotaRaido\Core\View; +use \MotaRaido\Core\Route; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +Route::add('/history/#user', function($user) use ($query) { + $view = new View(); + $userData = $query->select('history', ['usernameUser' => $user, 'ishide' => false]); + $driverData = $query->select('history', ['usernameDriver' => $user, 'ishide' => false]); + + $view->assign('user', $user); + $view->assign('title', 'History'); + $view->assign('image', IMG); + $view->assign('historyUser', $userData); + $view->assign('historyDriver', $driverData); + $view->assign('script', JS . "history.js?time=" . date("H:i:s")); + + $view->render(__DIR__ . '/History.view.php'); +}); + +Route::add('/history/#user/update/#driver/#date', function($user, $driver, $date) use ($query) { + $query->transaction(function() use ($query, $user, $driver, $date) { + $query->update('history', ['ishide' => 1], ['usernameUser' => $user, 'usernameDriver' => $driver, 'dateOrder' => $date]); + }); + header('Location: /history/' . $user); +}); \ No newline at end of file diff --git a/src/app/Menu/History/History.view.php b/src/app/Menu/History/History.view.php new file mode 100644 index 0000000000000000000000000000000000000000..3a3b9c43c40dae4c185e963e64a898051f34ce85 --- /dev/null +++ b/src/app/Menu/History/History.view.php @@ -0,0 +1,83 @@ +<?php + +namespace MotaRaido\Menu\Profile; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + +<?php echo $this->header; ?> +<div class="subtitle-cont subtitle-history"> + TRANSACTION HISTORY +</div> + <div class="body-container"> + <div class='menu'> + <div class="menu-column"></div> + <div class="menu-column"></div> + <div id="user-his" class="menu-cell" onclick="tabActive('user');">MY PREVIOUS ORDERS</div> + <div id="driver-his" class="menu-cell" onclick="tabActive('driver');">DRIVER HISTORY</div> + </div> + </div> + + <div id="history-container"> + <ol class="history-list order-list"> + <?php foreach($this->historyUser as $history): ?> + <li class="list-text-his"> + <div class="history-pic-div"> + <img class="profile-pic-his" src=<?php echo $this->image . $history[1]; ?> alt=""> + </div> + <span class="hide"> + <a href=<?php echo "/history/". $history[0] . "/update/" . $history[1] . "/" . rawurlencode($history[4]); ?>>HIDE</a> + </span> + <div class="his-text"> + <div class="date-his"><?php echo htmlentities($history[4]); ?></div> + <div class="name-his"><b><?php echo $history[1]; ?></b></div> + <div><?php echo $history[5]; ?> - <?php echo $history[6]; ?></div> + <div> + You rated : ★<?php echo $history[2]; ?> + <div> + <div> + You commented: + <div class="comment"> + <?php echo $history[3]; ?> + </div> + </div> + </div> + </li> + <?php endforeach; ?> + </ol> + + <ol class="history-list driver-list"> + + <?php foreach($this->historyDriver as $history): ?> + <li class="list-text-his"> + <div class="history-pic-div"> + <img class="profile-pic-his" src=<?php echo $this->image . $history[0]; ?> alt="" /> + </div> + <span class="hide"> + <a href=<?php echo "/history/". $history[0] . "/update/" . $history[1] . "/" . rawurlencode($history[4]); ?>>HIDE</a> + </span> + <div class="his-text"> + <div class="date-his"><?php echo $history[4]; ?></div> + <div><b><?php echo $history[0]; ?></b></div> + <div><?php echo $history[5]; ?> - <?php echo $history[6]; ?></div> + <div> + gave <span><?php echo $history[2]; ?></span> stars for this order + <div> + <div> + and left comment: + <div class="comment"> + <?php echo $history[3]; ?> + </div> + </div> + </div> + </li> + <?php endforeach; ?> + </ol> + </div> + <script src=<?php echo $this->script; ?>></script> +<?php echo $this->footer; ?> \ No newline at end of file diff --git a/src/app/Menu/Order/CompleteOrder.routes.php b/src/app/Menu/Order/CompleteOrder.routes.php new file mode 100644 index 0000000000000000000000000000000000000000..83ca30f5aeb748f0f7db154660fe70b9af09e7bd --- /dev/null +++ b/src/app/Menu/Order/CompleteOrder.routes.php @@ -0,0 +1,43 @@ +<?php + +namespace MotaRaido\Menu\Order; + +use \MotaRaido\Core\View; +use \MotaRaido\Core\Route; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +Route::add('/order/#user/completeorder', function($user) use ($query) { + $driver = $_POST['driver-username']; + $from = $_POST['pickLoc']; + $dest = $_POST['dest']; + $driverInfo = $query->select('user',['username' => $driver]); + $view = new View(); + $view->assign('title', 'Complete Order'); + $view->assign('image', IMG . $driver); + $view->assign('from', $from); + $view->assign('dest', $dest); + $view->assign('user', $user); + $view->assign('driver', $driver); + $view->assign('drivername', $driverInfo[0][2]); + + $view->render(__DIR__ . '/CompleteOrder.view.php'); + +}); + +Route::add('/order/#user/completeorder/finish', function($user) use ($query) { + $query->transaction(function() use ($query,$user) { + header('Location: /order/' . $user); + $name = $_POST['driver']; + $rating = $_POST['rating']; + $comment = $_POST['comment']; + $from = $_POST['from']; + $dest = $_POST['dest']; + $query->insert('history', ['usernameUser' => $user, 'usernameDriver' => $name, 'rating' => $rating, 'comment' => $comment, 'dateOrder' => date("Y-m-d H:i:s"), 'pickup' => $from, 'destination' => $dest, 'ishide' => 0]); + + }); +}); \ No newline at end of file diff --git a/src/app/Menu/Order/CompleteOrder.view.php b/src/app/Menu/Order/CompleteOrder.view.php new file mode 100644 index 0000000000000000000000000000000000000000..2e68ef08087c512a180fa18247af1e06737c0bcf --- /dev/null +++ b/src/app/Menu/Order/CompleteOrder.view.php @@ -0,0 +1,58 @@ +<?php + +namespace MotaRaido\Menu\Order; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + +<?php echo $this->header; ?> +<div class="edit-profile-header"> + Make an order +</div> +<div class="progress-container"> + <div class="progress"> + <div class="progress-num">1</div> Select Destination + </div> + <div class="progress"> + <div class="progress-num">2</div> Select a driver + </div> + <div class="progress selected"> + <div class="progress-num selected">3</div> Complete your order + </div> +</div> +<div class="edit-profile-header"> + How was it? +</div> +<form action="/order/<?php echo $this->user; ?>/completeorder/finish" method="post" name="completeorder-form"> + <div class="completeorder-container"> + <input type='hidden' name='driver' value='<?php echo $this->driver; ?>'> + <input type='hidden' name='from' value='<?php echo $this->from; ?>'> + <input type='hidden' name='dest' value='<?php echo $this->dest; ?>'> + <img class="driver-completeorder-pic" src="<?php echo $this->image; ?>" alt=""> + <div class="driver-name-disp">@<?php echo $this->driver; ?></div> + <div class="driver-fullname-disp"><?php echo $this->drivername; ?></div> + <span class="starRating"> + <input id="rating5" type="radio" name="rating" value="5"> + <label for="rating5">5</label> + <input id="rating4" type="radio" name="rating" value="4"> + <label for="rating4">4</label> + <input id="rating3" type="radio" name="rating" value="3"> + <label for="rating3">3</label> + <input id="rating2" type="radio" name="rating" value="2"> + <label for="rating2">2</label> + <input id="rating1" type="radio" name="rating" value="1"> + <label for="rating1">1</label> + </span> + <textarea cols="5" placeholder="Your comment..." name="comment"></textarea> + </div> + <div class="right-align"> + <input class="accept-button select-driver-btn completeorder-btn" type="submit" value="Complete Order"> + </div> + +</form> + diff --git a/src/app/Menu/Order/Order.routes.php b/src/app/Menu/Order/Order.routes.php new file mode 100644 index 0000000000000000000000000000000000000000..91a33e6e0884f4ed6a1007689e93a32066cff690 --- /dev/null +++ b/src/app/Menu/Order/Order.routes.php @@ -0,0 +1,21 @@ +<?php + +namespace MotaRaido\Menu\Order; + +use \MotaRaido\Core\View; +use \MotaRaido\Core\Route; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +Route::add('/order/#user', function($user) use ($query) { + $query->transaction(function() use ($query, $user) { + $view = new View(); + $view->assign('title', 'Order'); + $view->assign('user', $user); + $view->render(__DIR__ . '/Order.view.php'); + }); +}); \ No newline at end of file diff --git a/src/app/Menu/Order/Order.view.php b/src/app/Menu/Order/Order.view.php new file mode 100644 index 0000000000000000000000000000000000000000..00acb52f023c3f5c2ef6704d86c544a4111e119c --- /dev/null +++ b/src/app/Menu/Order/Order.view.php @@ -0,0 +1,48 @@ +<?php + +namespace MotaRaido\Menu\Order; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + + +<div class="container"> + <div class="edit-profile-header"> + Make an order + </div> + <div class="progress-container"> + <div class="progress selected"> + <div class="progress-num">1</div> Select Destination + </div> + <div class="progress"> + <div class="progress-num">2</div> Select a driver + </div> + <div class="progress"> + <div class="progress-num">3</div> Complete your order + </div> + </div> + <form action=<?php echo "/order/" . $this->user . "/selectdriver"; ?> method='post'> + <div class="edit-profile-btm"> + <div class="form-input"> + <label for="pick-point">Picking point</label> + <input class="ep-textarea" type="text" name="pick-point" /> + </div> + <div class="form-input"> + <label for="destination">Destination</label> + <input class="ep-textarea" type="text" name="destination" /> + </div> + <div class="form-input"> + <label for="pref-driver">Preferred Driver</label> + <input class="ep-textarea" type="text" name="pref-driver" placeholder="(Optional)"/> + </div> + <div class="right-align"> + <input class="accept-button select-driver-btn" id="save-profile" type="submit" value="Next" /> + </div> + </div> + </form> +</div> \ No newline at end of file diff --git a/src/app/Menu/Order/SelectDriver.routes.php b/src/app/Menu/Order/SelectDriver.routes.php new file mode 100644 index 0000000000000000000000000000000000000000..cdf52521f4757dd9081d145b1a3b4028d7eb4735 --- /dev/null +++ b/src/app/Menu/Order/SelectDriver.routes.php @@ -0,0 +1,64 @@ +<?php + +namespace MotaRaido\Menu\Order; + +use \MotaRaido\Core\View; +use \MotaRaido\Core\Route; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +Route::add('/order/#user/selectdriver', function($user) use ($query) { + $view = new View(); + $view->assign('title', 'Select Driver'); + $view->assign('script', JS . 'selectdriver.js'); + $view->assign('user', $user); + $view->assign('image', IMG); + + $pickLoc = $_POST['pick-point']; + $dest = $_POST['destination']; + $prefDriver = $_POST['pref-driver']; + $driverList = $query->select('preferredloc',[]); + $ratingDat = $query->select('history',[]); + $driverName = $query->select('user', []); + + $driverPrefLoc = array(); + $preferredDriver = ''; + $count = 0; + foreach($driverList as $driver) { + if(!strcasecmp($driver[0],$prefDriver) && $driver[0] !== $user) { + $preferredDriver = $driver[0]; + } else { + if (($driver[1] === $pickLoc || $driver[1] === $dest) && !in_array($driver[0],$driverPrefLoc) && $driver[0] !== $user) { + $driverPrefLoc[$count] = $driver[0]; + $count++; + } + } + } + + EmbedJS($driverPrefLoc, $ratingDat, $driverName, $user, $preferredDriver, $pickLoc, $dest); + print_r($jsDriverArr); + $view->render(__DIR__ . '/SelectDriver.view.php'); +}); + +function EmbedJS($driverArr, $ratingArr, $driverNameArr, $user, $prefDriver, $pickLoc, $dest) { + $jsRatingArr = json_encode($ratingArr); + $jsDriverArr = json_encode($driverArr); + $jsDriverNameArr = json_encode($driverNameArr); + $jsUser = json_encode($user); + $jsPrefDriver = json_encode($prefDriver); + $jsPickLoc = json_encode($pickLoc); + $jsDest = json_encode($dest); + echo "<script>"; + echo "var driverArr = $jsDriverArr;"; + echo "var ratingArr = $jsRatingArr;"; + echo "var driverNameArr = $jsDriverNameArr;"; + echo "var user = $jsUser;"; + echo "var preferredDriver = $jsPrefDriver;"; + echo "var pickLoc = $jsPickLoc;"; + echo "var dest = $jsDest;"; + echo "</script>"; +} \ No newline at end of file diff --git a/src/app/Menu/Order/SelectDriver.view.php b/src/app/Menu/Order/SelectDriver.view.php new file mode 100644 index 0000000000000000000000000000000000000000..b0420cca0dcb2b575420a8a8599951c4bd066836 --- /dev/null +++ b/src/app/Menu/Order/SelectDriver.view.php @@ -0,0 +1,38 @@ +<?php + +namespace MotaRaido\Menu\Order; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + +<?php echo $this->header; ?> +<div class="edit-profile-header"> + Make an order +</div> +<div class="progress-container"> + <div class="progress"> + <div class="progress-num">1</div> Select Destination + </div> + <div class="progress selected"> + <div class="progress-num">2</div> Select a driver + </div> + <div class="progress"> + <div class="progress-num">3</div> Complete your order + </div> +</div> +<div id="pref-driver" class="select-driver"> + <div class= "selectdriver-header"> + Preferred Drivers: + </div> + </div> +<div id="other-driver" class="select-driver"> + <div class="selectdriver-header"> + Other Drivers: + </div> +</div> +<script src="<?php echo $this->script; ?>"></script> diff --git a/src/app/Menu/Profile/EditPrefLoc.routes.php b/src/app/Menu/Profile/EditPrefLoc.routes.php new file mode 100644 index 0000000000000000000000000000000000000000..f16bc9489ffb2a26a2671a2f1136c6c0a1ab54e9 --- /dev/null +++ b/src/app/Menu/Profile/EditPrefLoc.routes.php @@ -0,0 +1,46 @@ +<?php + +namespace MotaRaido\Menu\Profile; + +use \MotaRaido\Core\View; +use \MotaRaido\Core\Route; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +Route::add('/preferred-loc/#user', function($user) use ($query) { + $view = new View(); + $view->assign('title', 'Edit Preferred Location'); + $view->assign('user', $user); + $prefLoc = $query->select('preferredloc', ['username' => $user]); + $view->assign('prefLoc', $prefLoc); + $view->render(__DIR__ . '/EditPrefLoc.view.php'); +}); + +Route::add('/preferred-loc/#user/finish', function($user) use ($query) { + $query->transaction(function() use ($query, $user) { + $location = $_POST['location']; + $query->insert('preferredloc', array('username' => $user, 'location' => $location)); + header('Location: /preferred-loc/' . $user); + }); +}); + +Route::add('/preferred-loc/#user/edit', function($user) use ($query) { + $query->transaction(function() use ($query, $user) { + $location_new = $_POST['location_new']; + $location_old = $_POST['location_old']; + $query->update('preferredloc', array('location' => $location_new), array('username' => $user, 'location' => $location_old)); + header('Location: /preferred-loc/' . $user); + }); +}); + + +Route::add('/preferred-loc/#user/delete/#location', function($user, $location) use ($query) { + $query->transaction(function() use ($query, $user, $location) { + $query->delete('preferredloc', array('username' => $user, 'location' => $location)); + header('Location: /preferred-loc/' . $user); + }); +}); \ No newline at end of file diff --git a/src/app/Menu/Profile/EditPrefLoc.view.php b/src/app/Menu/Profile/EditPrefLoc.view.php new file mode 100644 index 0000000000000000000000000000000000000000..b891a277bb0b8d156beb7746d50444c386e5040f --- /dev/null +++ b/src/app/Menu/Profile/EditPrefLoc.view.php @@ -0,0 +1,58 @@ +<?php + +namespace MotaRaido\Menu\Profile; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + +<div class="container"> + <h1 class="header"><?php echo $this->title; ?></h1> + <form action=<?php echo '/preferred-loc/' . $this->user . '/edit'; ?> method="post"> + <table style="width:100%"> + <tr> + <th>No</th> + <th>Location</th> + <th>Actions</th> + </tr> + <?php + $count = 0; + foreach($this->prefLoc as $loc) { + $count = $count + 1; + echo "<tr class='rows'>"; + echo "<td id='count'>" . $count . "</td>"; + echo "<td><div name='location'>" . $loc['location'] . "</div></td>"; + echo "<td id='action'><img class=\"pref-button\" name=\"edit-button\" src='" . IMG . "/edit.png' /><a href='/preferred-loc/" . $this->user . "/delete/" . $loc['location'] . "'><img class=\"pref-button\" src='" . IMG . "/delete.png' /></td></a>"; + echo "</tr>"; + } + ?> + </table> + </form> + <form action=<?php echo '/preferred-loc/' . $this->user . '/finish'; ?> method='post' enctype="multipart/form-data"> + <div class="edit-profile-btm"> + <h2 class="header">Add new Location:</h2> + <div class="form-input"> + <input type="text" id="next-button-text" name="location" /> + <input class="next-button" type="submit" value="Add" /> + </div> + </div> + </form> +</div> +<script> + var edit = Array.prototype.slice.call(document.getElementsByName('edit-button')); + var locs = document.getElementsByName('location'); + var rows = document.getElementsByClassName('rows'); + + edit.map(function(x, i) { + var loc = locs[i].innerHTML; + x.addEventListener('click', function (event) { + event.preventDefault(); + rows[i].cells[1].innerHTML = '<input type="text" name="location_new" value="' + loc + '" /><input type="hidden" name="location_old" value="' + loc + '"/>'; + rows[i].cells[2].innerHTML = '<input type="submit" value="Save" />'; + }); + }); +</script> \ No newline at end of file diff --git a/src/app/Menu/Profile/EditProfile.routes.php b/src/app/Menu/Profile/EditProfile.routes.php new file mode 100644 index 0000000000000000000000000000000000000000..6879e668b63020cc81535a6e844007351552d0e8 --- /dev/null +++ b/src/app/Menu/Profile/EditProfile.routes.php @@ -0,0 +1,50 @@ +<?php + +namespace MotaRaido\Menu\Profile; + +use \MotaRaido\Core\View; +use \MotaRaido\Core\Route; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +Route::add('/editprofile/#user', function($user) use ($query) { + $view = new View(); + $view->assign('title', 'Edit Profile'); + $view->assign('image', IMG . $user); + $view->include('header', APPDIR . '/Menu/Header.php'); + + $usrData = $query->select('user', ['username' => $user]); + $view->assign('user', $user); + $view->assign('name', $usrData[0][2]); + $view->assign('phone', $usrData[0][3]); + if($usrData[0][4]){ + $view->assign('isDriver', 'checked'); + } + + $view->render(__DIR__ . '/EditProfile.view.php'); +}); + +Route::add('/editprofile/#user/finish', function($user) use ($query) { + $query->transaction(function() use ($query,$user) { + $name = $_POST['your-name']; + $phone = $_POST['phone-number']; + $isDriver = $_POST['is-driver']; + $image = $_FILES['image']; + $driverValue = isset($isDriver) ? 1 : 0; + header('Location: /profile/' . $user); + $query->update('user', ['fullname' => $name,'phone' => $phone, 'isDriver' => $driverValue], ['username' => $user]); + if(!empty($image['name'])){ + $image['name'] = $user; + $target = $_SERVER['DOCUMENT_ROOT'] . IMG . basename($image['name']); + if (move_uploaded_file($image['tmp_name'], $target)) { + echo "File is valid, and was successfully uploaded.\n"; + } else { + echo 'Failed to upload file\n'; + } + } + }); +}); \ No newline at end of file diff --git a/src/app/Menu/Profile/EditProfile.view.php b/src/app/Menu/Profile/EditProfile.view.php new file mode 100644 index 0000000000000000000000000000000000000000..0b6bbf0dc1fc2be8568b5bc1c4633188671b0325 --- /dev/null +++ b/src/app/Menu/Profile/EditProfile.view.php @@ -0,0 +1,45 @@ +<?php + +namespace MotaRaido\Menu\Profile; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + + +<?php echo $this->header; ?> +<div class="edit-profile-container"> + <form action='/editprofile/<?php echo $this->user; ?>/finish' method='post' onsubmit="return editProfileValidation();" enctype="multipart/form-data" name="editprofile-form"> + <h1 class="edit-profile-header">Edit Profile Information</h1> + <img id="profile-pic" src="<?php echo $this->image; ?>" alt=""> + <div class="img-chooser"> + <p>Update profile picture</p> + <input type="file" name="image" accept="image/jpeg, image/png"> + </div> + <div class="edit-profile-btm"> + <div class="form-editprofile"> + <label for="your-name">Your Name</label> + <input class="ep-textarea" type="text" name="your-name" value="<?php echo $this->name; ?>"> + </div> + <div class="form-editprofile"> + <label for="phone-number">Phone</label> + <input class="ep-textarea" type="text" name="phone-number" value="<?php echo $this->phone; ?>"> + </div> + <div class="button-form"> + <div> + Status driver + </div> + <label class="switch"> + <input type="checkbox" name="is-driver" <?php echo $this->isDriver; ?>> + <span class="slider round"></span> + </label> + </div> + <a href='/profile/<?php echo $this->user; ?>'><input class="cancel-button" value="Back"></a> + <input class="accept-button" id="save-profile" type="submit" value="Save"> + </div> + </form> +</div> \ No newline at end of file diff --git a/src/app/Menu/Profile/Profile.routes.php b/src/app/Menu/Profile/Profile.routes.php new file mode 100644 index 0000000000000000000000000000000000000000..8bd76c414947bdde5e17a463f91a2b321cd38b14 --- /dev/null +++ b/src/app/Menu/Profile/Profile.routes.php @@ -0,0 +1,54 @@ +<?php + +namespace MotaRaido\Menu\Profile; + +use \MotaRaido\Core\View; +use \MotaRaido\Core\Route; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +Route::add('/profile/#user', function($user) use ($query) { + $view = new View(); + $view->assign('title', 'Profile'); + $view->assign('user', $user); + $view->assign('image', IMG . $user); + $view->assign('edit', IMG . 'pen.png'); + $view->include('header', APPDIR . '/Menu/HeaderWithMenu.php'); + + $usrData = $query->select('user', ['username' => $user]); + $ratingData = $query->select('history', ['usernameDriver' => $user]); + $preferredLoc = $query->select('preferredloc', ['username' => $user]); + + $view->assign('username', $usrData[0][0]); + $view->assign('name', $usrData[0][2]); + $view->assign('phone', $usrData[0][3]); + if($usrData[0][4]){ + $view->assign('isdriver', 'Driver'); + } + $view->assign('email', $usrData[0][5]); + if ($ratingData) + { + $count = 0; + $amount = 0; + foreach($ratingData as $rating) { + $amount += $rating[2]; + $count++; + } + + $view->assign('rating', $amount / $count); + $view->assign('votes', $count); + } + if (count($preferredLoc) != 0) + { + $view->assign('preferredloc', $preferredLoc); + } + else + { + $view->assign('preferredloc', []); + } + $view->render(__DIR__ . '/Profile.view.php'); +}); \ No newline at end of file diff --git a/src/app/Menu/Profile/Profile.view.php b/src/app/Menu/Profile/Profile.view.php new file mode 100644 index 0000000000000000000000000000000000000000..bbfa6fdcc3d0821b71399934a41afa79f670155e --- /dev/null +++ b/src/app/Menu/Profile/Profile.view.php @@ -0,0 +1,59 @@ +<?php + +namespace MotaRaido\Menu\Profile; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + +<?php echo $this->header ?> +<div id="info-profile"> + <div class="subtitle-cont"> + <div class="subtitle-profile"> + MY PROFILE + </div> + <a href="/editprofile/<?php echo $this->user; ?>" > + <div id="edit-pen-div"> + <img class="edit-pen" src=<?php echo $this->edit; ?>> + </div> + </a> + </div> + <div id="profile-pic-div"> + <img class="profile-picture" src=<?php echo $this->image; ?>> + </div> + <div id="info-text"> + <ol id="list-info"> + <li><b><?php echo $this->username; ?></b></li> + <li><?php echo $this->name; ?></li> + <?php if($this->isdriver == 'Driver'): ?> + <li><?php echo $this->isdriver; ?> | <?php for($i = 0; $i<floor($this->rating); $i++) { echo "★"; } ?> (<?php echo $this->rating; ?> rating from <?php echo $this->votes; ?> votes)</li> + <?php endif; ?> + <li><?php echo $this->email; ?></i></li> + <li><?php echo $this->phone; ?></i></li> + </ol> + </div> +</div> +<div> + <div class="subtitle-cont"> + <?php if($this->isdriver == 'Driver'): ?> + <div id="prefer-loc-title" class="subtitle-profile"> + PREFERRED LOCATIONS: + </div> + <a href="/preferred-loc/<?php echo $this->user; ?>"> + <div id="edit-pen-div"> + <img class="edit-pen" src=<?php echo $this->edit; ?>> + </div> + </a> + </div> + <?php foreach ($this->preferredloc as $loc): ?> + <div id="info-pref-text"> + <span class="loc-list"><?php echo " " . $loc[1] ?><span> + </div> + <?php endforeach; ?> + <?php endif; ?> +</div> +<?php echo $this->footer; ?> \ No newline at end of file diff --git a/src/app/SignUp/Signup.routes.php b/src/app/SignUp/Signup.routes.php new file mode 100644 index 0000000000000000000000000000000000000000..f77ab5b6a59bdc2aaa5b2e0f52b769940dc0fc60 --- /dev/null +++ b/src/app/SignUp/Signup.routes.php @@ -0,0 +1,75 @@ +<?php + +namespace MotaRaido\SignUp; + +use \MotaRaido\Core\View; +use \MotaRaido\Core\Route; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +Route::add('/signup', function() { + $view = new View(); + $view->assign('title', 'Sign Up'); + $view->assign('style', CSS . "style.css"); + $view->assign('profileStyle', CSS . "profile.css"); + $view->assign('script', JS . "signup.js?time=" . date("H:i:s")); + $view->render(__DIR__ . '/SignUp.view.php', false); + +}); + +Route::add('/signup/validation', function() use ($query) { + // header('Location: /signup'); + $query->transaction(function() use ($query) { + $username = $_GET['username']; + if ($_GET['password'] === $_GET['confirm-password']) + $password = $_GET['password']; + else + $password = null; + $email = $_GET['email']; + $fullname = $_GET['your-name']; + $phone = $_GET['phone-number']; + $isdriver = isset($_GET['driver']) ? 1 : 0; + + $ratingArray['username'] = $_GET['username']; + $ratingArray['rating'] = 0; + $ratingArray['votes'] = 0; + $ratingArray['numrat'] = 0; + + $datauser = $query->select('user', ['username' => $username]); + + $preferredlocArray['username'] = $_GET['username']; + if ($password != null && count($datauser) == 0) + { + $query->insert('user', ['username' => $username, 'password'=> $password, 'email' => $email, 'fullname' => $fullname, 'phone' => $phone, 'isdriver' => $isdriver]); + $query->insert('rating', $ratingArray); + $query->insert('preferredloc', $preferredlocArray); + header('Location: /profile/' . $username); + } + }); +}); + +Route::add('/validation', function() use ($query) { + if(isset($_GET['email'])) + { + $email = $_GET['email']; + $emailData = $query->select('user', ['email' => $email]); + $found = count($emailData) !== 0; + } + else if(isset($_GET['username'])) + { + $username = $_GET['username']; + $usrData = $query->select('user', ['username' => $username]); + $found = count($usrData) !== 0; + } + + if($found) { + print_r('Failed'); + } else { + print_r('OK'); + } + +}); \ No newline at end of file diff --git a/src/app/SignUp/Signup.view.php b/src/app/SignUp/Signup.view.php new file mode 100644 index 0000000000000000000000000000000000000000..39a4ed288c229987aced0a84cd748978d82612eb --- /dev/null +++ b/src/app/SignUp/Signup.view.php @@ -0,0 +1,61 @@ +<?php + +namespace MotaRaido\SignUp; + +if (!defined('MOTAFW')) +{ + echo 'This file can only be called via the main index.php file, and not directly'; + exit(); +} + +?> + +<section class="content-layout"> + <header class="title"> + <div> + <hr> + <h1><?php echo $this->title; ?></h1> + <hr> + </div> + </header> + <section class="form-layout"> + <form action="/signup/validation" method="get" name="signupform" onsubmit="return signupValidation()"> + <div class="form-input"> + <div>Your Name</div> + <input id="your-name" type="text" name="your-name"> + </div> + <div class="form-input checked-input"> + <div>Username</div> + <input id="username" type="text" name="username" onKeyUp="checkData('username','username-check')"> + <span id="username-check"></span> + </div> + <div class="form-input checked-input"> + <div>Email</div> + <input id="email" type="text" name="email" onKeyUp="checkData('email','email-check')"> + <span id="email-check"></span> + </div> + <div class="form-input"> + <div>Password</div> + <input id="password" type="password" name="password"> + </div> + <div class="form-input"> + <div>Confirm Password</div> + <input id="confirm-password" type="password" name="confirm-password"> + </div> + <div class="form-input"> + <div>Phone Number</div> + <input id="phone" type="text" name="phone-number"> + </div> + <div class="driver-checkbox"> + <input id="isdriver" type="checkbox" name="driver"> + <div>Also sign me up as a driver!</div> + </div> + <div id="button-layout"> + <div> + <a href="/login">Already have an account</a> + </div> + <input id="register-button" type="submit" value="Register"> + </div> + </form> + </section> +</section> \ No newline at end of file diff --git a/src/index.php b/src/index.php new file mode 100644 index 0000000000000000000000000000000000000000..a58148aefd8f923b59ebc43d02cae300f41faa9d --- /dev/null +++ b/src/index.php @@ -0,0 +1,27 @@ +<?php + session_start(); + define("MOTAFW", true); + define("APPDIR", __DIR__ . '/app/'); + define("PUBLICDIR", '/public/'); + define("CSS", PUBLICDIR . 'css/'); + define("JS", PUBLICDIR . 'js/'); + define("IMG", PUBLICDIR . 'img/'); + + require_once __DIR__ . '/vendor/autoload.php'; + + use \MotaRaido\Core\Config; + use \MotaRaido\Core\Database\Connector; + use \MotaRaido\Core\Database\Query; + + $query = new Query(new Connector(Config::get('database'))); + + // include all routes + $dir = new RecursiveDirectoryIterator(APPDIR); + $iter = new RecursiveIteratorIterator($dir); + $files = new RegexIterator($iter, '/^.+\.routes\.php$/', RecursiveRegexIterator::GET_MATCH); // an Iterator, not an array + + foreach ( $files as $file ) { + foreach($file as $route_file) { + require_once $route_file; + } + } diff --git a/src/public/css/.gitkeep b/src/public/css/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/public/css/fonts/geo.woff2 b/src/public/css/fonts/geo.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..4c1d8680a68afc90ed228ae5c313f9002255b7b2 Binary files /dev/null and b/src/public/css/fonts/geo.woff2 differ diff --git a/src/public/css/fonts/mukta1.woff2 b/src/public/css/fonts/mukta1.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..dfa6d95388c06078e73dc1ccc0df0cdd8c152c4b Binary files /dev/null and b/src/public/css/fonts/mukta1.woff2 differ diff --git a/src/public/css/fonts/mukta2.woff2 b/src/public/css/fonts/mukta2.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..ed0d8a0451ef90b479b036e337f741573dfa55bb Binary files /dev/null and b/src/public/css/fonts/mukta2.woff2 differ diff --git a/src/public/css/fonts/mukta3.woff2 b/src/public/css/fonts/mukta3.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..b6d906226264df96ac57ba02427ae5043bfd031f Binary files /dev/null and b/src/public/css/fonts/mukta3.woff2 differ diff --git a/src/public/css/profile.css b/src/public/css/profile.css new file mode 100644 index 0000000000000000000000000000000000000000..7bf19a4f7d989ea396720a3c92bd8cb9cce368d7 --- /dev/null +++ b/src/public/css/profile.css @@ -0,0 +1,154 @@ +.profile-picture { + width: 150px; + height: 150px; + border: 5px solid black; + float: left; + border-radius: 500px; + clear: both; +} + +#info-profile { + margin: 20px 0px; + height: auto; +} + +.edit-pen { + float: right; + height: 30px; + +} + +.subtitle-profile { + float: left; + width: 200px; + font-size: 2em; + font-weight: bold; + font-family: 'Mutka', sans-serif; +} + +#profile-pic-div { + margin: auto; + width: 160px; + height: 160px; +} + +#edit-pen-div { + margin: auto; + height: auto; +} + +.subtitle-cont { + margin-bottom: 20px; + height: 37px; +} + +#info-text { + margin: auto; + font-size: 1.2em; +} + +#list-info { + list-style: none; + text-align: center; + padding: 0px; +} + +#prefer-loc-title { + font-size: 1.5em; + width: 400px; +} + +.fa-star-o{ + color: red; +} + +#info-pref-text { + font-size: 1.2em; +} + +.subtitle-history { + float: left; + font-size: 2em; + font-weight: bold; + font-family: 'Mutka', sans-serif; + margin-top: 20px; +} + +.history-pic-div { + width: 120px; + height: 120px; + margin: 0px 20px; + float: left; +} + +.profile-pic-his { + width: 110px; + height: 110px; + border: 1px solid black; + float: left; +} + +.history-list { + margin-top: 20px; + list-style: none; + padding: 0px; + height: auto; +} + +.order-list { + display: none; +} + +.driver-list { + display: none; +} + +.active-list { + display:block; +} + +.comment { + margin-left: 180px; +} + +.hide{ + width: auto; + padding: 10px 15px; + border: 1px solid black; + border-radius: 10px; + background-color: red; + position: absolute; + right: 0; +} + +.his-text>span { + display: inline-block; +} + +.list-text-his { + height: auto; + position: relative; + clear: both; +} + +.date-his { + color: gray; +} + +.name-his { + font-size: 1.2em; +} + +.tab-active { + display: block; +} + +.active { + color: #ffffff; + border-color: #000000; + background-color: #5A1E83; +} + +.hide-element { + display: none; +} \ No newline at end of file diff --git a/src/public/css/style.css b/src/public/css/style.css new file mode 100644 index 0000000000000000000000000000000000000000..ae7bb6a41858edde4cdc42187c4481c84a4a3473 --- /dev/null +++ b/src/public/css/style.css @@ -0,0 +1,628 @@ +@charset "UTF-8"; + +body { + width: 470px; + margin: auto; + font-family: 'Mutka', sans-serif; +} + +textarea { + resize: none; + width: 100%; + margin-bottom: 10px; +} + +/* Order Header */ + .progress-container { + width: fit-content; + border-collapse:separate; + border-spacing: 10px 10px; + display: table; + } + + .progress { + width: 30%; + height: 50px; + font-size: 105%; + border: 1px solid black; + text-align: left; + vertical-align: middle; + display: table-cell; + } + + .progress-num { + display:inline-block; + background-color: #DDD; + width: 35px; + height: 35px; + border-radius: 100%; + margin: 0px 5px; + line-height: 200%; + text-align: center; + vertical-align: middle; + float: left; + } + + .selected { + background-color: #FFFF44; + } + +/* Header style */ + +.header-box { + height: fit-content content-box; + width: fit-content content-box; + margin-left: auto; + margin-right: auto; + margin-top: none; + margin-bottom: none; + font-family: 'Mutka', sans-serif; + column-count: 2; + -moz-column-count: 2; + -webkit-column-count: 2; + -webkit-column-span: all; /* Chrome, Safari, Opera */ + column-span: all; + column-gap: 40px; +} + +.col-header-left { + width: 50% content-box; + float: left; + vertical-align: middle; +} + +.logo-title { + font-family: 'Geo', sans-serif; + font-weight: bold; + font-size: 250%; + color: #5A1E83; +} + +.tagline { + color: #311B92; +} + +.col-header-right { + width: 50% content-box; + float: right; + text-align: right; + vertical-align: middle; + line-height: 2; +} + +/* Menu style */ + +.menu { + width: 100%; + display: table; + table-layout: fixed; +} + +.menu > div.menu-column { + display: table-column; +} + +.menu > div.menu-cell { + display: table-cell; + font-family: 'Mukta', sans-serif; + vertical-align: middle; + line-height: 50px; + text-align: center; + font-weight: bold; + border-style: solid; + border-width: 1px; +} + +.menu > div:hover, .menu > div.selected { + color: #ffffff; + border-color: #000000; + background-color: #5A1E83; +} + +/* Footer style */ +.footer { + column-count: 3; + -moz-column-count: 3; + -webkit-column-count: 3; + -webkit-column-span: all; + column-span: all; + -moz-column-gap: 2em; + -webkit-column-gap: 2em; + column-gap: 1.5em; + column-rule-style: solid; + border-style: solid; + border-width: 2px; +} + +.footer > div { + width: fit-content content-box; + text-align: center; + font-weight: bold; + font-family: 'Mukta', sans-serif; + vertical-align: middle; +} + +.img-chooser { + padding-top: 20px; +} + +.text-link { + text-decoration: none; + font-size: 120%; + font-weight: bold; + color: black; +} + + + +/* Container */ +.container { + width: inherit; +} + +.header { + line-height: 1.5; + text-transform: uppercase; +} + +.selectdriver-header { + text-transform: uppercase; + font-weight: bold; +} + +.edit-profile-container { + font-family: Verdana; +} + +.edit-profile-header { + text-transform: uppercase; + font-weight: bold; + width: 100%; + font-size: 170%; +} + +.edit-profile-btm { + clear: both; +} + +.form-editprofile{ + margin: 5px 0; +} + +.ep-textarea{ + width: 60%; + float: right; + clear: both; +} + +.content-layout { + background-color: rgb(124, 206, 43); + padding: 50px; + border: 10px solid rgb(10, 127, 10); + border-radius: 100px; + width: 350px; +} + +.title { + height: 27px; + padding: 0px 20px; +} + +.title>div>h1 { + text-align: center; + margin-top: 0px; + width: 100px; + float: left; +} + +.title>div>hr { + float:left; + position: relative; + width: 100px; + top: 5px; + background-color: rgb(10, 127, 10); + height: 5px; + border: none; +} + +.form-layout { + clear: left; +} + +.form-input { + width: 350px; + margin-bottom: 5px; +} + +.form-input>div { + float: left; + width: 135px; +} + +.form-input>input { + width: 198px; +} + +.checked-input>input { + width: 170px; +} + +.driver-checkbox { + margin: 20px 0px; +} + +.driver-checkbox>input { + float: left; + margin-left: 0px; +} + + +.cancel-button { + width: 75px; + height: 30px; + text-align: center; + text-transform: uppercase; + letter-spacing: 1px; + border: 1px solid black; + background-color: #D2002E; + border-radius: 10px; +} + +.accept-button { + width: 75px; + height: 30px; + text-transform: uppercase; + letter-spacing: 1px; + border: 1px solid black; + background-color: #83D535; + border-radius: 10px; +} + +.driver-completeorder-pic { + height: 100px; + width: 100px; + margin: 10px; + border-radius: 100%; + border: 3px solid #5A1E83; +} + +.completeorder-container { + text-align: center; + clear: both; +} + +.right-align { + width: 100%; + text-align: right; +} + +.driver-fullname-disp { + font-size: 105%; + font-weight: bold; + margin-top: 5px; +} + +/*Select driver*/ +.select-driver { + width: auto; + padding: 0 10px; + border-radius: 12px; + border: 1px solid black; + margin: 10px 0; +} + +.driver-content { + height: 120px; + overflow: hidden; +} + +.driver-pic { + height: 100px; + width: 100px; + margin: 10px; + border-radius: 100%; + border: 3px solid #5A1E83; + float: left; +} + +.driver-name-disp { + font-size: 160%; + font-weight: bold; + margin-top: 10px; +} + +.driver-rating-disp { + color: orange; + font-size: 110%; +} + +.driver-not-found { + color: grey; + height: 70px; + text-align: center; + text-transform: none; + line-height: 70px; + vertical-align: middle; +} + +.vote-disp { + color: black; +} + +.select-driver-btn { + width: auto; + color: white; + background-color: #5A1E83; + letter-spacing: 0.5px; + float: right; +} + +.order-btn { + float: none; + clear: both; +} + +#profile-pic { + width: 150px; + height: 150px; + border: 1px solid black; + float: left; + margin-right: 25px; + margin-bottom: 30px; +} + +#save-profile { + float: right; + margin-right: 120px; +} + +#register-button { + background-color: #4CAF50; + border: 5px solid rgb(10, 127, 10); + border-radius: 20px; + color: white; + padding: 15px 32px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin: 4px 2px; + cursor: pointer; +} + +#button-layout>div { + float: left; + width: 200px; + height: 66px; +} + +#button-layout a { + position: relative; + top: 20px; +} + + +.button-form { + text-align: right; + width: 350px; +} + +.button-form div { + float: left; +} + +.completeorder-btn { + width: 100px; + height: 50px; + float: none; +} + + /* The switch - the box around the slider */ + .switch { + position: relative; + display: inline-block; + + width: 50px; + height: 25px; +} + +/* Hide default HTML checkbox */ +.switch input {display:none;} + +/* The slider */ +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + -webkit-transition: .4s; + transition: .4s; +} + +.slider:before { + position: absolute; + content: ""; + height: 19px; + width: 19px; + left: 4px; + bottom: 3px; + background-color: white; + -webkit-transition: .4s; + transition: .4s; +} + +input:checked + .slider { + background-color: #1E7B25; +} + +input:focus + .slider { + box-shadow: 0 0 1px #1E7B25; +} + +input:checked + .slider:before { + -webkit-transform: translateX(23px); + -ms-transform: translateX(23px); + transform: translateX(23px); +} + +/* Rounded sliders */ +.slider.round { + border-radius: 34px; +} + +.slider.round:before { + border-radius: 50%; +} + +/* Menu Order */ +.menu-order { + height: 100%; + width: 100%; + position: relative; + font-size: 12px; + border-spacing: 20px 12px; +} + +.menu-order-column { + height: 100%; +} + +.menu-order-cell { + display: table-cell; + position: relative; + text-align: left; + font-weight: bold; +} + +.menu-order-number +{ + position: relative; + display: block; + width: 50px; + height: 50px; + border-radius: 25px; /* or 50% */ + text-align: center; + margin-left: auto; + margin-right: auto; + background-color: #311B92; + color: #ffffff; + line-height: 50px; +} + +.menu-order-title +{ + position: relative; + display: inline-block; +} + +#next-button-text { + line-height: 20px; + width: 75%; + padding-right: 1px; +} + +input.next-button { + width: 20%; + height: 30px; + line-height: 20px; + text-transform: uppercase; + letter-spacing: 1px; + border: 1px solid black; + background-color: #83D535; + border-radius: 10px; + display: inline-block; +} + +table, th, td { + table-layout: auto !important; + width: 100% auto !important; + max-width:100%; + white-space:nowrap; + border: 1px solid black; + border-collapse: collapse; +} + +.pref-button { + width: 21px; + height: 21px; + vertical-align: middle; + border: none; + display: inline-block; +} + +/** Rating **/ +.starRating:not(old){ + display : inline-block; + width : 7.5em; + height : 1.5em; + overflow : hidden; + vertical-align : bottom; +} + +.starRating:not(old) > input{ + margin-right : -100%; + opacity : 0; +} + +.starRating:not(old) > label{ + display : block; + float : right; + position : relative; + background : url('../img/star-off.svg'); + background-size : contain; +} + +.starRating:not(old) > label:before{ + content : ''; + display : block; + width : 1.5em; + height : 1.5em; + background : url('../img/star-on.svg'); + background-size : contain; + opacity : 0; + transition : opacity 0.2s linear; +} + +.starRating:not(old) > label:hover:before, +.starRating:not(old) > label:hover ~ label:before, +.starRating:not(:hover) > :checked ~ label:before{ + opacity : 1; +} + +/* Font customization */ +/* latin */ +@font-face { + font-family: 'Geo'; + font-style: normal; + font-weight: 400; + src: local('Geo'), local('Geo-Regular'), url(./fonts/geo.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; +} + +/* devanagari */ +@font-face { + font-family: 'Mukta'; + font-style: normal; + font-weight: 400; + src: local('Mukta Regular'), local('Mukta-Regular'), url(./fonts/mukta1.woff2) format('woff2'); + unicode-range: U+02BC, U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200B-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB; +} +/* latin-ext */ +@font-face { + font-family: 'Mukta'; + font-style: normal; + font-weight: 400; + src: local('Mukta Regular'), local('Mukta-Regular'), url(./fonts/mukta1.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Mukta'; + font-style: normal; + font-weight: 400; + src: local('Mukta Regular'), local('Mukta-Regular'), url(./fonts/mukta1.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; +} diff --git a/src/public/css/style_old.css b/src/public/css/style_old.css new file mode 100644 index 0000000000000000000000000000000000000000..7ee8d5f20ad0ad8b49088c590ce18c398f09c1d8 --- /dev/null +++ b/src/public/css/style_old.css @@ -0,0 +1,614 @@ +@charset "UTF-8"; + +/* Font customization */ +/* latin */ +@font-face { + font-family: 'Geo'; + font-style: normal; + font-weight: 400; + src: local('Geo'), local('Geo-Regular'), url(./fonts/geo.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; +} + +/* devanagari */ +@font-face { + font-family: 'Mukta'; + font-style: normal; + font-weight: 400; + src: local('Mukta Regular'), local('Mukta-Regular'), url(./fonts/mukta1.woff2) format('woff2'); + unicode-range: U+02BC, U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200B-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB; +} +/* latin-ext */ +@font-face { + font-family: 'Mukta'; + font-style: normal; + font-weight: 400; + src: local('Mukta Regular'), local('Mukta-Regular'), url(./fonts/mukta1.woff2) format('woff2'); + unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Mukta'; + font-style: normal; + font-weight: 400; + src: local('Mukta Regular'), local('Mukta-Regular'), url(./fonts/mukta1.woff2) format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215; +} + +/* Body style */ + +body { + width: 470px; + margin: auto; + font-family: 'Mutka', sans-serif; +} + +textarea { + resize: none; + width: 100%; + margin-bottom: 10px; +} + +/* Order Header */ + .progress-container { + width: fit-content; + border-collapse:separate; + border-spacing: 10px 10px; + display: table; + } + + .progress { + width: 30%; + height: 50px; + font-size: 105%; + border: 1px solid black; + text-align: left; + vertical-align: middle; + display: table-cell; + } + + .progress-num { + display:inline-block; + background-color: #DDD; + width: 35px; + height: 35px; + border-radius: 100%; + margin: 0px 5px; + line-height: 200%; + text-align: center; + vertical-align: middle; + } + + .selected { + background-color: #FFFF44; + } + +/* Header style */ + +.header-box { + height: fit-content content-box; + width: fit-content content-box; + margin-left: auto; + margin-right: auto; + margin-top: none; + margin-bottom: none; + column-count: 2; + -moz-column-count: 2; + -webkit-column-count: 2; + -webkit-column-span: all; /* Chrome, Safari, Opera */ + column-span: all; + column-gap: 40px; +} + +.col-header-left { + width: 50% content-box; + float: left; + vertical-align: middle; +} + +.logo-title { + font-family: 'Geo', sans-serif; + font-weight: bold; + font-size: 250%; + color: #5A1E83; +} + +.tagline { + color: #311B92; +} + +.col-header-right { + width: 50% content-box; + float: right; + text-align: right; + vertical-align: middle; + line-height: 2; +} + +/* Menu style */ + +.menu { + width: 100%; + display: table; + table-layout: fixed; +} + +.menu > div.menu-column { + display: table-column; +} + +.menu > div.menu-cell { + display: table-cell; + font-family: 'Mukta', sans-serif; + vertical-align: middle; + line-height: 50px; + text-align: center; + font-weight: bold; + border-style: solid; + border-width: 1px; +} + +.menu-item:hover, .menu-item#selected { + color: #ffffff; + border-color: #000000; + background-color: #5A1E83; +} + +/* Footer style */ +.footer { + width: 100% fit-content; + display: inline-block; + column-count: 3; + column-span: all; + column-gap: 1.5em; + column-rule-style: solid; + border-style: solid; + border-width: 2px; + margin: auto; +} + +.footer > div { + text-align: center; + font-weight: bold; + font-family: 'Mukta', sans-serif; + vertical-align: middle; +} + +.img-chooser { + padding-top: 20px; +} + +/* Container */ +.container { + width: inherit; +} + +.header { + line-height: 1.5; + text-transform: uppercase; +} + +.selectdriver-header { + text-transform: uppercase; + font-weight: bold; +} + +.edit-profile-container { + font-family: Verdana; +} + +.edit-profile-header { + text-transform: uppercase; + font-weight: bold; + width: 100%; + font-size: 170%; +} + +.edit-profile-btm { + clear: both; +} + +.form-editprofile{ + margin: 5px 0; +} + + + +.ep-textarea{ + width: 60%; + float: right; + clear: both; +} + +.content-layout { + background-color: rgb(124, 206, 43); + padding: 50px; + border: 10px solid rgb(10, 127, 10); + border-radius: 100px; + width: 350px; +} + +.title { + height: 27px; + padding: 0px 20px; +} + +.title>div>h1 { + text-align: center; + margin-top: 0px; + width: 100px; + float: left; +} + +.title>div>hr { + float:left; + position: relative; + width: 100px; + top: 5px; + background-color: rgb(10, 127, 10); + height: 5px; + border: none; +} + +.form-layout { + clear: left; +} + +.form-input { + width: 350px; + margin-bottom: 5px; +} + +.form-input>div { + float: left; + width: 130px; +} + +.form-input>input { + width: 198px; +} + +.driver-checkbox { + margin: 20px 0px; +} + +.driver-checkbox>input { + float: left; + margin-left: 0px; +} + + +.cancel-button { + width: 75px; + height: 30px; + text-align: center; + text-transform: uppercase; + letter-spacing: 1px; + border: 1px solid black; + background-color: #D2002E; + border-radius: 10px; +} + +.accept-button { + width: 75px; + height: 30px; + text-transform: uppercase; + letter-spacing: 1px; + border: 1px solid black; + background-color: #83D535; + border-radius: 10px; +} + + +.driver-completeorder-pic { + height: 100px; + width: 100px; + margin: 10px; + border-radius: 100%; + border: 3px solid #5A1E83; +} + +.completeorder-container { + text-align: center; + clear: both; +} + +.right-align { + width: 100%; + text-align: right; +} + +.driver-fullname-disp { + font-size: 105%; + font-weight: bold; + margin-top: 5px; +} + +/*Select driver*/ +.select-driver { + width: fit-content; + padding: 0 10px; + border-radius: 12px; + border: 1px solid black; + margin: 10px 0; +} + +.driver-content { + height: 120px; + overflow: hidden; +} + +.driver-pic { + height: 100px; + width: 100px; + margin: 10px; + border-radius: 100%; + border: 3px solid #5A1E83; + float: left; +} + +.driver-name-disp { + font-size: 160%; + font-weight: bold; + margin-top: 10px; +} + +.driver-rating-disp { + color: orange; + font-size: 110%; +} + +.driver-not-found { + color: grey; + height: 70px; + text-align: center; + text-transform: none; + line-height: 70px; + vertical-align: middle; +} + +.vote-disp { + color: black; +} + +.select-driver-btn { + width: auto; + color: white; + background-color: #5A1E83; + letter-spacing: 0.5px; + float: right; +} + +.order-btn { + float: none; + clear: both; +} + +#profile-pic { + width: 150px; + height: 150px; + border: 1px solid black; + float: left; + margin-right: 25px; + margin-bottom: 30px; +} + +#save-profile { + float: right; +} + +#register-button { + background-color: #4CAF50; + border: 5px solid rgb(10, 127, 10); + border-radius: 20px; + color: white; + padding: 15px 32px; + text-align: center; + text-decoration: none; + display: inline-block; + font-size: 16px; + margin: 4px 2px; + cursor: pointer; +} + +#button-layout>div { + float: left; + width: 200px; + height: 66px; +} + +#button-layout a { + position: relative; + top: 20px; +} + + +.button-form { + text-align: right; + width: 100%; +} + +.button-form div { + float: left; +} + +.completeorder-btn { + width: 100px; + height: 50px; + float: none; +} + + /* The switch - the box around the slider */ + .switch { + position: relative; + display: inline-block; + + width: 50px; + height: 25px; +} + +/* Hide default HTML checkbox */ +.switch input {display:none;} + +/* The slider */ +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + -webkit-transition: .4s; + transition: .4s; +} + +.slider:before { + position: absolute; + content: ""; + height: 19px; + width: 19px; + left: 4px; + bottom: 3px; + background-color: white; + -webkit-transition: .4s; + transition: .4s; +} + +input:checked + .slider { + background-color: #1E7B25; +} + +input:focus + .slider { + box-shadow: 0 0 1px #1E7B25; +} + +input:checked + .slider:before { + -webkit-transform: translateX(23px); + -ms-transform: translateX(23px); + transform: translateX(23px); +} + +/* Rounded sliders */ +.slider.round { + border-radius: 34px; +} + +.slider.round:before { + border-radius: 50%; +} + +/* Menu Order */ +.menu-order { + height: 100%; + width: 100%; + position: relative; + font-size: 12px; + border-spacing: 20px 12px; +} + +.menu-order-column { + height: 100%; +} + +.menu-order-cell { + display: table-cell; + position: relative; + text-align: left; + font-weight: bold; +} + +.menu-order-number +{ + position: relative; + display: block; + width: 50px; + height: 50px; + border-radius: 25px; /* or 50% */ + text-align: center; + margin-left: auto; + margin-right: auto; + background-color: #311B92; + color: #ffffff; + line-height: 50px; +} + +.menu-order-title +{ + position: relative; + display: inline-block; +} + +#next-button-text { + line-height: 20px; + width: 75%; + padding-right: 1px; +} + +input.next-button { + width: 20%; + height: 30px; + line-height: 20px; + text-transform: uppercase; + letter-spacing: 1px; + border: 1px solid black; + background-color: #83D535; + border-radius: 10px; + display: inline-block; +} + +table, th, td { + table-layout: auto !important; + width: 100% auto !important; + max-width:100%; + white-space:nowrap; + border: 1px solid black; + border-collapse: collapse; +} + +.pref-button { + width: 21px; + height: 21px; + vertical-align: middle; + border: none; + display: inline-block; +} + +/** Rating **/ +.starRating:not(old){ + display : inline-block; + width : 7.5em; + height : 1.5em; + overflow : hidden; + vertical-align : bottom; +} + +.starRating:not(old) > input{ + margin-right : -100%; + opacity : 0; +} + +.starRating:not(old) > label{ + display : block; + float : right; + position : relative; + background : url('../img/star-off.svg'); + background-size : contain; +} + +.starRating:not(old) > label:before{ + content : ''; + display : block; + width : 1.5em; + height : 1.5em; + background : url('../img/star-on.svg'); + background-size : contain; + opacity : 0; + transition : opacity 0.2s linear; +} + +.starRating:not(old) > label:hover:before, +.starRating:not(old) > label:hover ~ label:before, +.starRating:not(:hover) > :checked ~ label:before{ + opacity : 1; +} diff --git a/src/public/img/.gitkeep b/src/public/img/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/public/img/a b/src/public/img/a new file mode 100644 index 0000000000000000000000000000000000000000..33aea4c0776f5cb48d23fab288743ca549d3092e Binary files /dev/null and b/src/public/img/a differ diff --git a/src/public/img/admin b/src/public/img/admin new file mode 100644 index 0000000000000000000000000000000000000000..dd3fea2721dfc529ad21300b36bada01e362032d Binary files /dev/null and b/src/public/img/admin differ diff --git a/src/public/img/delete.png b/src/public/img/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..f8998a18f10f6e0e754cdf3f06794b299e90a1b9 Binary files /dev/null and b/src/public/img/delete.png differ diff --git a/src/public/img/driver1 b/src/public/img/driver1 new file mode 100644 index 0000000000000000000000000000000000000000..8de4beb39862ac7125f2339dcb1c9b32ab7f90f8 Binary files /dev/null and b/src/public/img/driver1 differ diff --git a/src/public/img/edit.png b/src/public/img/edit.png new file mode 100644 index 0000000000000000000000000000000000000000..919913bc0052626f61433d69128dc17ac739450b Binary files /dev/null and b/src/public/img/edit.png differ diff --git a/src/public/img/images.jpg b/src/public/img/images.jpg new file mode 100644 index 0000000000000000000000000000000000000000..30b7ce2cd13386017b2fa5d56503d42e4c25ea1d Binary files /dev/null and b/src/public/img/images.jpg differ diff --git a/src/public/img/motaraido.png b/src/public/img/motaraido.png new file mode 100644 index 0000000000000000000000000000000000000000..2b72f7e2abdd5f8ea4d11911d7c6ad9260be5262 Binary files /dev/null and b/src/public/img/motaraido.png differ diff --git a/src/public/img/pen.png b/src/public/img/pen.png new file mode 100644 index 0000000000000000000000000000000000000000..d2bcdf9ca880be6a8d6d687245ec080d4d711240 Binary files /dev/null and b/src/public/img/pen.png differ diff --git a/src/public/img/profilepic.png b/src/public/img/profilepic.png new file mode 100644 index 0000000000000000000000000000000000000000..2b72f7e2abdd5f8ea4d11911d7c6ad9260be5262 Binary files /dev/null and b/src/public/img/profilepic.png differ diff --git a/src/public/img/star-off.svg b/src/public/img/star-off.svg new file mode 100755 index 0000000000000000000000000000000000000000..9a393aa40d139025bf2324aec47830757facb84a --- /dev/null +++ b/src/public/img/star-off.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"> + <path fill="#fff" stroke="#ccc" d="M 12,2.5 14.4,9.5 21.5,9.5 15.8,13.75 18.5,21.5 12,16.625 5.5,21.5 8.2,13.75 2.5,9.5 9.6,9.5 z"/> +</svg> diff --git a/src/public/img/star-on.svg b/src/public/img/star-on.svg new file mode 100755 index 0000000000000000000000000000000000000000..fac31ff43ec2ba8dff2f36a3b0ae43d92b312533 --- /dev/null +++ b/src/public/img/star-on.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"> + <path fill="#311B92" stroke="#000" d="M 12,2.5 14.4,9.5 21.5,9.5 15.8,13.75 18.5,21.5 12,16.625 5.5,21.5 8.2,13.75 2.5,9.5 9.6,9.5 z"/> +</svg> diff --git a/src/public/img/tes1 b/src/public/img/tes1 new file mode 100644 index 0000000000000000000000000000000000000000..7352b27d5a4202c3849d34614463b6e94eee7285 Binary files /dev/null and b/src/public/img/tes1 differ diff --git a/src/public/img/winarto b/src/public/img/winarto new file mode 100644 index 0000000000000000000000000000000000000000..33aea4c0776f5cb48d23fab288743ca549d3092e Binary files /dev/null and b/src/public/img/winarto differ diff --git a/src/public/img/yowinarto b/src/public/img/yowinarto new file mode 100644 index 0000000000000000000000000000000000000000..8de4beb39862ac7125f2339dcb1c9b32ab7f90f8 Binary files /dev/null and b/src/public/img/yowinarto differ diff --git a/src/public/js/.gitkeep b/src/public/js/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/public/js/app.js b/src/public/js/app.js new file mode 100644 index 0000000000000000000000000000000000000000..dbea0f5c367dec9b0cb20f3b11c4ce40644838a3 --- /dev/null +++ b/src/public/js/app.js @@ -0,0 +1,102 @@ +function loginValidation() { + var username = document.forms["loginform"]["username"]; + var pwd = document.forms["loginform"]["password"]; + var usrVerify = Validate(username, "empty"); + var pwdVerify = Validate(pwd, "empty"); + return (usrVerify && pwdVerify); +} + +function editProfileValidation() { + var name = document.forms["editprofile-form"]["your-name"]; + var phone = document.forms["editprofile-form"]["phone-number"]; + var nameVerify = Validate(name, "empty", 0, 20, "length"); + var phoneVerify = Validate(phone, "empty", 9, 12, "length"); + return (nameVerify && phoneVerify); +} + +function Validate(inputArea, type1, min = 0, max = 0, type2 = null, type3 = null) { + var error = GetErrorMessage(inputArea.value, type1, min, max); + if(error === "") { + if (type2 != null) { + error = GetErrorMessage(inputArea.value, type2, min, max); + console.log(type2 + "length"); + } + if (error === "") { + if (type3 != null) { + error = GetErrorMessage(inputArea.value, type3, min, max); + } + } + } + if(error !== "" && inputArea.nextElementSibling === null) { + var errorEl = document.createElement("p"); + errorEl.innerHTML = error; + errorEl.className = "error"; + insertAfterElement(errorEl, inputArea); + + inputArea.addEventListener("blur", function() { + var error = GetErrorMessage(inputArea.value, type1, min, max); + if(error === "") { + if (type2 != null) { + error = GetErrorMessage(inputArea.value, type2, min, max); + } + if (error === "") { + if (type3 != null) { + error = GetErrorMessage(inputArea.value, type3, min, max); + } + } + } + if (error === ""){ + this.nextSibling.remove(); + } + },true); + } + return (error === ""); +} + +function insertAfterElement(el, src) { + src.parentNode.insertBefore(el, src.nextSibling); +} + + +function GetErrorMessage(textArea, type, min = 0, max = 0) { + var validateText = ""; + switch(type) { + case "empty" : + if(isEmpty(textArea)) { + validateText = "Fill in the field"; + } + break; + case "email" : + if(!isEmail(textArea)) { + validatedText = "Invalid Email Address"; + } + break; + case "number" : + if(isNumber(textArea)){ + validateText = "Fill in with only number"; + } + break; + case "length" : + if (!isLengthEqual(textArea,min,max)){ + validateText = "Character must be between " + min.toString() + " and " + max.toString() + " long"; + } + break; + } + return validateText; +} + +function isEmpty(textArea) { + return (textArea.match(/^s+$/) || textArea == ""); +} + +function isNumber(textArea) { + return (!isNaN(textArea)); +} + +function isLengthEqual(textArea, min, max){ + return (textArea.length >= min && textArea.length <= max); +} + +function isEmail(textArea) { + return (textArea.match(/^([a-zA-Z0-9])+([.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-]+)+/)); +} \ No newline at end of file diff --git a/src/public/js/history.js b/src/public/js/history.js new file mode 100644 index 0000000000000000000000000000000000000000..4e4b3f528dfb96a699cdbb10ad6ba0b731005f5a --- /dev/null +++ b/src/public/js/history.js @@ -0,0 +1,41 @@ + +function tabActive(tag) { + var tabUser = document.getElementById('user-his'); + var tabDriver = document.getElementById('driver-his'); + var order = document.getElementsByClassName('order-list'); + var driver = document.getElementsByClassName('driver-list'); + + if (tag == 'user') { + order[0].classList.add("active-list"); + driver[0].classList.remove("active-list"); + tabUser.classList.add('active'); + tabDriver.classList.remove('active'); + } + else { + driver[0].classList.add("active-list"); + order[0].classList.remove("active-list"); + tabDriver.classList.add('active'); + tabUser.classList.remove('active'); + } +} + +tabActive('user'); + +function hideThis(user) { + updateHide(user); + console.log(user[0]); +} + +function updateHide(history) +{ + var data = "user=" + history[0] + "&driver=" + history[1] + "&date=" + history[4]; + var xhr; + if (window.XMLHttpRequest) { + xhr = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + xhr = new ActiveXObject("Microsoft.XMLHTTP"); + } + xhr.open("GET", "/history/update", true); + xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + xhr.send(data); +} \ No newline at end of file diff --git a/src/public/js/selectdriver.js b/src/public/js/selectdriver.js new file mode 100644 index 0000000000000000000000000000000000000000..2d7b38f4833461051ad76f37a3eac112a88b0156 --- /dev/null +++ b/src/public/js/selectdriver.js @@ -0,0 +1,97 @@ +var prefDriver = document.getElementById("pref-driver"); +var otherDriver = document.getElementById("other-driver"); +var driverSumRating = []; +var driverCountRating = []; +var driverNameList = []; + +for (var i = 0; i < driverArr.length; i++) { + for(var j = 0; j < ratingArr.length; j++) { + if(driverArr[i] === ratingArr[j]["usernameDriver"]){ + driverSumRating[driverArr[i]] = (driverSumRating[driverArr[i]] === undefined) ? parseFloat(ratingArr[j]["rating"]) : driverSumRating[driverArr[i]] + parseFloat(ratingArr[j]["rating"]); + driverCountRating[driverArr[i]] = (driverCountRating[driverArr[i]] === undefined) ? 1 : driverCountRating[driverArr[i]]+1; + } + } + for(var k = 0; k < driverNameArr.length; k++) { + if(driverArr[i] === driverNameArr[k]["username"]){ + driverNameList[driverArr[i]] = driverNameArr[k]["fullname"]; + break; + } + } +} + +for(var j = 0; j < ratingArr.length; j++) { + if(preferredDriver === ratingArr[j]["usernameDriver"]){ + driverSumRating[preferredDriver] = (driverSumRating[preferredDriver] === undefined) ? parseFloat(ratingArr[j]["rating"]) : driverSumRating[preferredDriver] + parseFloat(ratingArr[j]["rating"]); + driverCountRating[preferredDriver] = (driverCountRating[preferredDriver] === undefined) ? 1 : driverCountRating[preferredDriver]+1; + } +} +for(var k = 0; k < driverNameArr.length; k++) { + if(preferredDriver === driverNameArr[k]["username"]){ + driverNameList[preferredDriver] = driverNameArr[k]["fullname"]; + break; + } +} + +if(preferredDriver !== "") { + CreateDriverDisplay(prefDriver, preferredDriver); +} else { + CreateNotFoundDisplay(prefDriver); +} + +if(driverArr.length > 0) { + for (var i = 0; i < driverArr.length; i++) { + CreateDriverDisplay(otherDriver, driverArr[i]); + } +} else { + CreateNotFoundDisplay(otherDriver); +} + +function CreateDriverDisplay(driverType, driverUsrName) { + var newForm = driverType.appendChild(document.createElement("form")); + var newContainer = newForm.appendChild(document.createElement("div")); + var newImg = newContainer.appendChild(document.createElement("img")); + var newName = newContainer.appendChild(document.createElement("div")); + var newRating = newContainer.appendChild(document.createElement("div")); + var postUsrName = newContainer.appendChild(document.createElement("input")); + var newPickLoc = newContainer.appendChild(document.createElement("input")); + var newDest = newContainer.appendChild(document.createElement("input")); + var newBtn = newContainer.appendChild(document.createElement("input")); + + + var avgRating = (driverSumRating[driverUsrName]/driverCountRating[driverUsrName]).toFixed(1).toString(); + + newForm.setAttribute('method', 'post'); + newForm.setAttribute('action', '/order/' + user + '/completeorder'); + newContainer.classList.add("driver-content"); + + newImg.classList.add("driver-pic"); + newImg.setAttribute('src', '/public/img/' + driverUsrName); + + newName.classList.add("driver-name-disp"); + newName.innerHTML = driverNameList[driverUsrName]; + + newRating.classList.add("driver-rating-disp"); + newRating.innerHTML = "★" + avgRating + " <span class='vote-disp'>(" + driverCountRating[driverUsrName] + " votes)</span>"; + + postUsrName.setAttribute('type', 'hidden'); + postUsrName.setAttribute('name', 'driver-username'); + postUsrName.setAttribute('value', driverUsrName); + + newPickLoc.setAttribute('type','hidden'); + newPickLoc.setAttribute('name','pickLoc'); + newPickLoc.setAttribute('value', pickLoc); + newDest.setAttribute('type','hidden'); + newDest.setAttribute('name','dest'); + newDest.setAttribute('value', dest); + + newBtn.classList.add("accept-button"); + newBtn.classList.add("select-driver-btn"); + newBtn.setAttribute('type','submit'); + newBtn.setAttribute('value','Select Driver'); +} + +function CreateNotFoundDisplay(driverType) { + var newContainer = driverType.appendChild(document.createElement("div")); + newContainer.classList.add("driver-not-found"); + newContainer.innerHTML = "Nothing to display."; +} \ No newline at end of file diff --git a/src/public/js/signup.js b/src/public/js/signup.js new file mode 100644 index 0000000000000000000000000000000000000000..43a9342a95538b30e1b8bf663cf3fc0a0b62718f --- /dev/null +++ b/src/public/js/signup.js @@ -0,0 +1,44 @@ +function checkData(name, element) +{ + var data = "?" + name + "=" + document.forms["signupform"][name].value; + var xhr; + if (window.XMLHttpRequest) { + xhr = new XMLHttpRequest(); + } else if (window.ActiveXObject) { + xhr = new ActiveXObject("Microsoft.XMLHTTP"); + } + + xhr.open("GET", "/validation" + data, true); + xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); + xhr.send(null); + xhr.onload = function() { + if (xhr.readyState == 4) { + if (xhr.status == 200) { + if (xhr.responseText === 'OK') { + document.getElementById(element).innerHTML = "√"; + } else { + document.getElementById(element).innerHTML = "X"; + } + } + else { + alert('There was a problem with the request.'); + } + } + } +} + +function signupValidation() { + var username = document.forms["signupform"]["username"]; + var password = document.forms["signupform"]["password"]; + var cpassword = document.forms["signupform"]["confirm-password"]; + var email = document.forms["signupform"]["email"]; + var fullname = document.forms["signupform"]["your-name"]; + var phone = document.forms["signupform"]["phone"]; + var usrVerify = Validate(username, "empty"); + var pwdVerify = Validate(password, "empty"); + var cpwdVerify = Validate(cpassword, "empty"); + var emailVerify = Validate(email, "empty", 0, 0, "email"); + var fullnameVerify = Validate(fullname, "empty", 0, 20, "length"); + var phoneVerify = Validate(phone, "empty", 9, 12, "length"); + return (usrVerify && pwdVerify && cpwdVerify && emailVerify && fullnameVerify && phoneVerify); +} \ No newline at end of file diff --git a/src/vendor/autoload.php b/src/vendor/autoload.php new file mode 100644 index 0000000000000000000000000000000000000000..530b760cf2fed5f40f9d6e1458980c1715bcfc96 --- /dev/null +++ b/src/vendor/autoload.php @@ -0,0 +1,21 @@ +<?php +spl_autoload_register(function ($class) { + + $prefix = 'MotaRaido\\'; + + $base_dir = APPDIR; + + $len = strlen($prefix); + if (strncmp($prefix, $class, $len) !== 0) { + return; + } + + $relative_class = substr($class, $len); + + $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; + + if (file_exists($file)) { + require_once $file; + } +}); +