Commits

Anonymous committed 3e4df21

mockups

Comments (0)

Files changed (8)

foodoptimizr/static/css/foodoptimizr.css

 div.header h1 {
     color:#fff;
     padding: 10px;
+    text-shadow: 2px 2px 2px #000;
 }
 
 div.content {
     padding: 5px;
 }
 
-tr.red {
+.red {
    background-color: #f99; 
 }
 
-tr.green {
+.green {
    background-color: #9f9; 
 }
 

foodoptimizr/static/css/jquery.autocomplete.css

+.acInput {
+	width: 200px;
+}
+.acResults {
+	padding: 0px;
+	border: 1px solid WindowFrame;
+	background-color: Window;
+	overflow: hidden;
+}
+
+.acResults ul {
+	width: 100%;
+	list-style-position: outside;
+	list-style: none;
+	padding: 0;
+	margin: 0;
+}
+
+.acResults li {
+	margin: 0px;
+	padding: 2px 5px;
+	cursor: pointer;
+	display: block;
+	width: 100%;
+	font: menu;
+	font-size: 12px;
+	overflow: hidden;
+}
+
+.acLoading {
+	background : url('indicator.gif') right center no-repeat;
+}
+
+.acSelect {
+	background-color: Highlight;
+	color: HighlightText;
+}

foodoptimizr/static/js/jquery.autocomplete.js

+/**
+ * jquery.autocomplete.js
+ * Version 3.2
+ * Copyright (c) Dylan Verheul <dylan.verheul@gmail.com>
+ */
+(function($) {
+
+    /**
+     * Autocompleter Object
+     * @param {jQuery} $elem jQuery object with one input tag
+     * @param {Object=} options Settings
+     * @constructor
+     */
+    $.Autocompleter = function($elem, options) {
+
+        /**
+         * Cached data
+         * @type Object
+         * @private
+         */
+        this.cacheData_ = {};
+
+        /**
+         * Number of cached data items
+         * @type number
+         * @private
+         */
+        this.cacheLength_ = 0;
+
+        /**
+         * Class name to mark selected item
+         * @type string
+         * @private
+         */
+    	this.selectClass_ = 'jquery-autocomplete-selected-item';
+
+    	/**
+    	 * Handler to activation timeout
+    	 * @type ?number
+    	 * @private
+    	 */
+        this.keyTimeout_ = null;
+
+    	/**
+    	 * Last key pressed in the input field (store for behavior)
+    	 * @type ?number
+    	 * @private
+    	 */
+        this.lastKeyPressed_ = null;
+
+    	/**
+    	 * Last value processed by the autocompleter
+    	 * @type ?string
+    	 * @private
+    	 */
+        this.lastProcessedValue_ = null;
+
+    	/**
+    	 * Last value selected by the user
+    	 * @type ?string
+    	 * @private
+    	 */
+        this.lastSelectedValue_ = null;
+
+    	/**
+    	 * Is this autocompleter active?
+    	 * @type boolean
+    	 * @private
+    	 */
+        this.active_ = false;
+
+    	/**
+    	 * Is it OK to finish on blur?
+    	 * @type boolean
+    	 * @private
+    	 */
+        this.finishOnBlur_ = true;
+
+        /**
+         * Assert parameters
+         */
+        if (!$elem || !($elem instanceof jQuery) || $elem.length !== 1 || $elem.get(0).tagName.toUpperCase() !== 'INPUT') {
+            alert('Invalid parameter for jquery.Autocompleter, jQuery object with one element with INPUT tag expected');
+            return;
+        }
+
+        /**
+         * Init and sanitize options
+         */
+        if (typeof options === 'string') {
+            this.options = { url:options };
+        } else {
+            this.options = options;
+        }
+		this.options.maxCacheLength = parseInt(this.options.maxCacheLength);
+		if (isNaN(this.options.maxCacheLength) || this.options.maxCacheLength < 1) {
+			this.options.maxCacheLength = 1;
+		}
+		this.options.minChars = parseInt(this.options.minChars);
+		if (isNaN(this.options.minChars) || this.options.minChars < 1) {
+			this.options.minChars = 1;
+		}
+
+        /**
+         * Init DOM elements repository
+         */
+        this.dom = {};
+
+        /**
+         * Store the input element we're attached to in the repository, add class
+         */
+        this.dom.$elem = $elem;
+		if (this.options.inputClass) {
+			this.dom.$elem.addClass(this.options.inputClass);
+		}
+
+        /**
+         * Create DOM element to hold results
+         */
+		this.dom.$results = $('<div></div>').hide();
+		if (this.options.resultsClass) {
+			this.dom.$results.addClass(this.options.resultsClass);
+		}
+		this.dom.$results.css({
+			position: 'absolute'
+		});
+		$('body').append(this.dom.$results);
+
+        /**
+         * Shortcut to self
+         */
+        var self = this;
+
+        /**
+         * Attach keyboard monitoring to $elem
+         */
+		$elem.keydown(function(e) {
+			self.lastKeyPressed_ = e.keyCode;
+			switch(self.lastKeyPressed_) {
+
+				case 38: // up
+					e.preventDefault();
+					if (self.active_) {
+						self.focusPrev();
+					} else {
+						self.activate();
+					}
+					return false;
+				break;
+
+				case 40: // down
+					e.preventDefault();
+					if (self.active_) {
+						self.focusNext();
+					} else {
+						self.activate();
+					}
+					return false;
+				break;
+
+				case 9: // tab
+				case 13: // return
+					if (self.active_) {
+						e.preventDefault();
+						self.selectCurrent();
+						return false;
+					}
+				break;
+
+				case 27: // escape
+					if (self.active_) {
+						e.preventDefault();
+						self.finish();
+						return false;
+					}
+				break;
+
+				default:
+					self.activate();
+
+			}
+		});
+		$elem.blur(function() {
+			if (self.finishOnBlur_) {
+				setTimeout(function() { self.finish(); }, 200);
+			}
+		});
+
+    };
+
+    $.Autocompleter.prototype.position = function() {
+        var offset = this.dom.$elem.offset();
+		this.dom.$results.css({
+			top: offset.top + this.dom.$elem.outerHeight(),
+			left: offset.left
+		});
+    };
+
+	$.Autocompleter.prototype.cacheRead = function(filter) {
+		var filterLength, searchLength, search, maxPos, pos;
+		if (this.options.useCache) {
+			filter = String(filter);
+			filterLength = filter.length;
+			if (this.options.matchSubset) {
+				searchLength = 1;
+			} else {
+				searchLength = filterLength;
+			}
+			while (searchLength <= filterLength) {
+				if (this.options.matchInside) {
+					maxPos = filterLength - searchLength;
+				} else {
+					maxPos = 0;
+				}
+				pos = 0;
+				while (pos <= maxPos) {
+					search = filter.substr(0, searchLength);
+					if (this.cacheData_[search] !== undefined) {
+						return this.cacheData_[search];
+					}
+					pos++;
+				}
+				searchLength++;
+			}
+		}
+		return false;
+    };
+
+	$.Autocompleter.prototype.cacheWrite = function(filter, data) {
+		if (this.options.useCache) {
+			if (this.cacheLength_ >= this.options.maxCacheLength) {
+				this.cacheFlush();
+			}
+			filter = String(filter);
+			if (this.cacheData_[filter] !== undefined) {
+				this.cacheLength_++;
+			}
+			return this.cacheData_[filter] = data;
+		}
+		return false;
+    };
+
+	$.Autocompleter.prototype.cacheFlush = function() {
+	    this.cacheData_ = {};
+	    this.cacheLength_ = 0;
+    };
+
+	$.Autocompleter.prototype.callHook = function(hook, data) {
+		var f = this.options[hook];
+		if (f && $.isFunction(f)) {
+			return f(data, this);
+		}
+		return false;
+	};
+
+	$.Autocompleter.prototype.activate = function() {
+	    var self = this;
+	    var activateNow = function() {
+	        self.activateNow();
+	    };
+		var delay = parseInt(this.options.delay);
+		if (isNaN(delay) || delay <= 0) {
+			delay = 250;
+		}
+		if (this.keyTimeout_) {
+			clearTimeout(this.keyTimeout_);
+		}
+		this.keyTimeout_ = setTimeout(activateNow, delay);
+	};
+
+    $.Autocompleter.prototype.activateNow = function() {
+		var value = this.dom.$elem.val();
+		if (value !== this.lastProcessedValue_ && value !== this.lastSelectedValue_) {
+			if (value.length >= this.options.minChars) {
+				this.active_ = true;
+				this.lastProcessedValue_ = value;
+				this.fetchData(value);
+			}
+		}
+	};
+
+	$.Autocompleter.prototype.fetchData = function(value) {
+		if (this.options.data) {
+			this.filterAndShowResults(this.options.data, value);
+		} else {
+		    var self = this;
+			this.fetchRemoteData(value, function(remoteData) {
+				self.filterAndShowResults(remoteData, value);
+			});
+		}
+	};
+
+	$.Autocompleter.prototype.fetchRemoteData = function(filter, callback) {
+		var data = this.cacheRead(filter);
+		if (data) {
+			callback(data);
+		} else {
+		    var self = this;
+			this.dom.$elem.addClass(this.options.loadingClass);
+		    var ajaxCallback = function(data) {
+		        var parsed = false;
+		        if (data !== false) {
+    				parsed = self.parseRemoteData(data);
+    				self.cacheWrite(filter, parsed);
+		        }
+				self.dom.$elem.removeClass(self.options.loadingClass);
+				callback(parsed);
+		    };
+			$.ajax({
+                url: this.makeUrl(filter),
+                success: ajaxCallback,
+				error: function() {
+				    ajaxCallback(false);
+				}
+            });
+		}
+	};
+
+    $.Autocompleter.prototype.setExtraParam = function(name, value) {
+        var index = $.trim(String(name));
+        if (index) {
+            if (!this.options.extraParams) {
+                this.options.extraParams = {};
+            }
+            if (this.options.extraParams[index] !== value) {
+                this.options.extraParams[index] = value;
+                this.cacheFlush();
+            }
+        }
+    };
+
+	$.Autocompleter.prototype.makeUrl = function(param) {
+	    var self = this;
+		var paramName = this.options.paramName || 'q';
+		var url = this.options.url;
+		var params = $.extend({}, this.options.extraParams);
+		// If options.paramName === false, append query to url
+		// instead of using a GET parameter
+		if (this.options.paramName === false) {
+		    url += encodeURIComponent(param);
+		} else {
+    		params[paramName] = param;
+		}
+		var urlAppend = [];
+		$.each(params, function(index, value) {
+			urlAppend.push(self.makeUrlParam(index, value));
+		});
+		if (urlAppend.length) {
+    		url += url.indexOf('?') == -1 ? '?' : '&';
+    		url += urlAppend.join('&');
+		}
+		return url;
+	};
+
+	$.Autocompleter.prototype.makeUrlParam = function(name, value) {
+		return String(name) + '=' + encodeURIComponent(value);
+	}
+
+	$.Autocompleter.prototype.parseRemoteData = function(remoteData) {
+		var results = [];
+		var text = String(remoteData).replace('\r\n', '\n');
+		var i, j, data, line, lines = text.split('\n');
+		var value;
+		for (i = 0; i < lines.length; i++) {
+			line = lines[i].split('|');
+			data = [];
+			for (j = 0; j < line.length; j++) {
+				data.push(unescape(line[j]));
+			}
+			value = data.shift();
+			results.push({ value: unescape(value), data: data });
+		}
+		return results;
+	};
+
+	$.Autocompleter.prototype.filterAndShowResults = function(results, filter) {
+		this.showResults(this.filterResults(results, filter), filter);
+	};
+
+	$.Autocompleter.prototype.filterResults = function(results, filter) {
+
+		var filtered = [];
+		var value, data, i, result, type;
+		var regex, pattern, attributes = '';
+
+		for (i = 0; i < results.length; i++) {
+			result = results[i];
+			type = typeof result;
+			if (type === 'string') {
+				value = result;
+				data = {};
+			} else if ($.isArray(result)) {
+				value = result.shift();
+				data = result;
+			} else if (type === 'object') {
+				value = result.value;
+				data = result.data;
+			}
+			value = String(value);
+			// Condition below means we do NOT do empty results
+			if (value) {
+				if (typeof data !== 'object') {
+					data = {};
+				}
+				pattern = String(filter);
+				if (!this.options.matchInside) {
+					pattern = '^' + pattern;
+				}
+				if (!this.options.matchCase) {
+					attributes = 'i';
+				}
+				regex = new RegExp(pattern, attributes);
+				if (regex.test(value)) {
+					filtered.push({ value: value, data: data });
+				}
+			}
+		}
+
+		if (this.options.sortResults) {
+			return this.sortResults(filtered);
+		}
+
+		return filtered;
+
+	};
+
+	$.Autocompleter.prototype.sortResults = function(results) {
+	    var self = this;
+		if ($.isFunction(this.options.sortFunction)) {
+			results.sort(this.options.sortFunction);
+		} else {
+			results.sort(function(a, b) { return self.sortValueAlpha(a, b); });
+		}
+		return results;
+	};
+
+	$.Autocompleter.prototype.sortValueAlpha = function(a, b) {
+		a = String(a.value);
+		b = String(b.value);
+		if (!this.options.matchCase) {
+			a = a.toLowerCase();
+			b = b.toLowerCase();
+		}
+		if (a > b) {
+			return 1;
+		}
+		if (a < b) {
+			return -1;
+		}
+		return 0;
+	};
+
+	$.Autocompleter.prototype.showResults = function(results, filter) {
+	    var self = this;
+		var $ul = $('<ul></ul>');
+		var i, result, $li, extraWidth, first = false, $first = false;
+		var numResults = results.length;
+		for (i = 0; i < numResults; i++) {
+			result = results[i];
+			$li = $('<li>' + this.showResult(result.value, result.data) + '</li>');
+			$li.data('value', result.value);
+			$li.data('data', result.data);
+			$li.click(function() {
+				var $this = $(this);
+				self.selectItem($this);
+			}).mousedown(function() {
+				self.finishOnBlur_ = false;
+			}).mouseup(function() {
+				self.finishOnBlur_ = true;
+			});
+			$ul.append($li);
+			if (first === false) {
+				first = String(result.value);
+				$first = $li;
+				$li.addClass(this.options.firstItemClass);
+			}
+			if (i == numResults - 1) {
+				$li.addClass(this.options.lastItemClass);
+			}
+		}
+
+		// Alway recalculate position before showing since window size or
+		// input element location may have changed. This fixes #14
+		this.position();
+
+		this.dom.$results.html($ul).show();
+		extraWidth = this.dom.$results.outerWidth() - this.dom.$results.width();
+		this.dom.$results.width(this.dom.$elem.outerWidth() - extraWidth);
+		$('li', this.dom.$results).hover(
+			function() { self.focusItem(this); },
+			function() { /* void */ }
+		);
+		if (this.autoFill(first, filter)) {
+			this.focusItem($first);
+		}
+	};
+
+	$.Autocompleter.prototype.showResult = function(value, data) {
+		if ($.isFunction(this.options.showResult)) {
+			return this.options.showResult(value, data);
+		} else {
+			return value;
+		}
+	};
+
+	$.Autocompleter.prototype.autoFill = function(value, filter) {
+		var lcValue, lcFilter, valueLength, filterLength;
+		if (this.options.autoFill && this.lastKeyPressed_ != 8) {
+			lcValue = String(value).toLowerCase();
+			lcFilter = String(filter).toLowerCase();
+			valueLength = value.length;
+			filterLength = filter.length;
+			if (lcValue.substr(0, filterLength) === lcFilter) {
+				this.dom.$elem.val(value);
+				this.selectRange(filterLength, valueLength);
+				return true;
+			}
+		}
+		return false;
+	};
+
+	$.Autocompleter.prototype.focusNext = function() {
+		this.focusMove(+1);
+	};
+
+	$.Autocompleter.prototype.focusPrev = function() {
+		this.focusMove(-1);
+	};
+
+	$.Autocompleter.prototype.focusMove = function(modifier) {
+		var i, $items = $('li', this.dom.$results);
+		modifier = parseInt(modifier);
+		for (var i = 0; i < $items.length; i++) {
+			if ($($items[i]).hasClass(this.selectClass_)) {
+				this.focusItem(i + modifier);
+				return;
+			}
+		}
+		this.focusItem(0);
+	};
+
+	$.Autocompleter.prototype.focusItem = function(item) {
+		var $item, $items = $('li', this.dom.$results);
+		if ($items.length) {
+			$items.removeClass(this.selectClass_).removeClass(this.options.selectClass);
+			if (typeof item === 'number') {
+				item = parseInt(item);
+				if (item < 0) {
+					item = 0;
+				} else if (item >= $items.length) {
+					item = $items.length - 1;
+				}
+				$item = $($items[item]);
+			} else {
+				$item = $(item);
+			}
+			if ($item) {
+				$item.addClass(this.selectClass_).addClass(this.options.selectClass);
+			}
+		}
+	};
+
+	$.Autocompleter.prototype.selectCurrent = function() {
+		var $item = $('li.' + this.selectClass_, this.dom.$results);
+		if ($item.length == 1) {
+			this.selectItem($item);
+		} else {
+			this.finish();
+		}
+	};
+
+	$.Autocompleter.prototype.selectItem = function($li) {
+		var value = $li.data('value');
+		var data = $li.data('data');
+		var displayValue = this.displayValue(value, data);
+		this.lastProcessedValue_ = displayValue;
+		this.lastSelectedValue_ = displayValue;
+		this.dom.$elem.val(displayValue).focus();
+		this.setCaret(displayValue.length);
+		this.callHook('onItemSelect', { value: value, data: data });
+		this.finish();
+	};
+
+	$.Autocompleter.prototype.displayValue = function(value, data) {
+		if ($.isFunction(this.options.displayValue)) {
+			return this.options.displayValue(value, data);
+		} else {
+			return value;
+		}
+	};
+
+	$.Autocompleter.prototype.finish = function() {
+		if (this.keyTimeout_) {
+			clearTimeout(this.keyTimeout_);
+		}
+		if (this.dom.$elem.val() !== this.lastSelectedValue_) {
+			if (this.options.mustMatch) {
+				this.dom.$elem.val('');
+			}
+			this.callHook('onNoMatch');
+		}
+		this.dom.$results.hide();
+		this.lastKeyPressed_ = null;
+		this.lastProcessedValue_ = null;
+		if (this.active_) {
+			this.callHook('onFinish');
+		}
+		this.active_ = false;
+	};
+
+	$.Autocompleter.prototype.selectRange = function(start, end) {
+		var input = this.dom.$elem.get(0);
+		if (input.setSelectionRange) {
+			input.focus();
+			input.setSelectionRange(start, end);
+		} else if (this.createTextRange) {
+			var range = this.createTextRange();
+			range.collapse(true);
+			range.moveEnd('character', end);
+			range.moveStart('character', start);
+			range.select();
+		}
+	};
+
+	$.Autocompleter.prototype.setCaret = function(pos) {
+		this.selectRange(pos, pos);
+	};
+
+    /**
+     * autocomplete plugin
+     */
+    $.fn.autocomplete = function(options) {
+        if (typeof options === 'string') {
+            options = {
+                url: options
+            };
+        }
+        var o = $.extend({}, $.fn.autocomplete.defaults, options);
+		return this.each(function() {
+		    var $this = $(this);
+		    var ac = new $.Autocompleter($this, o);
+		    $this.data('autocompleter', ac);
+		});
+
+	};
+
+    /**
+     * Default options for autocomplete plugin
+     */
+	$.fn.autocomplete.defaults = {
+	    paramName: 'q',
+		minChars: 1,
+		loadingClass: 'acLoading',
+		resultsClass: 'acResults',
+		inputClass: 'acInput',
+		selectClass: 'acSelect',
+		mustMatch: false,
+		matchCase: false,
+		matchInside: true,
+		matchSubset: true,
+		useCache: true,
+		maxCacheLength: 10,
+		autoFill: false,
+		sortResults: true,
+		sortFunction: false,
+		onItemSelect: false,
+		onNoMatch: false
+	};
+
+})(jQuery);

foodoptimizr/templates/add_entry.html

+{% extends "layout.html" %}
+
+{% set selected="add_entry" %}
+
+{% block content %}
+<div class="span-12">
+<form method="POST" action="">
+    <fieldset>
+        <label>Date</label><input autofocus type="date" max="2010-11-20" value="2010-11-20">
+        <label>Red day<input type="radio" name="day"></label>
+        <label>Green day<input type="radio" name="day" checked></label>
+    </fieldset>
+
+    <fieldset>
+        <legend>Weigh-in</legend>
+        <label>Your current weight</label><input type="number" size="3" value="120">
+    </fieldset>
+
+    <fieldset>
+        <legend>Add a food</legend>
+        <input type="search" placeholder="find food">
+        <input type="submit" value="Add a new food">
+    </fieldset>
+
+    <div class="submit">
+        <input type="submit" value="Enter">
+    </div>
+</form>
+</div>
+<div class="span-12 last">
+        <table>
+            <thead>
+                <tr>
+                    <th style="font-size:10pt;">Item</th>
+                    <th style="font-size:10pt;">Sins</th>
+                    <th style="font-size:10pt;">Portions</th>
+                    <th style="font-size:10pt;">Total</th>
+                </tr>
+            </thead>
+            <tbody>
+                <tr>
+                    <td>Wholemeal bread (slice)</td>
+                    <td>5</td>
+                    <td><input type="number" size="2" value="2"></td>
+                    <td>10</td>
+                </tr>
+                <tr>
+                    <td>Cheese (28g)</td>
+                    <td>2</td>
+                    <td><input type="number" size="2" value="3"></td>
+                    <td>6</td>
+                </tr>
+                <tr>
+                    <td>Mushrooms</td>
+                    <td>0</td>
+                    <td>-</td>
+                    <td>0</td>
+                </tr>
+                <tr class="red">
+                    <td>Beef mince</td>
+                    <td>0</td>
+                    <td>-</td>
+                    <td>0</td>
+                </tr>
+                <tr>
+                    <td colspan=3>Your daily limit: <b>12</b></td>
+                    <td><b style="color:#f00;">16</b></td> 
+                </tr>
+            </tbody>
+        </table>
+
+</div>
+{% endblock %}

foodoptimizr/templates/add_food.html

 {% extends "layout.html" %}
 
+{% set selected='add_food' %}
+
 {% block content %}
 
 <form method="POST" action="" class="span-12 append-12">

foodoptimizr/templates/index.html

 {% extends "layout.html" %}
 
+{% set selected='index' %}
+
 {% block content %}
 
 <h2>Dan's diary</h2>
     <tbody>
             {% for i in range(20) %}
             <tr class="{{ ('red', 'green')|random }}">
-                <td><a href="">{{ i + 1 }}.11.2010</a></td>          
+                <td><a href="">{{ 20 - i }}.11.2010</a></td>          
                 <td>{{ range(15)|random }}</td>
                 <td>120</td>
             </tr>

foodoptimizr/templates/layout.html

     <link rel="stylesheet" href="{{ url_for('.static', filename='css/blueprint/screen.css') }}" media="print" />
     <!--[if IE]><link rel="stylesheet" href="{{ url_for('.static', filename='css/blueprint/ie.css') }}" /><![endif]--> 
     <link rel="stylesheet" href="{{ url_for('.static', filename='css/foodoptimizr.css') }}" />
+    <script type="text/javascript" src="https://www.google.com/jsapi?key=ABQIAAAApkvnuvkv2qzkTZWfHB1_3xT2yXp_ZAY8_ufC3CFXhHIE1NvwkxT7Pyq2orpHXVNBVQhqPJ02iAlFmw"></script>
 </head>
 <body>
     <div class="container">
 
         <div class="span-24 navigation">
             <ul>
-            	<li class="selected">
-            		<a href="">Calendar</a>
+                <li{% if selected=='index' %} class="selected"{% endif %}>
+                <a href="{{ url_for('main.index') }}">Calendar</a>
             	</li>
-            	<li>
-            		<a href="">Make an entry</a>
+            	<li{% if selected=='add_entry' %} class="selected"{% endif %}>
+                <a href="{{ url_for('main.add_entry') }}">Make an entry</a>
             	</li>
-                <li>
+                <li{% if selected=='add_food' %} class="selected"{% endif %}>
                     <a href="{{ url_for('main.add_food') }}">Add a new food</a>
                 </li>
                <li>
-                    <a href="">Add a new recipe</a>
-                </li>
-                <li>
-                    <input type="text" placeholder="Find a food">
-                </li>
- 
-                <li>
-                    <input type="text" placeholder="Find a recipe">
+                    <input type="search" name="q" placeholder="Find a food">
                 </li>
             </ul>
         </div>
         </div><!-- end of footer -->
 
     </div><!-- end of container --> 
+    <script type="text/javascript">
+    google.load("jquery", "1.4.1"); 
+    google.load("jqueryui", "1.8.6");
+    </script>
 </body>
 </html>

foodoptimizr/views/main.py

 @main.route("/add-food/")
 def add_food():
     return render_template("add_food.html")
+
+
+@main.route("/add-entry/")
+def add_entry():
+    return render_template("add_entry.html")