From 26205df4cf1855f43a340ac8af2146db6433f8ab Mon Sep 17 00:00:00 2001 From: cuqmbr <52876496+cuqmbr@users.noreply.github.com> Date: Tue, 22 Feb 2022 12:00:53 +0200 Subject: [PATCH] Initial & last commit --- bills.sql | 180 +++++++++++++++++++++++++++++++++++ book.php | 95 +++++++++++++++++++ connection.php | 12 +++ createbook.php | 95 +++++++++++++++++++ css/book.css | 74 +++++++++++++++ css/createbook.css | 85 +++++++++++++++++ css/index.css | 69 ++++++++++++++ css/profile.css | 148 +++++++++++++++++++++++++++++ css/receipt.css | 105 ++++++++++++++++++++ css/sign.css | 79 ++++++++++++++++ elements/footer.php | 34 +++++++ elements/header.php | 151 +++++++++++++++++++++++++++++ functions.php | 1 + head.php | 36 +++++++ img/icon.png | Bin 0 -> 22504 bytes img/logo.png | Bin 0 -> 13453 bytes index.php | 59 ++++++++++++ js/dragndrop.js | 38 ++++++++ login.php | 79 ++++++++++++++++ logout.php | 10 ++ profile.php | 226 ++++++++++++++++++++++++++++++++++++++++++++ receipt.js | 28 ++++++ receipt.php | 156 ++++++++++++++++++++++++++++++ remove_book.php | 27 ++++++ remove_receipt.php | 28 ++++++ remove_user.php | 28 ++++++ sign_up.php | 106 +++++++++++++++++++++ 27 files changed, 1949 insertions(+) create mode 100644 bills.sql create mode 100644 book.php create mode 100644 connection.php create mode 100644 createbook.php create mode 100644 css/book.css create mode 100644 css/createbook.css create mode 100644 css/index.css create mode 100644 css/profile.css create mode 100644 css/receipt.css create mode 100644 css/sign.css create mode 100644 elements/footer.php create mode 100644 elements/header.php create mode 100644 functions.php create mode 100644 head.php create mode 100644 img/icon.png create mode 100644 img/logo.png create mode 100644 index.php create mode 100644 js/dragndrop.js create mode 100644 login.php create mode 100644 logout.php create mode 100644 profile.php create mode 100644 receipt.js create mode 100644 receipt.php create mode 100644 remove_book.php create mode 100644 remove_receipt.php create mode 100644 remove_user.php create mode 100644 sign_up.php diff --git a/bills.sql b/bills.sql new file mode 100644 index 0000000..173a308 --- /dev/null +++ b/bills.sql @@ -0,0 +1,180 @@ +-- phpMyAdmin SQL Dump +-- version 4.9.7deb1 +-- https://www.phpmyadmin.net/ +-- +-- Host: localhost:3306 +-- Generation Time: Aug 05, 2021 at 02:05 PM +-- Server version: 8.0.26-0ubuntu0.21.04.3 +-- PHP Version: 7.4.16 + +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: `bills` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `Books` +-- + +CREATE TABLE `Books` ( + `book_id` int NOT NULL, + `owner_id` int DEFAULT NULL, + `account` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `name` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `adress` varchar(255) COLLATE utf8_bin DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- +-- Dumping data for table `Books` +-- + +INSERT INTO `Books` (`book_id`, `owner_id`, `account`, `name`, `adress`) VALUES +(8, 6, '00000295', 'Газ', 'Ул. Шевченко'), +(10, 6, '149', 'Вода', 'Ул. Шевченко'), +(23, 21, 'хз', 'Свет', 'Шевченко'), +(24, 21, 'хз', 'Свет', 'Шевченко'), +(36, 19, '10810', 'Водоснабжение', 'Титова'), +(37, 19, '6263', 'Газоснабжение', 'Титова'), +(38, 19, '770333066', 'Электроенегрия', 'Титова'), +(42, 19, '1', 'Кавун', '1'), +(43, 19, '1', 'Дыня', '1'); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `Receipts` +-- + +CREATE TABLE `Receipts` ( + `receipt_id` int NOT NULL, + `book_id` int DEFAULT NULL, + `start_date` date DEFAULT NULL, + `final_date` date DEFAULT NULL, + `start_num` int DEFAULT NULL, + `final_num` int DEFAULT NULL, + `rate` float DEFAULT NULL, + `comment` varchar(255) COLLATE utf8_bin DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- +-- Dumping data for table `Receipts` +-- + +INSERT INTO `Receipts` (`receipt_id`, `book_id`, `start_date`, `final_date`, `start_num`, `final_num`, `rate`, `comment`) VALUES +(47, 8, '2021-07-19', '2021-08-16', 1111, 1121, 8.99, 'Благодарю'), +(57, 24, '2021-06-21', '2021-07-21', 4200, 4300, 1.68, ''), +(90, 37, '2021-05-01', '2021-05-31', 2422, 2429, 8.99, ''), +(91, 37, '2021-06-01', '2021-06-30', 2429, 2436, 8.99, ''), +(92, 38, '2021-05-01', '2021-05-31', 18688, 18965, 1.68, ''), +(94, 38, '2021-06-01', '2021-06-30', 18965, 19260, 1.68, ''), +(96, 36, '2021-05-01', '2021-05-31', 1064, 1074, 2.17, ''), +(97, 36, '2021-06-01', '2021-06-30', 1074, 1086, 2.17, ''), +(101, 37, '2021-07-01', '2021-07-31', 2436, 2443, 8.99, ''), +(106, 38, '2021-07-01', '2021-07-31', 19260, 19550, 1.68, ''), +(108, 8, '2021-08-03', '2021-06-30', 12, 18, 8, ''), +(109, 10, '2021-06-01', '2021-06-30', 12, 15, 22, ''), +(110, 42, '2021-07-01', '2021-07-31', 0, 100, 3.99, ''), +(111, 43, '2021-06-01', '2021-06-30', 0, 100, 4, ''); + +-- -------------------------------------------------------- + +-- +-- Table structure for table `Users` +-- + +CREATE TABLE `Users` ( + `user_id` int NOT NULL, + `create_time` datetime DEFAULT CURRENT_TIMESTAMP, + `username` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `email` varchar(255) COLLATE utf8_bin DEFAULT NULL, + `password` varchar(128) COLLATE utf8_bin DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin; + +-- +-- Dumping data for table `Users` +-- + +INSERT INTO `Users` (`user_id`, `create_time`, `username`, `email`, `password`) VALUES +(6, '2021-07-19 13:32:44', 'tatyana', 'email@gmail.com', 'password hash'), +(19, '2021-07-20 21:33:35', 'Данил', 'dr.juniorf@gmail.com', '$2y$10$pvUpTNEwt$@#@35sdfAwtvhSJcCSMcSsadfhg..UK.GnTd6vhzGg6ZJsdfhAigJU7GjjPqpEkzuB3G'), +(21, '2021-07-21 11:47:47', 'Aliona', 'lola.lolina96@gmail.com', '$2y$10$Dbxo42/yRcikL1TudfsjdfgjASDFX2tSK.SFG.aTasdfSBRqmTEjKU5nVkASDFHSDGJuYTeFLywV/Z3dY4ca'); + +-- +-- Indexes for dumped tables +-- + +-- +-- Indexes for table `Books` +-- +ALTER TABLE `Books` + ADD PRIMARY KEY (`book_id`), + ADD KEY `owner_id` (`owner_id`); + +-- +-- Indexes for table `Receipts` +-- +ALTER TABLE `Receipts` + ADD PRIMARY KEY (`receipt_id`), + ADD KEY `Receipts_ibfk_1` (`book_id`); + +-- +-- Indexes for table `Users` +-- +ALTER TABLE `Users` + ADD PRIMARY KEY (`user_id`), + ADD UNIQUE KEY `email` (`email`); + +-- +-- AUTO_INCREMENT for dumped tables +-- + +-- +-- AUTO_INCREMENT for table `Books` +-- +ALTER TABLE `Books` + MODIFY `book_id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=44; + +-- +-- AUTO_INCREMENT for table `Receipts` +-- +ALTER TABLE `Receipts` + MODIFY `receipt_id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=112; + +-- +-- AUTO_INCREMENT for table `Users` +-- +ALTER TABLE `Users` + MODIFY `user_id` int NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=22; + +-- +-- Constraints for dumped tables +-- + +-- +-- Constraints for table `Books` +-- +ALTER TABLE `Books` + ADD CONSTRAINT `Books_ibfk_1` FOREIGN KEY (`owner_id`) REFERENCES `Users` (`user_id`) ON DELETE CASCADE; + +-- +-- Constraints for table `Receipts` +-- +ALTER TABLE `Receipts` + ADD CONSTRAINT `Receipts_ibfk_1` FOREIGN KEY (`book_id`) REFERENCES `Books` (`book_id`) 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/book.php b/book.php new file mode 100644 index 0000000..55e173c --- /dev/null +++ b/book.php @@ -0,0 +1,95 @@ + 0) { + + while($row = mysqli_fetch_assoc($book_data)) { + $book_name = $row['name']; + $book_adress = $row['adress']; + } + } + + #Validate ownership + $link_user_id = $_GET['user_id']; + $session_user_id = $_SESSION['user_id']; + + if ($link_user_id != $session_user_id) { + header("Location: index.php"); + } + +?> + + + + + + +
+ + На главную + +

