Meeskond "Head isu": Difference between revisions
m →Screenshots: add cafes list |
|||
(13 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
== | ==Team== | ||
* Liisa Viljaste (Lember) | * Liisa Viljaste (Lember) | ||
* Kalev Paju | * Kalev Paju | ||
Line 5: | Line 5: | ||
* Katri Pokats | * Katri Pokats | ||
==Summary (est)== | |||
Kuna oli teada kitsas ajapiirang, siis sai võetud kinni õpetaja pakutud teemast - kohvikuteema. | |||
Algsest XML-st sai ka vastav andmemudel. Veebiteenusega muidugi sellist 1:1 väljundit pakkuda ei saa, kuna veebiteenusel ei saanud atribuute väljundisse (vähemalt meie näites). | |||
Kitsas ajapiirang ei lasknud teha valmis kogu funktsionaalsust, mis sai algselt mõeldud. | |||
Põhiline funktsionaalsus sai klientrakendustesse juurutatud, kuid administreerimise poolel ''desktop''-rakendusel ei saanud kõike teostatud. | |||
Tagantjärele mõeldes oleks pidanud skoopi kokku tõmbama ja mitte mõtlema nii laiaks süsteemi. | |||
Tegemise käigus sai omandatud oskusi Visual Studio programmiga ja saime teada, et on ka .Net rakendustele teenused olemas, mida saab tasuta kasutada. Nii saime oma MSSQL andmebaasi, WSDL-teenuse ja veebiklientrakenduse sellele teenusele üles panna. | |||
Tiimivahelise peamiseks suhtluskanaliks oli e-post, kuid sai ka kommenteeritud ja püstitatud ülesandeid vastavas keskkonnas, milleks valisime Springloopsi ''ticket''-süsteemi, mis toetas ka versioonihaldust ja oli autentitav. Samuti sai kord nädalas loenguvaheajal lühikesi püstijala koosolekuid peetud, kus jaagasime omavahel tööülesandeid. | |||
Saime teada et .Net rakenduse tegemine ei olegi nii raske kui seda algselt ette kujutasime. Kindlasti oli üllatus kui lihtsalt sai tehtud MSSQLi andmetest läbi LINQ veebiteenus. | |||
==Source files== | |||
Webservices: http://headisu.somee.com/app/webservice-ver0.2.zip | |||
Web application: http://headisu.somee.com/app/KohvikuVeebiKlient.zip | |||
Windows client for admin: http://headisu.somee.com/app/WpfHeadIsu-win_klient.zip | |||
== Used services == | |||
* For version control and team discussion we used [http://www.slsapp.com Springloops] | |||
For one project this is free for use | |||
Used [http://tortoisesvn.net/ TortoiseSVN] in Windows to commit and update to there | |||
* For C# online hosting we used FREE.NET HOSTING package from http://www.somee.com/FreeAspNetHosting.aspx | |||
From there we serve private AdminService, public Cafes service and Web application | |||
Web application: http://headisu.somee.com/ | |||
== XML == | == XML == | ||
Line 475: | Line 508: | ||
==WebService methods== | ==WebService methods== | ||
===Source=== | ===Source=== | ||
http://headisu.somee.com/app/webservice-ver0. | http://headisu.somee.com/app/webservice-ver0.2.zip | ||
===Public methods=== | ===Public methods=== | ||
Service location: ''http://headisu.somee.com/Cafes.asmx | Service location: ''http://headisu.somee.com/Cafes.asmx'' | ||
*getCafeMenus | *getCafeMenus | ||
Line 532: | Line 565: | ||
*saveCountry | *saveCountry | ||
For admin: add/update country entry | For admin: add/update country entry | ||
*saveState | |||
For admin: add/update state entry | |||
*saveCity | |||
For admin: add/update city entry | |||
*saveFood | *saveFood | ||
For admin: add/update food entry | For admin: add/update food entry | ||
Line 545: | Line 582: | ||
* for administrating only | * for administrating only | ||
* using AdminService.asmx | * using AdminService.asmx | ||
WPF app setup: http://headisu.somee.com/app/WPFApp.zip | |||
Username: admin | |||
Pwd: ????????? | |||
===Screenshots=== | ===Screenshots=== | ||
[[File:Headisu_logging-in.png||400px]] | [[File:Headisu_logging-in.png||400px]] | ||
Line 554: | Line 594: | ||
* using Cafes.asmx | * using Cafes.asmx | ||
Web application is public at: | |||
http://headisu.somee.com/ | |||
Web application startup preview: <br> | |||
[[File:act_screenshot.jpg||300px]] | |||
Web application selection preview: <br> | |||
[[File:act_screenshot_selected.jpg||300px]] | |||
Initial design sketch for web application of daily menu display that was not fully realised due to time constraints: <br> | |||
[[File:plan_Screenshot.jpg||300px]] |
Latest revision as of 14:40, 3 June 2011
Team
- Liisa Viljaste (Lember)
- Kalev Paju
- Elvin Risti
- Katri Pokats
Summary (est)
Kuna oli teada kitsas ajapiirang, siis sai võetud kinni õpetaja pakutud teemast - kohvikuteema.
Algsest XML-st sai ka vastav andmemudel. Veebiteenusega muidugi sellist 1:1 väljundit pakkuda ei saa, kuna veebiteenusel ei saanud atribuute väljundisse (vähemalt meie näites).
Kitsas ajapiirang ei lasknud teha valmis kogu funktsionaalsust, mis sai algselt mõeldud.
Põhiline funktsionaalsus sai klientrakendustesse juurutatud, kuid administreerimise poolel desktop-rakendusel ei saanud kõike teostatud.
Tagantjärele mõeldes oleks pidanud skoopi kokku tõmbama ja mitte mõtlema nii laiaks süsteemi.
Tegemise käigus sai omandatud oskusi Visual Studio programmiga ja saime teada, et on ka .Net rakendustele teenused olemas, mida saab tasuta kasutada. Nii saime oma MSSQL andmebaasi, WSDL-teenuse ja veebiklientrakenduse sellele teenusele üles panna.
Tiimivahelise peamiseks suhtluskanaliks oli e-post, kuid sai ka kommenteeritud ja püstitatud ülesandeid vastavas keskkonnas, milleks valisime Springloopsi ticket-süsteemi, mis toetas ka versioonihaldust ja oli autentitav. Samuti sai kord nädalas loenguvaheajal lühikesi püstijala koosolekuid peetud, kus jaagasime omavahel tööülesandeid.
Saime teada et .Net rakenduse tegemine ei olegi nii raske kui seda algselt ette kujutasime. Kindlasti oli üllatus kui lihtsalt sai tehtud MSSQLi andmetest läbi LINQ veebiteenus.
Source files
Webservices: http://headisu.somee.com/app/webservice-ver0.2.zip Web application: http://headisu.somee.com/app/KohvikuVeebiKlient.zip Windows client for admin: http://headisu.somee.com/app/WpfHeadIsu-win_klient.zip
Used services
- For version control and team discussion we used Springloops
For one project this is free for use Used TortoiseSVN in Windows to commit and update to there
- For C# online hosting we used FREE.NET HOSTING package from http://www.somee.com/FreeAspNetHosting.aspx
From there we serve private AdminService, public Cafes service and Web application Web application: http://headisu.somee.com/
XML
Teise tiimi arvustus meie XML-le: https://wiki.itcollege.ee/index.php/Talk:Meeskond_%22Head_isu%22
XML
<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xsl" href="kohvik.xslt"?>
<!--
itkheadisu2011.slsapp.com
http://itkheadisu2011.slsapp.com/source/itkheadisu
Elvin Risti eristi[at]itcollege.ee
Liisa Lember lilember[at]itcollege.ee
Kalev Paju kpaju[at]itcollege.ee
Katri Pokats
-->
<cafemenus>
<cafes>
<cafe id="1">
<name>Reval</name>
<address id="1">
<coordinates long="59.430756" lat="24.74565" />
<street>Pärnu mnt</street>
<house>271</house>
<houseExtra />
<city>Tallinn</city>
<!-- country - ISO 3166-1 alpha-2 code - http://en.wikipedia.org/wiki/ISO_3166-2 -->
<country>EE</country>
<zip>10141</zip>
<!-- opened is per location -->
<opened year="2011">
<weekdays>
<!-- http://en.wikipedia.org/wiki/ISO_8601 -->
<weekday begin="09:00:00+03:00" until="19:00:00+03:00">1</weekday>
<weekday begin="09:00:00+03:00" until="19:00:00+03:00">2</weekday>
<weekday begin="09:00:00+03:00" until="19:00:00+03:00">3</weekday>
<weekday begin="09:00:00+03:00" until="19:00:00+03:00">4</weekday>
<weekday begin="09:00:00+03:00" until="21:00:00+03:00">5</weekday>
<weekday begin="10:00:00+03:00" until="15:00:00+03:00">6</weekday>
<weekday isclosed="true">7</weekday>
</weekdays>
<exceptions>
<date isclosed="true">2011-01-01</date>
<date isclosed="true">2011-02-24</date>
<date begin="12:00:00+03:00" until="19:00:00+03:00">2011-02-25</date>
</exceptions>
</opened>
<comment lang="et">Asume kesklinnas Pärnu mnt ja Tatari nurgal.</comment>
</address>
</cafe>
<cafe id="2">
<name>Reval 2</name>
<address id="3">
<coordinates long="59.430756" lat="24.74565" />
<street>Pärnu mnt</street>
<house>272</house>
<houseExtra />
<city>Tallinn</city>
<!-- country - ISO 3166-1 alpha-2 code - http://en.wikipedia.org/wiki/ISO_3166-2 -->
<country>EE</country>
<zip>10141</zip>
<!-- opened is per location -->
<opened year="2011">
<weekdays>
<!-- http://en.wikipedia.org/wiki/ISO_8601 -->
<weekday begin="09:00:00+03:00" until="19:00:00+03:00">1</weekday>
<weekday begin="09:00:00+03:00" until="19:00:00+03:00">2</weekday>
<weekday begin="09:00:00+03:00" until="19:00:00+03:00">3</weekday>
<weekday begin="09:00:00+03:00" until="19:00:00+03:00">4</weekday>
<weekday begin="09:00:00+03:00" until="21:00:00+03:00">5</weekday>
<weekday begin="10:00:00+03:00" until="15:00:00+03:00">6</weekday>
<weekday isclosed="true">7</weekday>
</weekdays>
</opened>
<comment lang="et">Asume kesklinnas Pärnu mnt ja Tatari nurgal.</comment>
</address>
</cafe>
</cafes>
<menus>
<menuscafe cafeid="1">
<!-- currency - ISO 4217 - http://en.wikipedia.org/wiki/ISO_4217 -->
<currency>EUR</currency>
<!-- @lang - ISO 639-1 - http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes -->
<menu lang="et">
<item type="food" subtype="roast">
<name>Kiievi kotlett</name>
<!-- @comment - simple comment -->
<price comment="väike">2</price>
<price comment="suur">3</price>
<!-- availability: true/false -->
<availability>true</availability>
<comment>Väiksel portsul üks kotlett, suurel kolm.</comment>
</item>
<item type="drink">
<name>Piim</name>
<!-- @unit: string,litres -->
<price quantity="0.33" unit="l">0.5</price>
<availability>true</availability>
<comment />
</item>
<item type="food" subtype="dessert">
<name>Martsipani tort</name>
<!-- @comment - simple comment -->
<price comment="viil">1</price>
<price quantity="0.8" unit="kg">9</price>
<!-- availability: true/false -->
<availability>true</availability>
<comment>Tordil on valge jänese pilt.</comment>
</item>
</menu>
<benefits>
<benefit isprecent="true" name="ISIC kaart">5</benefit>
<benefit isprecent="true" name="Püsikliendi soodustus">10</benefit>
<benefit isprecent="false" name="Kampaania X soodustus">1.5</benefit>
</benefits>
</menuscafe>
</menus>
</cafemenus>
XML Schema
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="cafemenus">
<xs:complexType>
<xs:sequence>
<xs:element name="cafes">
<xs:complexType>
<xs:sequence>
<xs:element name="cafe" maxOccurs="unbounded" >
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="address" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="coordinates" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="long" type="xs:decimal" use="required" />
<xs:attribute name="lat" type="xs:decimal" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="street" type="xs:string" />
<xs:element name="house" type="xs:unsignedInt" />
<xs:element name="houseExtra" type="xs:string" />
<xs:element name="city" type="xs:string" />
<xs:element name="country" type="xs:string" />
<xs:element name="zip" type="xs:unsignedShort" />
<xs:element name="opened" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="weekdays">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="7" maxOccurs="7" name="weekday">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:unsignedByte">
<xs:attribute name="begin" type="xs:time" use="optional" />
<xs:attribute name="until" type="xs:time" use="optional" />
<xs:attribute name="isclosed" type="xs:boolean" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="exceptions" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="date">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:date">
<xs:attribute name="isclosed" type="xs:boolean" use="optional" />
<xs:attribute name="begin" type="xs:time" use="optional" />
<xs:attribute name="until" type="xs:time" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="year" type="xs:unsignedShort" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="comment">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="lang" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:unsignedInt" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="menus">
<xs:complexType>
<xs:sequence>
<xs:element name="menuscafe" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="currency" type="xs:string" />
<xs:element name="menu">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="item">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element maxOccurs="unbounded" name="price">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="comment" type="xs:string" use="optional" />
<xs:attribute name="quantity" type="xs:decimal" use="optional" />
<xs:attribute name="unit" type="xs:string" use="optional" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="availability" type="xs:boolean" />
<xs:element name="comment" type="xs:string" />
</xs:sequence>
<xs:attribute name="type" type="xs:string" use="required" />
<xs:attribute name="subtype" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="lang" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:element name="benefits" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="benefit">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="isprecent" type="xs:boolean" use="required" />
<xs:attribute name="name" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="cafeid" type="xs:unsignedInt" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
XSLT
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h1>Kohvikud</h1>
<xsl:apply-templates select="/cafemenus/cafes/cafe" />
</body>
</html>
</xsl:template>
<xsl:template match="/cafemenus/cafes/cafe">
<h2><xsl:value-of select="name"/></h2>
<div class="addresses">
<xsl:apply-templates select="address" />
</div>
<div class="menus" style="clear:both;">
<xsl:call-template name="show_menus">
<xsl:with-param name="cafe_id" select="@id"/>
</xsl:call-template>
</div>
<hr />
</xsl:template>
<xsl:template match="address">
<!-- variable "thisyear" should be come from querystring, currently we set it statically -->
<xsl:variable name="thisyear" select="2011" />
<div class="address" style="clear:both;">
<xsl:choose>
<xsl:when test="coordinates and coordinates/@long!='' and coordinates/@lat!=''">
<img border="0" style="float:right;">
<xsl:attribute name="src">http://maps.google.com/maps/api/staticmap?zoom=16&size=200x200&maptype=roadmap&markers=color:red|label:A|<xsl:value-of select="coordinates/@long" />,<xsl:value-of select="coordinates/@lat" />&sensor=false</xsl:attribute>
</img>
</xsl:when>
</xsl:choose>
<xsl:value-of select="street" /> 
<xsl:value-of select="house" />
<xsl:choose>
<xsl:when test="houseExtra!=''">, <xsl:value-of select="houseExtra" /></xsl:when>
</xsl:choose>, <xsl:value-of select="city" /><br />
<xsl:choose>
<xsl:when test="opened and opened/@year = $thisyear">
<xsl:call-template name="show_opened">
<xsl:with-param name="opened" select="opened[@year = $thisyear]"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</div>
</xsl:template>
<xsl:template name="show_opened">
<xsl:param name="opened" />
<strong>Oleme avatud:</strong>
<table border="1" cellpadding="0">
<tr bgcolor="#9acd32">
<th>päev</th>
<th>alates</th>
<th>kuni</th>
</tr>
<xsl:for-each select="$opened/weekdays/weekday">
<tr>
<td>
<xsl:call-template name="getShortDayname">
<xsl:with-param name="weekday" select="."/>
</xsl:call-template>
</td>
<xsl:choose>
<xsl:when test="@isclosed and @isclosed = 'true'">
<td colspan="2">suletud</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:value-of select="substring(@begin, 1, 2)" />:<xsl:value-of select="substring(@begin, 4, 2)" />
</td>
<td>
<xsl:value-of select="substring(@until, 1, 2)" />:<xsl:value-of select="substring(@until, 4, 2)" />
</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
<xsl:choose>
<xsl:when test="$opened/exceptions and $opened/exceptions/date">
<strong>Erandid:</strong>
<table border="1" cellpadding="0">
<tr bgcolor="#9acd32">
<th>päev</th>
<th>alates</th>
<th>kuni</th>
</tr>
<xsl:for-each select="$opened/exceptions/date">
<tr>
<td>
<xsl:value-of select="." />
</td>
<xsl:choose>
<xsl:when test="@isclosed and @isclosed = 'true'">
<td colspan="2">suletud</td>
</xsl:when>
<xsl:otherwise>
<td>
<xsl:value-of select="substring(@begin, 1, 2)" />:<xsl:value-of select="substring(@begin, 4, 2)" />
</td>
<td>
<xsl:value-of select="substring(@until, 1, 2)" />:<xsl:value-of select="substring(@until, 4, 2)" />
</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template name="show_menus" match="/cafemenus/menus">
<xsl:param name="cafe_id" />
<xsl:choose>
<xsl:when test="/cafemenus/menus/menuscafe[@cafeid=$cafe_id]">
<xsl:variable name="currency">
<xsl:value-of select="/cafemenus/menus/menuscafe[@cafeid=$cafe_id]/currency" />
</xsl:variable>
<h3>Menüü</h3>
<table border="1">
<thead>
<tr bgcolor="#9acd32">
<th>Tüüp</th>
<th>Nimetus</th>
<th>Hinnad</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="/cafemenus/menus/menuscafe[@cafeid=$cafe_id]/menu/item">
<tr>
<td>
(<xsl:value-of select="@type" />
<xsl:choose>
<xsl:when test="@subtype">
--> <xsl:value-of select="@subtype" />
</xsl:when>
</xsl:choose>)
</td>
<td>
<xsl:value-of select="name" />
</td>
<td>
<xsl:value-of select="price" /> <xsl:value-of select="$currency"/>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</xsl:when>
<xsl:otherwise>
<h2>Menüü puudub</h2>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="getShortDayname">
<xsl:param name="weekday" />
<xsl:choose>
<xsl:when test="$weekday = 1">E</xsl:when>
<xsl:when test="$weekday = 2">T</xsl:when>
<xsl:when test="$weekday = 3">K</xsl:when>
<xsl:when test="$weekday = 4">N</xsl:when>
<xsl:when test="$weekday = 5">R</xsl:when>
<xsl:when test="$weekday = 6">L</xsl:when>
<xsl:when test="$weekday = 7">P</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Result preview
HeadIsu ERD
WebService methods
Source
http://headisu.somee.com/app/webservice-ver0.2.zip
Public methods
Service location: http://headisu.somee.com/Cafes.asmx
- getCafeMenus
- getCafeWithAddresses
- getCafes
- getCities
- getCountries
- getMenu
- getStates
Restricted methods
Service location: http://headisu.somee.com/AdminService.asmx
- IsRole
Is user in role
- deleteCafe
For admin: delete cafe entry
- deleteFood
For admin: delete food entry
- deleteFoodType
For admin: delete food's type
- deleteMenu
For admin: delete menu entry
- getCafeMenus
- getCafeWithAddresses
- getCafes
- getCities
- getCountries
- getDayLog
For admin: get log for asked date
- getMenu
- getRolesList
Returns roles list
- getStates
- getTodayLog
For admin: get log only for today
- isAdmin
Has user admin role
- logout
logout user
- removeBenefit
For admin: remove benefit name
- removeCafeBenefit
For admin: remove cafe's benefit
- removeFoodMenu
For admin: remove food from menu
- saveBenefit
For admin: add/update benefit name
- saveCafe
For admin: add/update cafe entry
- saveCafeBenefit
For admin: add/update cafe's benefit
- saveCountry
For admin: add/update country entry
- saveState
For admin: add/update state entry
- saveCity
For admin: add/update city entry
- saveFood
For admin: add/update food entry
- saveFoodMenu
For admin: add/update food to menu
- saveFoodType
For admin: add/update food's type
- saveMenu
For admin: add/update menu entry
Windows Application
- made with WPF
- for administrating only
- using AdminService.asmx
WPF app setup: http://headisu.somee.com/app/WPFApp.zip Username: admin Pwd: ?????????
Screenshots
Web application
- using Cafes.asmx
Web application is public at:
http://headisu.somee.com/
Web application startup preview:
Web application selection preview:
Initial design sketch for web application of daily menu display that was not fully realised due to time constraints: