Sfoglia il codice sorgente

Multiple changes.

Allow project creation.
Data re-org.
Style updates.
Navigation fixes.
Nathaniel van Diepen 10 anni fa
parent
commit
2211048c33

+ 62 - 20
api.php

@@ -8,6 +8,7 @@
 			$id = $_GET['id'];
 			switch($_GET['type']){
 				case 'user':
+					back(true);
 					if(!isset($_GET['template'])){
 						$ret['template'] = file_get_contents(PATH_DATA.'pages/user.template');
 					}
@@ -24,15 +25,19 @@
 					retj($ret,'User - '.$context['name']);
 				break;
 				case 'group':
+					back(true);
 					// TODO - handle group requests
 				break;
 				case 'issue':
+					back(true);
 					// TODO - handle issue requests
 				break;
 				case 'scrum':
+					back(true);
 					// TODO - handle scrum requests
 				break;
 				case 'project':
+					back(true);
 					if(!isset($_GET['template'])){
 						$ret['template'] = file_get_contents(PATH_DATA.'pages/project.template');
 					}
@@ -46,9 +51,11 @@
 					retj($ret,'Project - '.$context['title']);
 				break;
 				case 'admin':
+					back(true);
 					// TODO - handle admin requests
 				break;
 				case 'page':
+					$title = $id;
 					if(file_exists(PATH_DATA.'pages/'.$id.'.template')){
 						if(!isset($_GET['template'])){
 							$ret['template'] = file_get_contents(PATH_DATA.'pages/'.$id.'.template');
@@ -60,21 +67,29 @@
 						};
 						if(file_exists(PATH_DATA.'pages/'.$id.'.options')){
 							$options = objectToArray(json_decode(file_get_contents(PATH_DATA.'pages/'.$id.'.options'),true));
-							foreach($options as $key){
-								switch($key){
-									case 'users':
-										if($res = query("SELECT name FROM `users`;")){
-											$context['users'] = fetch_all($res,MYSQLI_ASSOC);
-										}
-									break;
-									case 'projects':
-										if($res = query("SELECT p.title,p.id,p.description,u.name as user FROM `projects` p JOIN `users` u ON u.id = p.u_id")){
-											$context['projects'] = fetch_all($res,MYSQLI_ASSOC);
-											foreach($context['projects'] as $key => $project){
-												$context['projects'][$key]['user'] = userObj($project['user']);
+							if(isset($options['secure'])&&$options['secure']&&!$LOGGEDIN){
+								back(true);
+							}
+							if(isset($options['title'])){
+								$title = $options['title'];
+							}
+							if(isset($options['context'])){
+								foreach($options['context'] as $key){
+									switch($key){
+										case 'users':
+											if($res = query("SELECT name FROM `users`;")){
+												$context['users'] = fetch_all($res,MYSQLI_ASSOC);
 											}
-										}
-									break;
+										break;
+										case 'projects':
+											if($res = query("SELECT p.title,p.id,p.description,u.name as user FROM `projects` p JOIN `users` u ON u.id = p.u_id")){
+												$context['projects'] = fetch_all($res,MYSQLI_ASSOC);
+												foreach($context['projects'] as $key => $project){
+													$context['projects'][$key]['user'] = userObj($project['user']);
+												}
+											}
+										break;
+									}
 								}
 							}
 						}
@@ -82,7 +97,7 @@
 					}else{
 						$ret['error'] = 'That page does not exist';
 					}
-					retj($ret,$id);
+					retj($ret,$title);
 				break;
 				case 'action':
 						switch($id){
@@ -112,7 +127,7 @@
 										'id'=>'register'
 									)
 								);
-								if(isvalid('username')&&isvalid('password')&&isvalid('password1')&&isvalid('email')&&isvalid('captcha')){
+								if(is_valid('username')&&is_valid('password')&&is_valid('password1')&&is_valid('email')&&is_valid('captcha')){
 									if($_GET['password']==$_GET['password1']){
 										if(compare_captcha($_GET['captcha'])){
 											if(addUser($_GET['username'],$_GET['password'],$_GET['email'])){
@@ -133,17 +148,44 @@
 								}
 								retj($ret,$id);
 							break;
+							case 'project':
+								back(true);
+								$ret['state'] = Array(
+									'data'=>Array(
+										'type'=>'page',
+										'id'=>$id,
+									)
+								);
+								if(isset($_GET['pid'])){
+									$ret['error'] = 'Invalid Action';
+								}elseif(is_valid('title')&&is_valid('description')){
+									if(!newProject($_GET['title'],$_GET['description'])){
+										$ret['error'] = 'Unable to create project.';
+									}
+								}else{
+									$ret['error'] = 'Fill in all the details.';
+								}
+								retj($ret,$id);
+							break;
 							default:
-								die('invalid action');
+								retj(Array(
+									'error'=>'Invalid action.'
+								));
 						}
 				break;
 				default:
-					die("invalid type");
+					retj(Array(
+						'error'=>'Invalid type.'
+					));
 			}
 		}else{
-			die("id missing");
+			retj(Array(
+				'error'=>'ID missing.'
+			));
 		}
 	}else{
-		die("type missing");
+		retj(Array(
+		'error'=>'Type missing.'
+	));
 	}
 ?>

+ 4 - 4
css/fonts.css

@@ -3,7 +3,7 @@
 	word-wrap: break-word;
 	font-weight: normal;
 }
-body,input[type=text],input[type=password]{
+body,input[type=text],input[type=password],textarea{
 	font-size: 130%;
 	line-height: 1.6875;
 }
@@ -12,17 +12,17 @@ pre {
 	white-space: pre-wrap;
 }
 @media only screen and (min-width: 400px){
-	body,input[type=text],input[type=password]{
+	body,input[type=text],input[type=password],textarea{
 		font-size: 120%;
 	}
 }
 @media only screen and (min-width: 800px){
-	body,input[type=text],input[type=password]{
+	body,input[type=text],input[type=password],textarea{
 		font-size: 110%;
 	}
 }
 @media only screen and (min-width: 1100px){
-	body,input[type=text],input[type=password]{
+	body,input[type=text],input[type=password],textarea{
 		font-size: 100%;
 	}
 }

+ 3 - 0
css/style.css

@@ -28,6 +28,9 @@ input[type=submit]:active,button.recommend:active{
 	background: #008aaa;
 	color: #333;
 }
+textarea{
+	min-height: 50px;
+}
 form#form{
 	width: 320px;
 }

+ 2 - 2
data/pages/login.template

@@ -1,6 +1,6 @@
 <script>
 	{{#if key}}
-		History.back();
+		back();
 	{{/if}}
 </script>
 <form id="form" style="display:none;">
@@ -29,7 +29,7 @@
 				apiCall(data,function(d){
 					if(!d.error){
 						setKey(d.key);
-						History.go(-1);
+						back();
 					}else{
 						setKey(null);
 						$('#loading').hide();

+ 4 - 0
data/pages/newproject.options

@@ -0,0 +1,4 @@
+{
+	"title": "New Project",
+	"secure": true
+}

+ 45 - 0
data/pages/newproject.template

@@ -0,0 +1,45 @@
+{{#if key}}
+	<form id="form">
+		<div>
+			<input type="text" name="title" class="fill-width" placeholder="Title"/>
+		</div>
+		<div>
+			<textarea type="text" name="description" class="fill-width" placeholder="Description"/></textarea>
+		</div>
+		<div>
+			<input type="button" value="cancel" class="cancel"/>
+			<input type="submit" value="create"/>
+		</div>
+	</form>
+	<script>
+		$(document).ready(function(){
+			$('form#form').submit(function(){
+				var data = $(this).serializeObject(),
+					State = History.getState();
+				for(var i in State.data){
+					data[i] = State.data;
+				}
+				data.type = 'action';
+				data.id = 'project';
+				apiCall(data,function(d){
+					if(!d.error){
+						back();
+					}else{
+						$('#loading').hide();
+					}
+					return false;
+				});
+				return false;
+			}).find('.cancel').click(function(){
+				back();
+				return false;
+			});
+		});
+	</script>
+{{else}}
+	<script>
+		$(document).ready(function(){
+			back();
+		});
+	</script>
+{{/if}}

+ 6 - 3
data/pages/projects.options

@@ -1,3 +1,6 @@
-[
-	"projects"
-]
+{
+	"secure": true,
+	"context": [
+		"projects"
+	]
+}

+ 3 - 5
data/pages/projects.template

@@ -1,8 +1,6 @@
-{{#if key}}
-	<a class="button" href="#page-newproject">
-		New
-	</a>
-{{/if}}
+<a class="button" href="#page-newproject">
+	New
+</a>
 <div class="accordion">
 	<span class="icons">
 		{

+ 1 - 1
data/pages/register.template

@@ -1,6 +1,6 @@
 <script>
 	{{#if key}}
-		History.back();
+		back();
 	{{/if}}
 </script>
 <form id="form" style="display:none;">

+ 6 - 3
data/pages/users.options

@@ -1,3 +1,6 @@
-[
-	"users"
-]
+{
+	"secure": true,
+	"context": [
+		"users"
+	]
+}

+ 0 - 0
data/pages/topbar.template → data/topbars/default.template


+ 8 - 4
js/index.js

@@ -293,6 +293,7 @@
 				$(window).resize();
 			},
 			content: function(t,c){
+				$(document).unbind('ready');
 				$('#content').html(
 					Handlebars.compile(t)(c)
 				);
@@ -359,15 +360,18 @@
 							input.val('');
 						})
 					);
-					if(input.hasClass('fill-width')){
-						input.css('width','calc(100% - '+(input.outerWidth()-input.width())+'px)');
-					}
 					input.focus(function(){
 						input.next().show();
 					}).blur(function(e){
 						input.next().hide();
 					});
 				});
+				$(selector).find('input[type=text],input[type=password],textarea').each(function(){
+					var input = $(this);
+					if(input.hasClass('fill-width')){
+						input.css('width','calc(100% - '+(input.outerWidth()-input.width())+'px)');
+					}
+				});
 			},
 			dialog: function(selector,title){
 				$(selector).dialog({
@@ -452,7 +456,7 @@
 		$.ajaxSetup({
 			async: false,
 			cache: false,
-			timeout: 2000
+			timeout: 30000 // 30 seconds
 		});
 		 $(document).ajaxError(function(event, request, settings) {
 			error({error:'Request timed out'});

+ 1 - 1
php/database.php

@@ -10,7 +10,7 @@
 		for ($i=0;$i<count($args);$i++){
 			if(is_string($args[$i])){
 				$args[$i] = $mysqli->real_escape_string($args[$i]);
-			}else{
+			}elseif(!is_numeric($args[$i])){
 				return false;
 			}
 		}

+ 30 - 10
php/functions.php

@@ -29,15 +29,19 @@
 			}
 		}
 		$json['state']['title'] = $title;
-		// URL
-		switch($type){
-			case 'user':$url='~'.$id;break;
-			case 'group':$url='+'.$id;break;
-			case 'issue':$url='!'.$id;break;
-			case 'action':$url='';break;
-			default:$url=$type.'-'.$id;
+		if(!isset($json['state']['url'])){
+			// URL
+			switch($type){
+				case 'user':$url='~'.$id;break;
+				case 'group':$url='+'.$id;break;
+				case 'issue':$url='!'.$id;break;
+				case 'action':$url='';break;
+				default:$url=$type.'-'.$id;
+			}
+			$json['state']['url'] = $url;
+		}else{
+			$url = $json['state']['url'];
 		}
-		$json['state']['url'] = $url;
 		// Tobar
 		if($LOGGEDIN){
 			$context = Array(
@@ -49,13 +53,18 @@
 		}
 		$context['title'] = $title;
 		$context['url'] = $url;
+		if(file_exists(PATH_DATA.'topbars/'.$type.'-'.$id)){
+			$topbar = file_get_contents(PATH_DATA.'topbars/'.$type.'-'.$id.'.template');
+		}else{
+			$topbar = file_get_contents(PATH_DATA.'topbars/default.template');
+		}
 		$json['topbar'] = Array(
-			'template'=>file_get_contents(PATH_DATA.'pages/topbar.template'),
+			'template'=>$topbar,
 			'context'=>$context
 		);
 		die(json_encode($json));
 	}
-	function isvalid($col,$v=null){
+	function is_valid($col,$v=null){
 		if($v == null){
 			$v = $_GET;
 		}
@@ -73,4 +82,15 @@
 			return false;
 		}
 	}
+	function back($ifNotLoggedIn=false){
+		global $LOGGEDIN;
+		if($ifNotLoggedIn && $LOGGEDIN){
+			return false;
+		}
+		retj(Array(
+			'state'=>Array(
+				'url'=>isset($_GET['back'])?$_GET['back']:'page-index'
+			)
+		));
+	}
 ?>

+ 16 - 1
php/project.php

@@ -1,7 +1,6 @@
 <?php
 	require_once(realpath(dirname(__FILE__)).'/config.php');
 	require_once(PATH_PHP.'database.php');
-	global $mysqli;
 	function projectObj($id){
 		if($res = query("SELECT p.title,p.id,p.description,u.name as user FROM `projects` p JOIN `users` u ON u.id = p.u_id  WHERE p.id='%d'",Array($id))){
 			if($res->num_rows == 1){
@@ -12,4 +11,20 @@
 		}
 		return false;
 	}
+	function newProject($title,$description,$user=null){
+		global $LOGGEDIN;
+		global $mysqli;
+		if($LOGGEDIN){
+			if(is_null($user)){
+				$user = $_SESSION['username'];
+			}
+			$user = userId($user);
+			if(false != $user){
+				if(query("INSERT INTO `projects` (title,description,u_id) VALUES ('%s','%s',%d)",Array($title,$description,$user))){
+					return true;
+				}
+			}
+		}
+		return false;
+	}
 ?>