+

+ +
+ + + +
+ + +
+ + +
+

Запись №'.$receipt_num.'

+

'.date("d.m.Y", strtotime($row[1])).' - '.date("d.m.Y", strtotime($row[2])).'

+ Посмотреть / Изменить +
+
'; + } + } + + + ?> + + + +
+ + + + + + \ No newline at end of file diff --git a/connection.php b/connection.php new file mode 100644 index 0000000..244ac57 --- /dev/null +++ b/connection.php @@ -0,0 +1,12 @@ + + + + + + + +
+
+ +

Создать книжку

+ +
* обязательное поле
+
+ + +
+
+ + +
+
+ + +
+
+ + +

+ + Назад +
+
+ + + + \ No newline at end of file diff --git a/css/book.css b/css/book.css new file mode 100644 index 0000000..79aa492 --- /dev/null +++ b/css/book.css @@ -0,0 +1,74 @@ +/* ****CONTENT**** */ +.content { + padding: 20px 20px 20px 20px; + + min-height: calc(100% - 242px); + + text-align: center; +} + + +h2 { + margin-bottom: 0px; +} + +h3 { + margin-bottom: 0px; +} + +.card-wrapper { + padding: 20px 0px 20px 0px; +} + +.card { + background-color: #D3DCE3; + + width: 300px; + height: 200px; + + display: inline-block; + vertical-align: top; + + margin: 1rem; + + border: 1px solid #aaa; + border-radius: 3px; + box-shadow: 1px 1px 2px #fff inset; +} + +/* FILLED CARD */ +.card-content-wrapper { + position: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +/* EMPTY CARD */ +.add-btn { + background-color: #235A81; + + width: 60px; + height: 60px; + + border: 1px solid #235A81; + border-radius: 30px; + + position: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + + display: grid; + text-align: center; + align-items: center; + + text-decoration: none; + color: #fff; + text-shadow: 0.5px 0.5px 0.5px #444; + font-size: 35px; +} + +.add-btn:hover { + background-color: #1f4f72; +} \ No newline at end of file diff --git a/css/createbook.css b/css/createbook.css new file mode 100644 index 0000000..e39e1ab --- /dev/null +++ b/css/createbook.css @@ -0,0 +1,85 @@ +.content { + padding: 20px 20px 20px 20px; + + height: calc(100% - 242px); +} + +.form { + background-color: #D3DCE3; + min-width: 300px; + max-width: 400px; + + position: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + + padding: 5px 20px 20px 20px; + + border: 1px solid #aaa; + border-radius: 3px; + + box-shadow: 1px 1px 2px #fff inset; + + text-align: center; + + z-index: 99; +} + +.form_title { + text-align: center; +} + +.input { + transition-duration: 0.3s; + + background-color: #fff; + + margin: 10px 0px 5px 0px; + width: 100%; + height: 30px; + + outline: none; + border: 1px solid #aaa; + border-radius: 3px; + + font-size: 15px; +} + +.input:hover, .input:focus { + transition-duration: 0.3s; + + outline: none; + box-shadow: 0px 0.1px 2px 0.1px #444444; +} + +.submit_button { + background-color: #235A81; + + margin: 5px 0px 0px 0px; + width: 100%; + height: 32px; + + border: 1px solid #aaa; + border-radius: 3px; + + cursor: pointer; + + color: #fff; + text-shadow: 0.5px 0.5px 0.5px #444; + font-size: 15px; +} + +.submit_button:hover { + background-color: #1f4f72; +} + +.link { + color: #235A81; +} + +.error { + margin: 0px; + + color: #235A81; +} \ No newline at end of file diff --git a/css/index.css b/css/index.css new file mode 100644 index 0000000..6b591ad --- /dev/null +++ b/css/index.css @@ -0,0 +1,69 @@ +/* ****CONTENT**** */ +.content { + padding: 20px 20px 20px 20px; + + text-align: center; + + min-height: calc(100% - 242px); +} + +.card { + background-color: #D3DCE3; + + width: 300px; + height: 500px; + + display: inline-block; + vertical-align: top; + + margin: 1rem; + + border: 1px solid #aaa; + border-radius: 3px; + box-shadow: 1px 1px 2px #fff inset; +} + +.card.dragging { + opacity: 0.5; +} + +/* FILLED CARD */ +.card-content-wrapper { + position: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +/* EMPTY CARD */ +.add-btn { + background-color: #235A81; + + width: 60px; + height: 60px; + + border: 1px solid #235A81; + border-radius: 30px; + + position: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + + display: grid; + text-align: center; + align-items: center; + + text-decoration: none; + color: #fff; + text-shadow: 0.5px 0.5px 0.5px #444; + font-size: 35px; +} + +.add-btn:hover { + background-color: #1f4f72; +} + +.link { + color: #235A81; +} \ No newline at end of file diff --git a/css/profile.css b/css/profile.css new file mode 100644 index 0000000..a817bca --- /dev/null +++ b/css/profile.css @@ -0,0 +1,148 @@ +.form { + /*background-color: #D3DCE3;*/ + min-width: 200px; + max-width: 400px; + + position: relative; + left: 50%; + transform: translate(-50%, 0%); + + padding: 5px 20px 20px 20px; + margin: 0px; + + /*border: 1px solid #aaa; + border-radius: 3px; + + box-shadow: 1px 1px 2px #fff inset;*/ + + z-index: 99; +} + +.title { + padding: 0; +} + +.input { + transition-duration: 0.3s; + + background-color: #fff; + + margin: 10px 0px 5px 0px; + width: 75%; + height: 30px; + + outline: none; + border: 1px solid #aaa; + border-radius: 3px; + + font-size: 15px; +} + +.input:hover, .input:focus { + transition-duration: 0.3s; + + outline: none; + box-shadow: 0px 0.1px 2px 0.1px #444444; +} + +.submit_button { + background-color: #235A81; + + margin: 10px 0px 0px 0px; + width: 77%; + height: 30px; + + border: 1px solid #aaa; + border-radius: 3px; + + cursor: pointer; + + color: #fff; + text-shadow: 0.5px 0.5px 0.5px #444; + font-size: 15px; +} + +.submit_button:hover { + background-color: #1f4f72; +} + +.btn { + display: inline-block; + + background-color: #235A81; + + padding: 20px 40px 20px 40px; + margin: 10px 5px 10px 5px; + + border-radius: 30px; + + text-decoration: none; + font-size: 15px; + text-shadow: 0.5px 0.5px 0.5px #444; + font-weight: bolder; + color: #fff; +} + +.btn:hover { + background-color: #1f4f72; +} + +.link { + color: #235A81; +} + +.error { + margin: 0px; + + color: #235A81; +} + +.content { + width: 100%; +} + +.stats { + height: auto; + + padding: 0px 20px 5px 20px; + + text-align: center; + + display: grid; + justify-content: center; +} + +.chart_div { + text-align: left; + + width: 90vw; + height: 400px; +} + +.chpwd { + height: 400px; + + display: grid; + align-content: center; + text-align: center; +} + +.settings { + height: 300px; + + display: grid; + align-content: center; + justify-content: center; + text-align: center; +} + +hr { + color: #444; + border-radius: 50%; +} + +@media screen and (max-width: 450px) { + .chart_div { + height: 300px; + } +} \ No newline at end of file diff --git a/css/receipt.css b/css/receipt.css new file mode 100644 index 0000000..1e92ce5 --- /dev/null +++ b/css/receipt.css @@ -0,0 +1,105 @@ +.content { + padding: 20px 20px 20px 20px; + + height: fit-content; + + text-align: center; +} + +.form { + background-color: #D3DCE3; + min-width: 300px; + max-width: 400px; + + position: relative; + left: 50%; + transform: translate(-50%, 0%); + + padding: 5px 20px 20px 20px; + margin: 15px 0px 15px 0px; + + border: 1px solid #aaa; + border-radius: 3px; + + box-shadow: 1px 1px 2px #fff inset; + + z-index: 99; +} + +.input-container { + width: 300px; + margin: 0 auto; +} + +.input-label { + text-align: left; + margin: 0px 0px 5px 6px; +} + +.input { + transition-duration: 0.3s; + + background-color: #fff; + + margin: 0px 0px 0px 0px; + width: 135px; + height: 30px; + + outline: none; + border: 1px solid #aaa; + border-radius: 3px; + + font-size: 15px; + + -webkit-validation-bubble-message: none; +} + +.num-input { + width: 9.8ch; +} + +.comment { + width: 285px; + height: 50px; + + resize: none; +} + +.input:hover, .input:focus { + transition-duration: 0.3s; + + outline: none; + box-shadow: 0px 0.1px 2px 0.1px #444444; +} + +.submit_button { + background-color: #235A81; + + margin: 0px; + min-width: 295px; + height: 32px; + + border: 1px solid #aaa; + border-radius: 3px; + + cursor: pointer; + + color: #fff; + text-shadow: 0.5px 0.5px 0.5px #444; + font-size: 15px; +} + +.submit_button:hover { + background-color: #1f4f72; +} + +.link { + color: #235A81; +} + +.error { + text-align: left; + color: #235A81; + + margin: 5px 0px 0px 6px; +} \ No newline at end of file diff --git a/css/sign.css b/css/sign.css new file mode 100644 index 0000000..fe5f16a --- /dev/null +++ b/css/sign.css @@ -0,0 +1,79 @@ +body { + padding: 0px 15px 0px 15px; + + width: calc(100% - 30px) +} + +.form { + background-color: #D3DCE3; + min-width: 300px; + max-width: 400px; + + position: relative; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + + padding: 5px 20px 20px 20px; + + border: 1px solid #aaa; + border-radius: 3px; + + box-shadow: 1px 1px 2px #fff inset; + + text-align: center; +} + +.input { + transition-duration: 0.3s; + + background-color: #fff; + + margin: 10px 0px 5px 0px; + width: 100%; + height: 30px; + + outline: none; + border: 1px solid #aaa; + border-radius: 3px; + + font-size: 15px; +} + +.input:hover, .input:focus { + transition-duration: 0.3s; + + outline: none; + box-shadow: 0px 0.1px 2px 0.1px #444444; +} + +.submit_button { + background-color: #235A81; + + margin: 5px 0px 0px 0px; + width: 100%; + height: 30px; + + border: 1px solid #aaa; + border-radius: 3px; + + cursor: pointer; + + color: #fff; + text-shadow: 0.5px 0.5px 0.5px #444; + font-size: 15px; +} + +.submit_button:hover { + background-color: #1f4f72; +} + +.link { + color: #235A81; +} + +.error { + margin: 0px; + + color: #235A81; +} \ No newline at end of file diff --git a/elements/footer.php b/elements/footer.php new file mode 100644 index 0000000..b3ce501 --- /dev/null +++ b/elements/footer.php @@ -0,0 +1,34 @@ + + + \ No newline at end of file diff --git a/elements/header.php b/elements/header.php new file mode 100644 index 0000000..208aafd --- /dev/null +++ b/elements/header.php @@ -0,0 +1,151 @@ + + +
+ + +
\ No newline at end of file diff --git a/functions.php b/functions.php new file mode 100644 index 0000000..b3d9bbc --- /dev/null +++ b/functions.php @@ -0,0 +1 @@ + + + + + + + + + Сайт + + + + + \ No newline at end of file diff --git a/img/icon.png b/img/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..874470e5870286b94933f185485095953a803014 GIT binary patch literal 22504 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 literal 0 HcmV?d00001 diff --git a/img/logo.png b/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..1d31d7efaead07dc47bbd1742c630717c5147810 GIT binary patch literal 13453 zcmeHtXH-+&*6t<*2)$P+p(vmN0Rn^`dat5Xl>iC7hTa4zf*@Tw(u*LyNRuwoL_|T9 zD$=BP6%}vr^_x+ANmxh#03g>;S2hFy zkU9Y1^*{)57P?vSSO8#|^EWc_G(`D8-8@_|_D*Q1r=J@diuSd~0D$ki$}Cgwb1kVV zKZNhHfKD(7yEo;`uXi0ez{@FUeu1yDmjuRbs6v~c+q=M?pLYI`UAgu7ielY`5<~3p z+kM`qslZi@#uvH4x1`VQ?0n_DwsEui^sqJK^vEba^x1B^!NI}W+>Kj73tKO}9u)hK zPJHpV{`O5Z=0#yO2ZR5yb(nY2>PDk}fB@aMgUA4ZvE1RhmWlmSn*Lz+o4L1ox^5QU ztUYbtx_Np%YECno*S9l_G<9CC&lX?dRt|9vZ^XPHoWhfHcJ=*fRrOQIfUSGojyGBk zv;3@{(lq0vT5PbU=D-W;NXB3a%<10ej~jwPzTX@3S~!D!R$#YMdiAQ)kT>KlMyKbo z*ThygSJ(YV!r`5Q>svHCq7*iXOxw>y!W!R7h>y!BW!#~0>DoDv4|+n;I7O!AXPH2m?aPdEbHKecZ?aA_Ti zPWzy~V=}Tw?0UG-xp%OvxLUT9a|LGGT5EOlhEBJ5isbhdKAOc*bGG7h3y*W-Z>79J z622nGE`!?GUeIv27&||V>(TLC=<56M%CYLv8&G%@mRI}(h`A=w(#_5BXH+7C4{xllh(4XQ4%&Y)Y{?L<&iTshKG@5H9#4F|v`>@#h|W-( zf7!@TN8pInV}yUzqOPktP2Wo6e43$yeeoN8YaOvSh7}Jhk5|kA)+@u64e!i0a+1BT zZ3nhukvqNdutjz5c#(CxLcJl|{tV0m^fl4x&Ee{ruIT&5re2K`kEc_{ePr%oq<{R-626$M33z=+-bC9Y~Lli)BQI z+&&)4s1#InO_5q25!W;3c_EmbRG%%PO8CKBj_nh-&kvjJ()J9dABF8-9*-~=Z+9k2 z7QPNjY`J-GtTCB7g?VS`68Sokq@28ggJ|GOt=L|7bOxZ+edwM-Loo_p0{^M7NyKA_pVBtty9@ZnfnIx9o< zt|9K@0#ysoS9iVK-+J}qQQRZeok)$(cdv9k7hH*LVDq1@Cu&qE?ci6JFuW&hvyjK- zbxmM14Z&Ndxv1vi|8R53x#eV$ECE(2ti>{Qvk@@=y|YAJzeDW7dzD##^( zmNJfIE+bQxw3@w#*kU9veAv4b|3WQgIrj2UbiId8>4nEwB;=E4xzue{vnK{e!&7WZ z?nYJvS%N|zJs)=)h}^X-ldJzUdHt2Vw|4&Rt5yE{R}2Y>CEB*jn3P5y^Acu1tCF-X zvAs0Fka&)FN{3kIv2lSm<=uAtn_tOxun!OT9+#Pp%IPpESJjY`UX)6p0qb=1Tbw+= zu7%w*CY_c1p)_sve zlFq#9)Vn(9UmuyX`d%J8v<7x%@&zoE*3W0$w^_Sc1L4=B(1oO2&CB{Km*J`7kB+5(xF=SiN8g}AdyJiqah&4u zLAUXbyuYh3*TzphiuIE6iLtO4c;MqU=yVh-Cce?bCHD6E8J>ppLa z8XF=oShRCqD2fB8be9Fu3cxya*8;%!hg+cppnXfxi0TV9FwZZG0+;UUu|bGT zIW@DY{be=L1l>9b_d#@ycGCJslXY1#scdpi3cKm1g&-TQH`R2>(6K05-cU0!Fp}@9d;~w0|*kA_i2sG#3N;Od(b)6?Q9Y}ZmUFoVVrR=%%c+=>=_t5dy7+iYZ zt?T+jv722fi7J9M2qNB}iRF0*mZDAx$qr#@b!DZ4=VyMdQASv$6Xo^Cp?VNHj#Nm{ zqyxpPF8yR%NyQ@Qr(?eGF!Q{;gs~~4bDh{BWS^Q#orFQNNJ%U_b~wghy*ET7-=LH{ zVrYeHNRAQ7Qfp{H&Kwoq)O9MHbNDqQ?>xo8^-YDZZ{)%ORZXIs%4|0Rk);gq^Iwa} z%rO!firx5nn8bO`z{ zx4fnNNr*$wZW$iM_Di!(@=3?FGrs${nU zg0`Yu-^r4;a>^+EpKkE_U(7>QuGu@0F4pEF^;?OPxK`TGXh4}@PM`RkSOLScYsdI@ z8b9{-%Ws6yy(V%)e)JrTOU;w6zW36Jl#Id|#qiK#6TPllPc-WF492vIm!CxHuC~F` zX3%csMF&#$zc^yD-I7l+R1AOZuPSsEKhbI?ip+&%`l$l_LnH7gQ~H=pmDAh1gJ}hi z*2qc4%YO{Ek$^lc-&>00ngy1#xly~gHU|#8pM3#ySko8d|&p9@^j1VC_dyoZ|33p<~pC% z07dhff(h8jif@PYT7#y~Lf7~j{(eNcw721yL}CB+6kyBiQFkNOi@%UC6tM{}MeYm* zNST#gX=dL;R;`aAZ)2wSAG}OnFt=@w2E*=*JR4@8C60K=lDVQCP_$#wLUPa2a3lS) zFx14Gl&~`>VZPx)bE~#-4;67romW9%9jl4Shqv>)d*eGL^Qr_tefMu-waDo|B|f{7TB}{?`k& z@!vhL+_s0yCCfz~#c$HBFng()8dkB;GHeuDQZjVMb6P(xz$8#R zBr0jrc(jwOvqwpL)V||*;IBpNun!Z~Qo-jin!AVb{E|){^UC_!tK5OQm+&L7EliWj zOD#^bpn9{CNv|sD2Ah@4+MXua4GQTD%rF~2fm3Tq08O0;Gj$Bh09hj`*06fOUBn!g z-?xTXHtroDV8+LLRhCQ{%p|93S<9TjZ`c|&Awx{`u`076|B7TBG!`ulRb;fLDI}BP z8q>qqeo?W&{q4A%B%9A=F_jHtVqd`OZOsSM0S>sUaF^;n z0{^Bnp~>U%2>r)4??k0Sdf7kg@XB14u^mB-aAU0y_w zU%>?mJ0FR%^MAd_?nP0VklukA!B^igxUv1 zckCAD;1NYqFTZ&1XRzpfkll--IdV?V(X5Zt>T-hiQG=UF1MI1NUU+Fl- ziua*+@yQ$HAB?I5#l^)EKIi3Gq)8&wjbaPun)rN??CO{e^^KmMUPZ3n-bQ&9Cu+B1O<)p4ryP(BhMTp zj*Ci{u<#4BU(4y_ycSHKB*!c#67Ztut0{W&j`_f~qYY)Q@A~<72=ORqq_tmaA z^%-+<)+W;UgCka6${mV#NKJ?rsul(8L>g)>^3p9Kcc_D}v>gL9)``OA+>;G&@}s$T z5-x}6^2Cqm)&(6pJ*@l0V)e$f0Jl zjO_TflJbCbv}R?!7kLMRXsfzsm4n!3p+Z@S<_k_m77*q0EfuRPJ{JB9+WM3hA@gOY zP8Va*-}XWy;BNBS4Q5nNxAMAculMo0c<9XeA9NXXGriL;BzI$rwKGm|)TXE<^KL*W zbl#3e+XXJjumCkIkPj-TPZ4Aw9wl`gD|4B6ejeX+RfMMDfq7Gq z`qzb*$t5G-AH}@tV;MI}FH2SNw<&4Dgq|({@W=-X{kshm%{s*)6Rlf}p2>N~30&>B zQz=d^M3d>yz~qm{lAIo2<|@lu5mgL)Ea>~s z@8Y4!&Zqk{wNzMm4Xr@Jx8Nyjnahd>J@!4Eo3FE8BY8lTtU~!scRk;w$O*G_a?|k} zR!_5!QJ7v~8e1@v*vPBj1_z znoluQ(*)eDuq_hnW|{@fx%8NzPBmjWJRL z=-winNpX4-vve1;MbJy(XcE6!;9PcCw#OcTP2zEzfrHSq)U{U+%u-&a?x+QiJo4)y z^DWYtTS-W-@d4MCxC96QCB!;wt86GU2*Cuu3gqi~J-I7)DA(x7530R=4tt{Sv1s3O z9RE&k-=I`PO;1eR`Xs_XSn;3OQ*>_t8s}&@h10M9b(09l-z(vx#L7 z1}f>l1xeXRZF>_)_?au5NyjMUo>+n#hi-2z^e{<>c(QFNE8NiYYT1 z#+?9Fmv(-b6l@UEbQu^bew#7B^I5L0BI`CpK!$m=M%~eF7m}nKJ_q)_&YVKHkM)>(lo>|HD6!#wP9=1MJbywpgV9pCfcq79yex_lef1Hn;O*_;G?^L<{IStu%&SbY)>)^+1 zmuo3chI^vTI4{Wcx{G9bQJg5;oXFrBg672I59DRs*(Z~XeNCM6pg6v++v`aac@*p-8ja?LIza#L=h_mI^_lUHknP^Sw*ZN_7_rr44s5uW$)qHM!X z6|trM^r6-Z2syc7SJ=~YOF7TY_{l9eEH$^d9ftC(VffjD`l&3X;~K)ev#VJGALot& z%D<4m3eoaSe8GCa8_C?c^z<3}PNFcHLtsmIRk$JTV1@bSeyY)K_p@$6`SxuPD~s}F zu(-XZK%iIh=dUTA_vUYfC5?Q2`E*`?JgGHu;^-Mw)#bu7x_c4)^ z4Wz_s+7yb~jdUx5p9Jae7q=CGdjwg*;Sx3<*S?llGgk(6LYfwZk<4@V!32)b!^u|KI;P&+=rJJE+aSM`ira+ z$BXMd_8{GpP1}w5)X1?ha@!ltkJCrO$8M*1;)6VswLX=$Zu^rL=!RhW%X^Lcob#`Z zD%!n@uF<7$GzzM|7gPF`k_fIvy1E>y#0rFtOO%fJI_9en62%d+4e|3#J&X#aK$cyb z*&8#y5@HrBgN(#abW_hfwH_&u8gChPbn-eFJ}{p@?;fU@NWH^8n2)*_((lj8GZV(P zz}-%c?@nzN&`pf!+VrI;RnNH1KE*iOPj1mnMpRZ-51r< z2dM_FD}Eqld|utf=NcTkr@G--c|*7(J?YI82J0V(E820nqwdd3!z`LwUFF7S-v=C& zWZb+}#+Al+4~>}G)%!~S@jLNqhO5o7dA4ovYH!D|--^Iv!*ew;EBGB~xcD`RL#o?^ zstRVQr1B?cT*pIUgtM{g2erY>!!<-j@^>sjv?-Lv#?M8 zzLk=r^(B6f`F6b~zxy-y_}QiGnQb*rPHS>Z8dRg+%)7>i%aTUqPJWrJ8o8tO-Kuha zXE4w)$8~e?8_j9wO!Ai%sm|GCKdt#&t-J?3I}#i4AX!mp9d>{L!(lJ(w{~*EfV=T6 zn`NE7{_;mX-j+iTDR@BWV@w(IG{rpKM=Wn;X!Cj<2Zt^HN-2s&DoDYqj&9S;2l{}0 z$-=d~HEnwNqjhqY{MNp4a$0T{Yu3@poaURfRrsO{a~tT>`3iGo&RVd)=#BIpao#+4 z*^jT@gc{17c#zOJM3KaiJ-?%@cvJC3py$Nok!2W>_};Qb25A4w#u7~9gh1%cOO_-q z;&n;$$%W;D_?*Qz`D8aYzwPHpGgYs>juiOjpmkz(c&JxC%ea%VszbB3C3G%KYDGBa zPipdS71}rN=;UeD@0zc%%+K|fk#ygKeqYUSjpVnB5Hh! zPhS3g<%jI<+rlr?l)AnJpp5}$35vX(b1N&c6Am+*|=Jv z1$~{}a8JSjKt|rz4Q1_!_JmrYZS7rTxpvw*xuEtovRuYuIxrnKCA6Kry1xhdiodRr zwZEgaqz#w69Epst6pp|d?TLc=Iy<>wrF><%e)3A;zMq+exS&5>JRN1ZOmy_2O0FJg zC|nRO2oq58wf7d`k|Tl2c-Ua143$-XQQ)p*x$HbW-K2zse0+QaeMALaJ#2-9B_$<= zU?M^yA_6!M0j!^kC(2jA1Hg8dLR`Eu= zcyj+vVPpMwyqlMY)6aBltcB1{XlI-&78h0cFCo=5boBp@I4gmzy|dd-6t38R@$|IE z{8_BOXgeGEna=M*aPYtL{>A%mx&L&=dFkj#DZ5&GoypTsmgPE&FJ^Q#D4 zQbYue5*M%*6SWe6i^4<%5MmM%0@k7;*5U{WxP*u`<~J%07py1B#TtD^g(DZV$MJ~3 z;F4%j8%Y6CYcVkaxD6U3ASsMN3)o=95O9>W4ctZ;{Tqdzhdr(n8GXeQbyiJbaS?HGNpS>B7$zYq zE+P7-(>1gQ7T1YqoWd|c5%|xMvuTmSC4(z0>a0(31V8P#T%?pd&?rw=4Ul+!?H^ZvECDC`pF>dS&$g99S^p6Pi}FU>{0xM{ z{V`;1hjOt+-?gl(49j zi0~zts1yvwCG;y{p|e%}w~S?k{zpw@emeZN4d8Hp*l^nmZnqNp`*!uKW@lym|M>Ye z7yln4;Hdu_Y|b+g<-H*MC%j|H%2j-Sxj#E|NbFJZKl(U62p% zIK%&9atHTvV7R@KlD>wL(%;?(1OUFophQ{qUL@<&n^%feF5cdPE+*tlnNrcazrIM9 zuUJNJ<^^jxB+X<>qGMF+Zd_P+W;N0M)YO>BSb^#r;Eu%_dM48RNTW0B^L3kv_xZ%` zvjgNCpfe}L2<=*(F@_q#X*a2rsv(?rAw6qp8R!vBLza#Y8|-);bLV|if3(P}Rh!i? zQBg(Prla2VZS-BqYU=jOMf4BVX$I=bIE)iSbF@_Xe(P^ps_PQ9#)ylmv2rtLu|4vH zUCLtF<8il`@El_FV6Vu2jBuP_ahy%=gc**dr8VnfA^evuscDq?%JOetbmFm_(5Oww z|6UY-YwSpC$#CE*9``dD@jM0Z?+dqf+srEv!rSLnl8~QbJ_M5C=U>k=^~v6`erEpw z=(b(Zbp0y9(sjuD@u-PG9(2+a8ne+=Lq~;ZnTVE*oW7#jRs;Y@{56ynjC|j1&31c< zw9teY6khS8qG_Rmv`{5+caypX)_k2}_0hUI{-n+Hx!z-=Bl3}egX6O|L;u;QUeXWT zWw$zfw0BfJzavpkOr;(IJBii@foY(z;WW?$!2OUV9}M9^G7+CgLh*XkdGJ8QRH}+U z9ceT}kf6Rq^`GATv}af0i9fM%Kd~sDBp?(F;r@+a@qZHh4WfJ&4#ku56B15y7L)Vr zViA&v6F{X3!3hY3De~b2gj4?%fS}R%GvqJ1zwl>}Uz!&o`Cy!8707v9atKA9P@GB} z{wzZ(&9e-{^+9JUmH!OcgM;8gs{IOimh&GWp>aq)93IusXZ7i_3JyS}n);<*5?iFEL{MiGTG^Q{G&y57`;nL~4nT;2BcIUc>*#C;;K9VG>YT?asiJ zi6LKQ%?WW1n$Wdh|1F!|mH59PO$jUBXT&1+7#E~U0FI`@|%$3k3QWxtco}+^!L#9%WKE&R|kv$vl z&hWx?hxR4a+PFpLps3VME~k==){ByZh-3O_y1#gLC_qu}ChUlvQ7H(|Ws+f#?fhG! z&~O5jN0qScm_8KsX%Io^ljnJby=jF=C3Xn5$o(0c)^bDRmVJmEZdqFDtn4bxDh$aax* zG!mpVMb*#drADo8xy#btT)lk}hcxSD@L}{}3=Mzp(7Y)4L6AEErcZ7(V?W~vrim=W zBiU}2j>E}-!@F~QR;ksQk|KH1@h|{R#!E}^L6-~?ilSl(w-iq&$C1hRQjU<+gK#oz zr$Sp$-p~Zt0vQ6PG(v?V%giUl+|95m!TAX*k&Q5oFolNaqwPX7!ZL6{%g8Rm0!G;D z)u1Q@vu=o~4FfR`8Fw!PmNjw#ob=xMGl02o8i5pXBV+9v5viwAkBsHSPe);xK!f_i zCfT;IS0kd}B!$}wAWYWVNTi4iOs4CR=myS@Ad(v>`1nO{6@G0|X%0>T}=FrJiOufa%B(O0b|w z19wr>;DeK5-dh1vM8}~>4{8fA(AMojrB2b=OKE95MGqQ8`Ap$$QnV>SC1)rkLiDXB zWj#FdsMP@PyE!5TP{}?D;Se_KXAmBuH{Ap^j+0(9yFejhGKRj*0J2*4#`1Jg z**+2v$bYR>u}g&)@(^(uScBy|6yANb zyvq%I3u{I8;LP$3dc%57J&=&-Pbs;x;3OCb$mdB2rv@O!+@F0C`ltbK7QMi*B`Um{ zwcrEiBqWV008Kd^(Q{ga0BtXRh=m|M5P+p4qd!S*56X=RSnw07I;}T<6pZ`3kbn57 z^4mCG$h^mcPYf6cAHVc&Q-~6%alA=?g8|r` ze|LJ!ApjgA4R<UzWMP^z&{8Igj~G- zQpVv|iT`Q+|H|pt1m+qh4|NR?dCKE)tDKlZ!#$P + + + + + + + +
+ + 0) { + + foreach (mysqli_fetch_all($userdata) as $row) { + array_push($books, $row); + } + + foreach ($books as $book) { + $book_id = $book[0]; + + echo '
+
+

'.$book[1].'

+

'.$book[2].'

+

Счёт '.$book[3].'

+ Подробнее

+ Удалить +
+
'; + } + } + + #print_r($books); + ?> + +
+ + +
+ +
+ + + + \ No newline at end of file diff --git a/js/dragndrop.js b/js/dragndrop.js new file mode 100644 index 0000000..f7e2661 --- /dev/null +++ b/js/dragndrop.js @@ -0,0 +1,38 @@ +const draggables = document.querySelectorAll('.card') +const container = document.querySelector('.content') + +draggables.forEach(draggable => { + draggable.addEventListener('dragstart', () => { + draggable.classList.add('dragging'); + }) + + draggable.addEventListener('dragend', () => { + draggable.classList.remove('dragging') + }) +}) + +container.addEventListener('dragover', e => { + e.preventDefault() + const afterElement = getDragAfterElement(container, e.clientX) + console.log(afterElement) + const draggable = document.querySelector('.dragging') + if (afterElement == null) { + container.appendChild(draggable) + } else { + container.insertBefore(draggable, afterElement) + } +}) + +function getDragAfterElement (container, x) { + const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')] + + draggableElements.reduce((closest, child) => { + const box = child.getBoundingClientRect() + const offset = x - box.right - box.width / 2 + if (offset < 0 && offset > closest.offset) { + return { offset: offset, element: child} + } else { + return closest + } + }, { offset: Number.NEGATIVE_INFINITY }).element +} \ No newline at end of file diff --git a/login.php b/login.php new file mode 100644 index 0000000..4580d36 --- /dev/null +++ b/login.php @@ -0,0 +1,79 @@ + 0) { + + while($row = mysqli_fetch_assoc($userdata)) { + $dbuser_id = $row['user_id']; + $dbusername = $row['username']; + $dbemail = $row['email']; + $dbpassword_hashed = $row['password']; + } + + if (password_verify($password, $dbpassword_hashed)) { + $_SESSION['loggedin'] = true; + $_SESSION['user_id'] = $dbuser_id; + $_SESSION['username'] = $dbusername; + $_SESSION['email'] = $dbemail; + + header("Location: index.php"); + + mysqli_close($conn); + } else { + $passwordErr = "Неправильный пароль"; + } + } else { + + $emailErr = "Почта не зарегестрирована"; + } + } +?> + + + + +
+ +

Войти

+ +
* обязательное поле
+
+ + +
+
+ + +
+
+ + + +

У вас ещё нету аккаунта? Создать аккаунт

+
+ + \ No newline at end of file diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..2836d2c --- /dev/null +++ b/logout.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/profile.php b/profile.php new file mode 100644 index 0000000..9931cc3 --- /dev/null +++ b/profile.php @@ -0,0 +1,226 @@ + 0) { + + while($row = mysqli_fetch_array($result)) { + $dbpassword_hashed = $row['password']; + } + } + + #Validate new password + $password = $_POST['pwd']; + $new_password = $_POST['npwd']; + $confirm_new_password = $_POST['cnpwd']; + + if ($new_password != $confirm_new_password) { + $confirm_passwordErr = 'Пароли не совпадают'; + } + + if (mb_strlen($new_password) < 8) { + $confirm_passwordErr = "Используйте больше 8 символов"; + } + + if (empty($new_password)) { + $confirm_passwordErr = "Вы не ввели пароль"; + } + + if (!password_verify($password, $dbpassword_hashed)) { + $passwordErr = "Вы ввели неправильный пароль"; + } + + #Set new password + if ($confirm_passwordErr == NULL && $passwordErr == NULL) { + + $password_hashed = password_hash($new_password, PASSWORD_DEFAULT); + $query = "UPDATE Users SET password = '$password_hashed' WHERE (user_id = '$session_user_id')"; + + if (mysqli_query($conn, $query)) { + header("Location: logout.php"); + mysqli_close($conn); + } else { + echo mysqli_errno($conn) . " : " . mysqli_error($conn); + } + } + + } + } + + include_once('head.php'); + + ####Get data to make graphs#### + $book_info = array(); + + #Get user's books + $book_ids = $book_names = array(); + + $query = "SELECT book_id, name FROM Books WHERE owner_id = '$session_user_id'"; + $result = mysqli_query($conn, $query); + + if (mysqli_num_rows($result) > 0) { + + while($row = mysqli_fetch_array($result)) { + + array_push($book_ids, $row['book_id']); + array_push($book_names, $row['name']); + } + } + + #Get user's boooks receipts into $book_info array + + $start_dates_all = $final_dates_all = $start_nums_all = $final_nums_all = $rates_all = $start_dates = $final_dates = $start_nums = $final_nums = $rates = array(); + + $curr_id = NULL; + $curr_num = -1; + + for ($i=0; $i < count($book_ids); $i++) { + + $query = "SELECT start_date, final_date, start_num, final_num, rate FROM Receipts WHERE book_id = '$book_ids[$i]' ORDER BY start_date LIMIT 100"; + $result = mysqli_query($conn, $query); + + if (mysqli_num_rows($result) > 0) { + + while($row = mysqli_fetch_array($result)) { + + if (date(strtotime($row['final_date'])) > date(strtotime('-2 month'))) { + + array_push($start_dates_all, $row['start_date']); + array_push($final_dates_all, $row['final_date']); + array_push($start_nums_all, $row['start_num']); + array_push($final_nums_all, $row['final_num']); + array_push($rates_all, $row['rate']); + + if ($curr_id != $book_ids[$i]) { + + $curr_id = $book_ids[$i]; + $curr_num++; + + array_push($book_info, array($book_ids[$i], $book_names[$i], array(array($row['start_date'], $row['final_date'], $row['start_num'], $row['final_num'], $row['rate'])))); + } else if ($curr_id == $book_ids[$i]) { + + array_push($book_info[$curr_num][2], array($row['start_date'], $row['final_date'], $row['start_num'], $row['final_num'], $row['rate'])); + } + } + } + } + } + + #$print_r($book_info); + +?> + + + + + + + + + + + + + +
+ +
+ +

Статистика

+ +
+ +
+ +
+ +
+ +
+ +

Изменить пароль

+ + +
+ + +
+ + +
+ + + +
+ +
+ +
+ +
+ +

Управление аккаунтом

+ + Удалить аккаунт + +
+ +
+ + + + \ No newline at end of file diff --git a/receipt.js b/receipt.js new file mode 100644 index 0000000..6c9a336 --- /dev/null +++ b/receipt.js @@ -0,0 +1,28 @@ +const monthlyField = document.getElementById("monthly"); +const totalField = document.getElementById("total"); + +const start_num = document.getElementById("start_num"); +const final_num = document.getElementById("final_num"); +const rate = document.getElementById("rate"); + +getMonthly(); +getTotal(); + +start_num.addEventListener("click", getMonthly); +final_num.addEventListener("input", getMonthly); +start_num.addEventListener("click", getTotal); +final_num.addEventListener("input", getTotal); +rate.addEventListener("input", getTotal); + +var monthly; +var total; + +function getMonthly() { + monthly = final_num.value - start_num.value; + monthlyField.value = monthly; +} + +function getTotal() { + total = monthly * rate.value; + totalField.value = Number((total).toFixed(2)); +} \ No newline at end of file diff --git a/receipt.php b/receipt.php new file mode 100644 index 0000000..a6b1865 --- /dev/null +++ b/receipt.php @@ -0,0 +1,156 @@ + 0) { + + while($row = mysqli_fetch_array($result)) { + $start_date = $row['start_date']; + $final_date = $row['final_date']; + $start_num = $row['start_num']; + $final_num = $row['final_num']; + $rate = $row['rate']; + $comment = $row['comment']; + } + } + + #Validate ownership + $link_user_id = $_GET['user_id']; + $session_user_id = $_SESSION['user_id']; + + if ($link_user_id != $session_user_id) { + header("Location: index.php"); + } + + #Post method + if ($_SERVER["REQUEST_METHOD"] == "POST") { + + #Collect data from html form via POST request method + $start_date = $_POST['start_date']; + $final_date = $_POST['final_date']; + $start_num = $_POST['start_num']; + $final_num = $_POST['final_num']; + $rate = $_POST['rate']; + $comment = $_POST['comment']; + + #Define error variables and set to empty valuse + $dateErr = $numErr = $rateErr = $commentErr = NULL; + + #Validate form and catch errors + + #Date confirmation + if(empty($start_date) || empty($final_date)) { + $dateErr = "Вы не ввели дату"; + } + + #Num confirmation + if ($start_num < 0 || empty($final_num)) { + $numErr = "Вы не ввели показания счётчика"; + } + + #Rate confirmation + if (empty($rate)) { + $rateErr = "Вы не ввели тариф"; + } + + #Comment validation + if (strlen($comment) > 255) { + $commentErr = "Коммнтарий не можеть быть длиннее 255 символов"; + } + + #Post data to the database is there are no errors + if ($dateErr == NULL && $numErr == NULL && $rateErr == NULL && $commentErr == NULL) { + + if ($receipt_id == NULL) { + + $query = "INSERT INTO Receipts (book_id, start_date, final_date, start_num, final_num, rate, comment) VALUES ('$book_id', '$start_date', '$final_date', '$start_num', '$final_num', '$rate', '$comment')"; + + if (mysqli_query($conn, $query)) { + echo "New record has been created successfully"; + header('Location: book.php?user_id='.$session_user_id.'&book_id='.$book_id.''); + } else { + echo mysqli_errno($conn) . " : " . mysqli_error($conn); + } + } else { + + $query = "UPDATE Receipts SET start_date = '$start_date', final_date = '$final_date', start_num = '$start_num', final_num = '$final_num', rate = '$rate', comment = '$comment' WHERE (receipt_id = '$receipt_id')"; + + if (mysqli_query($conn, $query)) { + echo "Receipts has been updated"; + header('Location: book.php?user_id='.$session_user_id.'&book_id='.$book_id.''); + } else { + echo mysqli_errno($conn) . " : " . mysqli_error($conn); + } + } + } + + mysqli_close($conn); + } + +?> + + + + + + +
+ + Назад + +
+ +

: Запись №

+ +
+ +

Дата*:

+ > - > +
+
+ +

Показания счётчика*:     За месяц:

+ > - > : +
+
+ +

Тариф*:        Сумма:

+ > : +
+
+ +

Комментарий к записи:

+ +
+
+ + +

+ + Удалить +
+ + +
+ +
+ + + + + + \ No newline at end of file diff --git a/remove_book.php b/remove_book.php new file mode 100644 index 0000000..6a2477f --- /dev/null +++ b/remove_book.php @@ -0,0 +1,27 @@ + \ No newline at end of file diff --git a/remove_receipt.php b/remove_receipt.php new file mode 100644 index 0000000..b76d05a --- /dev/null +++ b/remove_receipt.php @@ -0,0 +1,28 @@ + \ No newline at end of file diff --git a/remove_user.php b/remove_user.php new file mode 100644 index 0000000..d34018b --- /dev/null +++ b/remove_user.php @@ -0,0 +1,28 @@ + \ No newline at end of file diff --git a/sign_up.php b/sign_up.php new file mode 100644 index 0000000..9ce40b1 --- /dev/null +++ b/sign_up.php @@ -0,0 +1,106 @@ + + + + + +
+ +

Создать аккаунт

+ +
* обязательное поле
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + + +

У вас уже есть аккаунт? Войти

+
+ + \ No newline at end of file