summaryrefslogtreecommitdiff
path: root/demos/time-tracker/protected/pages
diff options
context:
space:
mode:
Diffstat (limited to 'demos/time-tracker/protected/pages')
-rw-r--r--demos/time-tracker/protected/pages/Docs/TopicList.tpl2
-rw-r--r--demos/time-tracker/protected/pages/Docs/WritingUnitTest.page43
-rw-r--r--demos/time-tracker/protected/pages/Docs/config.xml12
-rw-r--r--demos/time-tracker/protected/pages/Docs/db.pngbin26879 -> 26521 bytes
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/Login.page38
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/Login.php53
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/Logout.page0
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/Logout.php34
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/MainLayout.php7
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl40
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/SiteMap.php8
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/SiteMap.tpl43
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/UserCreate.page65
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/UserCreate.php78
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/UserList.page3
-rw-r--r--demos/time-tracker/protected/pages/TimeTracker/config.xml24
-rw-r--r--demos/time-tracker/protected/pages/Welcome.page168
17 files changed, 598 insertions, 20 deletions
diff --git a/demos/time-tracker/protected/pages/Docs/TopicList.tpl b/demos/time-tracker/protected/pages/Docs/TopicList.tpl
index 5fa2adb5..53243578 100644
--- a/demos/time-tracker/protected/pages/Docs/TopicList.tpl
+++ b/demos/time-tracker/protected/pages/Docs/TopicList.tpl
@@ -14,7 +14,7 @@
<div>Testing Business Code</div>
<ul>
- <li><a href="?page=Docs.CreateBusinessCode">Create Business Code</a></li>
+ <li><a href="?page=Docs.DatabaseDesign">Database Design</a></li>
<li><a href="?page=Docs.UsingSQLMap">Using SQLMap Data Mapper</a></li>
<li><a href="?page=Docs.UserClassAndExceptions">User Class and Exceptions</a></li>
<li><a href="?page=Docs.MoreTests">More Tests</a></li>
diff --git a/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page b/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page
index 32c7bc79..77bdcbe6 100644
--- a/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page
+++ b/demos/time-tracker/protected/pages/Docs/WritingUnitTest.page
@@ -1,13 +1,19 @@
<com:TContent ID="body">
<h1>Writing a Unit Test</h1>
+<p>Before we begin to write our business logic and code, we shall
+proceed with the path of <a href="http://tdd.com">test driven development</a> (TDD), or at least take
+some part of that process.</p>
+
<p>Unit testing is a useful tool when we want to start to test
our individual business logic classes.
- The <tt>tests/unit</tt> directory will be used to hold the unit test cases and <tt>tests/functional</tt> directory
-to hold the function test cases.
+ The <tt>tests/unit</tt> directory will be used to hold the unit test
+ cases and <tt>tests/functional</tt> directory
+ to hold the function test cases.
</p>
<h2>Write a unit test case</h2>
-<p>We will start be writing a very simple unit test case.</p>
+<p>We will start be writing a very simple unit test case. Notice
+that we are writing the test case <b>first</b>.</p>
<com:TTextHighlighter Language="php" CssClass="source">
&lt;?php
class ProjectTestCase extends UnitTestCase
@@ -29,14 +35,16 @@ directory.</p>
<img src="<%~ unit_test1.png %>" class="figure"/>
<div class="caption"><b>Figure 1:</b> Unit test runner</div>
</p>
-<p>Clicking on the <tt>ProjectTestCase.php</tt> like, you should see
+<p>Clicking on the <tt>ProjectTestCase.php</tt> link, you should see
<img src="<%~ unit_test2.png %>" class="figure"/>
<div class="caption"><b>Figure 2:</b> Unit test failure</div>
</p>
<h2>Smallest step to make the test pass.</h2>
-<p>Obviously, we need create the class <tt>Project</tt>, so lets define the class.</p>
+<p>Since we only wrote the test case and nothing else we expected
+that the test case will fail at some point. Obviously, we need create
+a class <tt>Project</tt>, so lets define the <tt>Project</tt> class.</p>
<com:TTextHighlighter Language="php" CssClass="source">
&lt;?php
class Project
@@ -44,15 +52,11 @@ class Project
}
?&gt;
</com:TTextHighlighter>
-<p>Save the above code as <tt>time-tracker/protected/pages/APP_CODE/Project.php</tt>.
- Where the <tt>APP_CODE</tt> directory will contain most of your business logic code for the Time Tracker application.</p>
-<p>We also need to add the following line in our test case so as to include the <tt>Project</tt> class file when running the tests.</p>
-
-<p class="note">
-The statement <tt>Prado::using('Application.APP_CODE.Project')</tt> basically
-loads the <tt>Project.php</tt> class file. It assumes that a class name <tt>Project</tt> has filename <tt>Project.php</tt>.
-For futher details regarding <tt>Prado::using</tt> can be found in <a href="http://www.pradosoft.com/demos/quickstart/index.php?page=Fundamentals.Components#704">Prado Namespaces</a> documentation.
-</p>
+<p>We save the above code as <tt>time-tracker/protected/pages/APP_CODE/Project.php</tt>.
+ Where the <tt>APP_CODE</tt> directory will contain most of the business logic code
+ for the Time Tracker application.</p>
+<p>Now, we also need to add the following line in our test case so as to
+include the <tt>Project</tt> class file when running the tests.</p>
<com:TTextHighlighter Language="php" CssClass="source">
&lt;?php
@@ -63,11 +67,20 @@ class ProjectTestCase extends UnitTestCase
}
?&gt;
</com:TTextHighlighter>
+
+<div class="info"><b>Info:</b>
+The statement <tt>Prado::using('Application.APP_CODE.Project')</tt> basically
+loads the <tt>Project.php</tt> class file. It assumes that a class name <tt>Project</tt> has filename <tt>Project.php</tt>.
+For futher details regarding <tt>Prado::using</tt> can be found in <a href="http://www.pradosoft.com/demos/quickstart/index.php?page=Fundamentals.Components#704">Prado Namespaces</a> documentation.
+</div>
+
<p>Run the unit test runner again, we see that the test has passed.
<img src="<%~ unit_test3.png %>" class="figure"/>
<div class="caption"><b>Figure 3:</b> Unit test success</div>
</p>
<p>
-Later on, we shall write more test cases. See the SimpleTest documentation for detailed tutorial on writing test cases.</p>
+Later on, we shall write more test cases. See the
+<a href="http://www.lastcraft.com/simple_test.php">SimpleTest documentation</a>
+for detailed tutorial on writing test cases.</p>
</com:TContent> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/Docs/config.xml b/demos/time-tracker/protected/pages/Docs/config.xml
index da4d3bfc..e8fdc3fe 100644
--- a/demos/time-tracker/protected/pages/Docs/config.xml
+++ b/demos/time-tracker/protected/pages/Docs/config.xml
@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
- <paths>
- <alias id="Pages" path="." />
- </paths>
- <pages MasterClass="Application.pages.Docs.Layout" />
+
+ <modules>
+ <module id="theme"
+ class="System.Web.UI.TThemeManager"
+ BasePath="Quickstart.themes"
+ BaseUrl="../quickstart/themes" />
+ </modules>
+ <pages MasterClass="Application.pages.Docs.Layout" Theme="PradoSoft"/>
</configuration> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/Docs/db.png b/demos/time-tracker/protected/pages/Docs/db.png
index f2209ef4..efdcc1e5 100644
--- a/demos/time-tracker/protected/pages/Docs/db.png
+++ b/demos/time-tracker/protected/pages/Docs/db.png
Binary files differ
diff --git a/demos/time-tracker/protected/pages/TimeTracker/Login.page b/demos/time-tracker/protected/pages/TimeTracker/Login.page
new file mode 100644
index 00000000..dbc16de1
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/Login.page
@@ -0,0 +1,38 @@
+<%@ Title="My Company - Time Tracker - Site Logon" %>
+<com:TContent ID="Main">
+<h2>Time Tracker Website Login</h2>
+
+<fieldset class="login"><legend>User Login</legend>
+ <div class="username">
+ <com:TLabel ForControl="username" Text="User Name:" />
+ <span class="required">*</span>
+ <com:TTextBox ID="username" />
+ <com:TRequiredFieldValidator
+ ControlToValidate="username"
+ ErrorMessage="Please enter your username."
+ ControlCssClass="required-field" />
+ </div>
+ <div class="password">
+ <com:TLabel ForControl="password" Text="Password:" />
+ <span class="required">*</span>
+ <com:TTextBox ID="password" TextMode="Password" />
+ <com:TRequiredFieldValidator
+ ControlToValidate="password"
+ ErrorMessage="Please enter your password."
+ ControlCssClass="required-field" />
+ </div>
+ <div class="remember">
+ <com:TCheckBox ID="remember" Text="Remember me next time" />
+ </div>
+ <com:TCustomValidator
+ ControlToValidate="password"
+ Display="Dynamic"
+ Text="Your login attempt was not successful. Please try again."
+ OnServerValidate="validateUser" />
+ <div class="signin">
+ <com:TButton Text="Log In" OnClick="doLogin" />
+ </div>
+ <div class="create">
+ <a href="?page=TimeTracker.UserCreate">Create New User</a>
+ </fieldset>
+ </com:TContent> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/Login.php b/demos/time-tracker/protected/pages/TimeTracker/Login.php
new file mode 100644
index 00000000..376953a5
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/Login.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Login Page class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+
+/**
+ * Login page class.
+ *
+ * Validate the user credentials and redirect to requested page
+ * if successful.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
+class Login extends TPage
+{
+ /**
+ * Validates the username and password.
+ * @param TControl custom validator that created the event.
+ * @param TServerValidateEventParameter validation parameters.
+ */
+ public function validateUser($sender, $param)
+ {
+ $authManager=$this->Application->getModule('auth');
+ if(!$authManager->login($this->username->Text,$this->password->Text))
+ $param->IsValid=false;;
+ }
+
+ /**
+ * Redirect to the requested page if login is successful.
+ * @param TControl button control that created the event.
+ * @param TEventParameter event parameters.
+ */
+ public function doLogin($sender, $param)
+ {
+ if($this->Page->IsValid)
+ {
+ $auth = $this->Application->getModule('auth');
+ $this->Response->redirect($auth->getReturnUrl());
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/Logout.page b/demos/time-tracker/protected/pages/TimeTracker/Logout.page
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/Logout.page
diff --git a/demos/time-tracker/protected/pages/TimeTracker/Logout.php b/demos/time-tracker/protected/pages/TimeTracker/Logout.php
new file mode 100644
index 00000000..08fdfaf6
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/Logout.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Logout class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+
+/**
+ * Logout page class.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
+class Logout extends TPage
+{
+ /**
+ * Logs out the current user and redirect to default page.
+ */
+ function onLoad($param)
+ {
+ $this->Application->getModule('auth')->logout();
+ $url = $this->Service->constructUrl($this->Service->DefaultPage);
+ $this->Response->redirect($url);
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/MainLayout.php b/demos/time-tracker/protected/pages/TimeTracker/MainLayout.php
new file mode 100644
index 00000000..253d6c03
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/MainLayout.php
@@ -0,0 +1,7 @@
+<?php
+
+class MainLayout extends TTemplateControl
+{
+}
+
+?> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl b/demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl
new file mode 100644
index 00000000..2d8bad44
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/MainLayout.tpl
@@ -0,0 +1,40 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<com:THead Title="My Company - Time Tracker - Log" />
+<body>
+
+<com:TForm>
+
+<h1 class="heading">
+ <a href="index.php">My Company
+ <span class="subheading">Time Tracker</span>
+ </a>
+</h1>
+<div class="minheading">
+<h2 class="login">
+ <com:TLabel CssClass="name" Text="Welcome <%= $this->User->Name %>" />
+ <com:THyperLink
+ Text="Login"
+ NavigateUrl=<%= $this->Service->constructUrl('TimeTracker.Login') %>
+ Visible=<%= $this->User->getIsGuest() %> />
+ <com:THyperLink
+ Text="Logout"
+ NavigateUrl=<%= $this->Service->constructUrl('TimeTracker.Logout') %>
+ Visible=<%= !$this->User->getIsGuest() %> />
+</h2>
+<h2 class="help"><a href="?page=Welcome">Help</a></h2>
+<h2 class="guide"><a href="?page=Docs.Home">Implementation Guide</a></h2>
+</div>
+
+<com:Application.pages.TimeTracker.SiteMap
+ Visible=<%= !$this->User->getIsGuest() %> />
+
+<div class="main">
+<com:TContentPlaceHolder ID="Main" />
+</div>
+
+</com:TForm>
+
+</body>
+</html> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/SiteMap.php b/demos/time-tracker/protected/pages/TimeTracker/SiteMap.php
new file mode 100644
index 00000000..0b71eb68
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/SiteMap.php
@@ -0,0 +1,8 @@
+<?php
+
+class SiteMap extends TTemplateControl
+{
+
+}
+
+?> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/SiteMap.tpl b/demos/time-tracker/protected/pages/TimeTracker/SiteMap.tpl
new file mode 100644
index 00000000..48187b52
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/SiteMap.tpl
@@ -0,0 +1,43 @@
+<com:TPanel CssClass="sitemap" Visible="true">
+<ul class="level1">
+ <li class="active"><a class="menuitem" href="?page=TimeTracker.TimeEntry">Log</a>
+ </li>
+ <li><span class="menuitem">Reports</span>
+ <ul class="level2">
+ <li><a href="?page=TimeTracker.ReportProject">Project Reports</a></li>
+ <li><a href="?page=TimeTracker.ReportResource">Resources Report</a></li>
+ </ul>
+ </li>
+ <li>
+ <span class="menuitem">Projects</span>
+ <ul class="level2">
+ <li><a href="?page=TimeTracker.ProjectDetails">Create New Project</a></li>
+ <li><a href="?page=TimeTracker.ProjectList">List Projects</a></li>
+ </ul>
+ </li>
+ <li>
+ <span class="menuitem">Adminstration</span>
+ <ul class="level2">
+ <li><a href="?page=TimeTracker.UserCreate">Create New User</a></li>
+ <li><a href="?page=TimeTracker.UserList">List Users</a></li>
+ </ul>
+ </li>
+</ul>
+<com:TClientScript PradoScripts="prado">
+ Event.OnLoad(function()
+ {
+ menuitems = $$(".menuitem");
+ menuitems.each(function(el)
+ {
+ Event.observe(el, "mouseover", function(ev)
+ {
+ menuitems.each(function(item)
+ {
+ Element.removeClassName(item.parentNode, "active");
+ });
+ Element.addClassName(Event.element(ev).parentNode, "active");
+ });
+ });
+ });
+</com:TClientScript>
+</com:TPanel> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/UserCreate.page b/demos/time-tracker/protected/pages/TimeTracker/UserCreate.page
new file mode 100644
index 00000000..fda7ba9b
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/UserCreate.page
@@ -0,0 +1,65 @@
+<com:TContent ID="Main">
+<h2>Create New User</h2>
+
+<fieldset class="signup"><legend>User Details</legend>
+ <h4>Sign Up for Your New Account</h4>
+ <div class="username">
+ <com:TLabel ForControl="username" Text="User Name:" />
+ <span class="required">*</span>
+ <com:TTextBox ID="username" />
+ <com:TRequiredFieldValidator
+ ControlToValidate="username"
+ Display="Dynamic"
+ ErrorMessage="Please enter your username."
+ ControlCssClass="required-field" />
+ <com:TCustomValidator
+ ControlToValidate="username"
+ Display="Dynamic"
+ OnServerValidate="checkUsername" />
+ </div>
+ <div class="password">
+ <com:TLabel ForControl="password" Text="Password:" />
+ <span class="required">*</span>
+ <com:TTextBox ID="password" TextMode="Password" />
+ <com:TRequiredFieldValidator
+ ControlToValidate="password"
+ Display="Dynamic"
+ ErrorMessage="Please enter your password (6 or more characters)."
+ ControlCssClass="required-field" />
+ <com:TRegularExpressionValidator
+ ControlToValidate="password"
+ Display="Dynamic"
+ RegularExpression="\w{6,}"
+ ErrorMessage="Please enter 6 or more characters."
+ ControlCssClass="required-field" />
+ </div>
+ <div class="password">
+ <com:TLabel ForControl="password2" Text="Confirm Password:" />
+ <span class="required">*</span>
+ <com:TTextBox ID="password2" TextMode="Password" />
+ <com:TCompareValidator
+ ControlToValidate="password"
+ ControlToCompare="password2"
+ ErrorMessage="The Password and Confirmation Password must match."
+ ControlCssClass="required-field" />
+ </div>
+ <div class="email">
+ <com:TLabel ForControl="email" Text="E-Mail Address:" />
+ <span class="required">*</span>
+ <com:TTextBox ID="email" Style="width:20em"/>
+ <com:TRequiredFieldValidator
+ ControlToValidate="email"
+ Display="Dynamic"
+ ErrorMessage="Please enter your E-Mail address."
+ ControlCssClass="required-field" />
+ <com:TEmailAddressValidator
+ ControlToValidate="email"
+ Display="Dynamic"
+ ErrorMessage="E-Mail address does not seem to be valid."
+ ControlCssClass="required-field" /> </div>
+ <div class="create">
+ <com:TButton Text="Create User" OnClick="createNewUser" />
+ </div>
+</fieldset>
+
+</com:TContent> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/UserCreate.php b/demos/time-tracker/protected/pages/TimeTracker/UserCreate.php
new file mode 100644
index 00000000..b337bfca
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/UserCreate.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * UserCreate page class file.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @link http://www.pradosoft.com/
+ * @copyright Copyright &copy; 2005-2006 PradoSoft
+ * @license http://www.pradosoft.com/license/
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ */
+
+/**
+ * Create new user page class. Validate that the usernames are unique
+ * and set the new user credentials as the current application credentials.
+ *
+ * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
+ * @version $Revision: $ $16/07/2006: $
+ * @package Demos
+ * @since 3.1
+ */
+class UserCreate extends TPage
+{
+ /**
+ * Verify that the username is not taken.
+ * @param TControl custom validator that created the event.
+ * @param TServerValidateEventParameter validation parameters.
+ */
+ public function checkUsername($sender, $param)
+ {
+ $userDao = $this->Application->Modules['daos']->getDao('UserDao');
+ $user = $userDao->getUserByName($this->username->Text);
+ if(!is_null($user))
+ {
+ $param->IsValid = false;
+ $sender->ErrorMessage =
+ "The user name is already taken, try '{$user->Name}01'";
+ }
+ }
+
+ /**
+ * Create a new user if all data entered are valid.
+ * The default user roles are obtained from "config.xml". The new user
+ * details is saved to the database and the new credentials are used as the
+ * application user. The user is redirected to the requested page.
+ * @param TControl button control that created the event.
+ * @param TEventParameter event parameters.
+ */
+ public function createNewUser($sender, $param)
+ {
+ if($this->IsValid)
+ {
+ $newUser = new TimeTrackerUser($this->User->Manager);
+ $newUser->EmailAddress = $this->email->Text;
+ $newUser->Name = $this->username->Text;
+ $newUser->IsGuest = false;
+ $newUser->Roles = $this->Application->Parameters['NewUserRoles'];
+
+ //save the user
+ $userDao = $this->Application->Modules['daos']->getDao('UserDao');
+ $userDao->addNewUser($newUser, $this->password->Text);
+
+ //update the user
+ $auth = $this->Application->getModule('auth');
+ $auth->updateSessionUser($newUser);
+ $this->Application->User = $newUser;
+
+ //return to requested page
+ $this->Response->redirect($auth->getReturnUrl());
+
+ //goto default page.
+ //$url = $this->Service->constructUrl($this->Service->DefaultPage);
+ //$this->Response->redirect($url);
+ }
+ }
+}
+
+?> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/UserList.page b/demos/time-tracker/protected/pages/TimeTracker/UserList.page
new file mode 100644
index 00000000..48b2bbc7
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/UserList.page
@@ -0,0 +1,3 @@
+<com:TContent ID="Main">
+<h1>List Users</h1>
+</com:TContent> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/TimeTracker/config.xml b/demos/time-tracker/protected/pages/TimeTracker/config.xml
new file mode 100644
index 00000000..dac6465d
--- /dev/null
+++ b/demos/time-tracker/protected/pages/TimeTracker/config.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<configuration>
+
+ <modules>
+ <!-- user manager module -->
+ <module id="users" class="Application.App_Code.UserManager" />
+ <!-- auth manager module -->
+ <module id="auth" class="System.Security.TAuthManager"
+ UserManager="users" LoginPage="TimeTracker.Login" />
+ </modules>
+
+ <authorization>
+ <allow roles="admin" />
+ <allow pages="UserCreate,Logout,Login" users="*" />
+ <deny users="*" />
+ </authorization>
+
+ <pages MasterClass="Application.pages.TimeTracker.MainLayout" Theme="TimeTracker" />
+
+ <parameters>
+ <parameter id="NewUserRoles" value="admin,manager,consultant" />
+ </parameters>
+</configuration> \ No newline at end of file
diff --git a/demos/time-tracker/protected/pages/Welcome.page b/demos/time-tracker/protected/pages/Welcome.page
new file mode 100644
index 00000000..65ada02d
--- /dev/null
+++ b/demos/time-tracker/protected/pages/Welcome.page
@@ -0,0 +1,168 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" >
+<head>
+ <title>Welcome</title>
+ <style type="text/css">
+ table {
+ border-collapse:collapse;
+ }
+
+ td, th {
+ border:1px solid black;
+ padding: 10px;
+ }
+
+ th {
+ text-align:left;
+ }
+ </style>
+</head>
+<body>
+ <h1>Time Tracker Starter Kit</h1>
+ <p>
+ Welcome to your new <strong>Time Tracker</strong> sample application. The key features are:</p>
+ <ul>
+ <li><strong>Projects.</strong> Define project information like due dates, hours to complete,
+ project resources, and more.</li>
+ <li><strong>Track Time.</strong> Track time spent each day by category and project.</li>
+ <li><strong>Reports.</strong> Generate progress and team resource reports across multiple projects.</li>
+ </ul>
+ <p>
+ The <a href="index.php">Time Tracker site is ready to run!</a> No changes are needed.</p>
+
+ <hr />
+
+ <h2>Site Members and Roles</h2>
+ <p>
+ Your Time Tracker Web site allows visitors to register as members and then log in.
+ Members have specific privileges defined by roles such as administrator or guest.
+ Each Time Tracker Web site defines site-specific roles.
+ The following table describes what features are available to visitors in different roles.</p>
+ <table>
+ <tr>
+ <th>Visitor</th>
+ <th>Privileges</th>
+ <th>Default Login</th>
+ </tr>
+ <tr>
+ <td>
+ Not logged in</td>
+ <td>
+ No privileges.</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>Logged in</td>
+ <td>
+ No privileges. All members must be associated at least with the role <strong>Consultant</strong>.</td>
+ <td>N/A</td>
+ </tr>
+ <tr>
+ <td>Logged in as <br />
+ <strong>Consultant</strong></td>
+ <td>May log time entries only.</td>
+ <td>username: <tt>consultant</tt><br />
+ password: <tt>consultant</tt></td>
+ </tr>
+ <tr>
+ <td>
+ Logged in as<br />
+ <strong>Project Manager</strong></td>
+ <td>
+ May additionally edit all projects and view reports.</td>
+ <td>username: <tt>manager</tt><br />
+ password: <tt>manager</tt></td>
+ </tr>
+ <tr>
+ <td>
+ Logged in as<br />
+ <strong>Project Administrator</strong></td>
+ <td>
+ May additionally view the list of all users.</td>
+ <td>username: <tt>admin</tt><br />
+ password: <tt>admin</tt></td>
+ </tr>
+ </table>
+ <p>
+ Be sure to create a user name for yourself and assign yourself to a role (such as administrator) that can manage the site.</p>
+ <p>
+ Visitors can register by clicking the <strong>Create new </strong>user link on the home page.
+ New members are activated automatically, and are assigned to a role as specified in the <tt>application.xml</tt> file.
+ You can manage users (for example, assign them to a role) when login as administrator.
+ For details, see <a href="#AppendixA">Appendix A</a>.</p>
+
+ <hr />
+
+ <h2>Projects and Time Entries</h2>
+ <h3>To add a project and categories</h3>
+ <ol>
+ <li>Log in to the site as a member in the role <strong>Project Manager</strong> or <strong>Project Administrator</strong>.</li>
+ <li>Click the <strong>Projects</strong> tab and then click <strong>Create New Project</strong>.</li>
+ <li>Specify a project name, project manager, estimated complete date, estimated duration, and description.</li>
+ <li>Under <strong>Specify Project Members</strong>, select a resource. You must select at least one resource. </li>
+ <li>Click <strong>Save</strong>. A category pane is displayed on the right.</li>
+ <li>Specify a category name, category abbreviation, and duration.</li>
+ <li>Click <strong>Add</strong>. The new category is displayed in the categories list. </li>
+ <li>Repeat steps 6 and 7 to create additional categories.</li>
+ </ol>
+ <h3>Log a Time Entry</h3>
+ <ol>
+ <li>Log in to the site as a consultant (member in the role <strong>Consultant</strong>).</li>
+ <li>Click the <strong>Log</strong> tab.</li>
+ <li>Under <strong>Log your hours</strong>, choose a project and a category and fill in the day, hours, and description.</li>
+ <li>Make sure the correct consultant is selected in the <strong>Time Sheet For</strong> list. </li>
+ <li>Click <strong>Add Entry</strong>.</li>
+ </ol>
+
+ <hr />
+
+ <h2>Reports</h2>
+ <h3>To create a project report</h3>
+ <ol>
+ <li>Log in to the site as a member in the role <strong>Project Manager</strong> or <strong>Project Administrator</strong>.</li>
+ <li>Click the <strong>Reports</strong> tab and then click <strong>Project Reports</strong>. </li>
+ <li>Under <strong>Select a project</strong>,<strong> </strong>choose one or more projects.</li>
+ <li>Click <strong>Generate Report</strong>.</li>
+ </ol>
+ <h3>To create a resource report</h3>
+ <ol>
+ <li>Log in to the site as a member in the role <strong>Project Manager</strong> or <strong>Project Administrator</strong>.</li>
+ <li>Click the <strong>Reports</strong> tab and then click <strong>Resources Report</strong>. </li>
+ <li>Select one or more projects, select one or more resources, and then specify a date range. </li>
+ <li>Click <strong>Generate Report</strong>.</li>
+ </ol>
+
+ <hr />
+
+ <a name="AppendixA" />
+ <h2>Appendix A - Manually Managing Members and Roles</h2>
+ <p>
+ Your Time Tracker Web site allows visitors to register as members.
+ Members have specific privileges defined by a role you assign to them.
+ A special administrative role has rights to perform all functions in the site.</p>
+ <p>
+ To create a user (member):</p>
+ <ol>
+ <li>Login as administrator, click <strong>Create New User</strong>.
+ </li>
+ <li>...</li>
+ </ol>
+ <p>
+ To modify an existing member's role:</p>
+ <ol>
+ <li>Login as administrator, click <strong>List Users</strong>.
+ </li>
+ <li>...</li>
+ </ol>
+
+ <hr />
+
+ <h2>Appendix B - Publishing Your Site</h2>
+ <p>
+ When you are ready to share the Web site with others, you can copy it to your Web server.
+ You need to know the File Transfer Protocol (FTP) address of your server, and if required, the user name and password assigned to you.</p>
+ <ol>
+ <li>...</li>
+ </ol>
+</body>
+</html>