Permalink
Browse files

Added chapter five starting point

  • Loading branch information...
1 parent 715f97f commit 4ca13bf5c4c21c7b21c919d9cfdc089b226f11d9 @timperrett timperrett committed Jun 9, 2010
Showing with 2,858 additions and 0 deletions.
  1. +168 −0 chapter-five/src/design/supplied/default.css
  2. +87 −0 chapter-five/src/design/supplied/homepage.html
  3. BIN chapter-five/src/design/supplied/images/bg01.jpg
  4. BIN chapter-five/src/design/supplied/images/bg02.jpg
  5. BIN chapter-five/src/design/supplied/images/bg03.jpg
  6. BIN chapter-five/src/design/supplied/images/bg04.jpg
  7. BIN chapter-five/src/design/supplied/images/bg05.jpg
  8. BIN chapter-five/src/design/supplied/images/bg06.jpg
  9. BIN chapter-five/src/design/supplied/images/homepage01.jpg
  10. BIN chapter-five/src/design/supplied/images/homepage02.jpg
  11. BIN chapter-five/src/design/supplied/images/homepage04.jpg
  12. BIN chapter-five/src/design/supplied/images/homepage05.jpg
  13. BIN chapter-five/src/design/supplied/images/homepage06.jpg
  14. BIN chapter-five/src/design/supplied/images/homepage07.jpg
  15. BIN chapter-five/src/design/supplied/images/homepage08.jpg
  16. BIN chapter-five/src/design/supplied/images/homepage09.jpg
  17. BIN chapter-five/src/design/supplied/images/homepage10.jpg
  18. BIN chapter-five/src/design/supplied/images/homepage11.gif
  19. BIN chapter-five/src/design/supplied/images/homepage12.gif
  20. BIN chapter-five/src/design/supplied/images/spacer.gif
  21. BIN chapter-five/src/design/supplied/images/subpage1_01.jpg
  22. BIN chapter-five/src/design/supplied/images/subpage1_02.jpg
  23. BIN chapter-five/src/design/supplied/images/subpage1_03.jpg
  24. BIN chapter-five/src/design/supplied/images/subpage1_04.jpg
  25. BIN chapter-five/src/design/supplied/images/subpage1_05.jpg
  26. BIN chapter-five/src/design/supplied/images/subpage2_01.jpg
  27. BIN chapter-five/src/design/supplied/images/subpage2_02.jpg
  28. BIN chapter-five/src/design/supplied/images/subpage2_03.jpg
  29. +135 −0 chapter-five/src/design/supplied/layout.css
  30. +86 −0 chapter-five/src/design/supplied/subpage1.html
  31. +70 −0 chapter-five/src/design/supplied/subpage2.html
  32. +95 −0 chapter-five/src/main/scala/bootstrap/liftweb/Boot.scala
  33. +15 −0 chapter-five/src/main/scala/bootstrap/liftweb/StaxLiftFilter.scala
  34. 0 chapter-five/src/main/scala/example/travel/comet/.keep
  35. +33 −0 chapter-five/src/main/scala/example/travel/comet/AuctionServer.scala
  36. +91 −0 chapter-five/src/main/scala/example/travel/comet/AuctionUpdater.scala
  37. +98 −0 chapter-five/src/main/scala/example/travel/lib/AucationHelpers.scala
  38. 0 chapter-five/src/main/scala/example/travel/model/.keep
  39. +86 −0 chapter-five/src/main/scala/example/travel/model/Auction.scala
  40. +32 −0 chapter-five/src/main/scala/example/travel/model/Bid.scala
  41. +44 −0 chapter-five/src/main/scala/example/travel/model/Customer.scala
  42. +26 −0 chapter-five/src/main/scala/example/travel/model/Order.scala
  43. +25 −0 chapter-five/src/main/scala/example/travel/model/OrderAuction.scala
  44. +44 −0 chapter-five/src/main/scala/example/travel/model/Supplier.scala
  45. 0 chapter-five/src/main/scala/example/travel/snippet/.keep
  46. +52 −0 chapter-five/src/main/scala/example/travel/snippet/Details.scala
  47. +8 −0 chapter-five/src/main/scala/example/travel/snippet/HelloWorld.scala
  48. +30 −0 chapter-five/src/main/scala/example/travel/snippet/Listings.scala
  49. 0 chapter-five/src/main/scala/example/travel/view/.keep
  50. +11 −0 chapter-five/src/main/webapp/404.html
  51. +21 −0 chapter-five/src/main/webapp/WEB-INF/web.xml
  52. +3 −0 chapter-five/src/main/webapp/admin/auctions.html
  53. +311 −0 chapter-five/src/main/webapp/admin/css/coolblue.css
  54. +42 −0 chapter-five/src/main/webapp/admin/css/enhancements.css
  55. +44 −0 chapter-five/src/main/webapp/admin/css/reset.css
  56. +23 −0 chapter-five/src/main/webapp/admin/css/screen.css
  57. BIN chapter-five/src/main/webapp/admin/images/current.gif
  58. BIN chapter-five/src/main/webapp/admin/images/header-bg.jpg
  59. BIN chapter-five/src/main/webapp/admin/images/header-bg.png
  60. +5 −0 chapter-five/src/main/webapp/admin/index.html
  61. +8 −0 chapter-five/src/main/webapp/admin/login.html
  62. +3 −0 chapter-five/src/main/webapp/admin/suppliers.html
  63. +45 −0 chapter-five/src/main/webapp/auction.html
  64. +20 −0 chapter-five/src/main/webapp/auctions.html
  65. +275 −0 chapter-five/src/main/webapp/css/default.css
  66. +135 −0 chapter-five/src/main/webapp/css/layout.css
  67. +26 −0 chapter-five/src/main/webapp/history.html
  68. BIN chapter-five/src/main/webapp/images/bg01.jpg
  69. BIN chapter-five/src/main/webapp/images/bg02.jpg
  70. BIN chapter-five/src/main/webapp/images/bg03.jpg
  71. BIN chapter-five/src/main/webapp/images/bg04.jpg
  72. BIN chapter-five/src/main/webapp/images/bg05.jpg
  73. BIN chapter-five/src/main/webapp/images/bg06.jpg
  74. BIN chapter-five/src/main/webapp/images/homepage01.jpg
  75. BIN chapter-five/src/main/webapp/images/homepage02.jpg
  76. BIN chapter-five/src/main/webapp/images/homepage03.jpg
  77. BIN chapter-five/src/main/webapp/images/homepage04.jpg
  78. BIN chapter-five/src/main/webapp/images/homepage05.jpg
  79. BIN chapter-five/src/main/webapp/images/homepage06.jpg
  80. BIN chapter-five/src/main/webapp/images/homepage07.jpg
  81. BIN chapter-five/src/main/webapp/images/homepage08.jpg
  82. BIN chapter-five/src/main/webapp/images/homepage09.jpg
  83. BIN chapter-five/src/main/webapp/images/homepage10.jpg
  84. BIN chapter-five/src/main/webapp/images/homepage11.gif
  85. BIN chapter-five/src/main/webapp/images/homepage12.gif
  86. BIN chapter-five/src/main/webapp/images/spacer.gif
  87. BIN chapter-five/src/main/webapp/images/subpage1_01.jpg
  88. BIN chapter-five/src/main/webapp/images/subpage1_02.jpg
  89. BIN chapter-five/src/main/webapp/images/subpage1_03.jpg
  90. BIN chapter-five/src/main/webapp/images/subpage1_04.jpg
  91. BIN chapter-five/src/main/webapp/images/subpage1_05.jpg
  92. BIN chapter-five/src/main/webapp/images/subpage2_01.jpg
  93. BIN chapter-five/src/main/webapp/images/subpage2_02.jpg
  94. BIN chapter-five/src/main/webapp/images/subpage2_03.jpg
  95. +29 −0 chapter-five/src/main/webapp/index.html
  96. +403 −0 chapter-five/src/main/webapp/js/jquery.blockui.js
  97. +12 −0 chapter-five/src/main/webapp/js/jquery.truncatable.js
  98. 0 chapter-five/src/main/webapp/search.html
  99. +7 −0 chapter-five/src/main/webapp/templates-hidden/_basket.html
  100. +5 −0 chapter-five/src/main/webapp/templates-hidden/_dark_basket.html
  101. +5 −0 chapter-five/src/main/webapp/templates-hidden/_light_basket.html
  102. +36 −0 chapter-five/src/main/webapp/templates-hidden/admin.html
  103. +38 −0 chapter-five/src/main/webapp/templates-hidden/base.html
  104. +22 −0 chapter-five/src/main/webapp/templates-hidden/default.html
  105. +31 −0 chapter-five/src/main/webapp/templates-hidden/splash.html
  106. +28 −0 chapter-five/src/main/webapp/templates-hidden/wide.html
  107. +15 −0 chapter-five/src/test/scala/LiftConsole.scala
  108. +28 −0 chapter-five/src/test/scala/RunWebApp.scala
  109. +2 −0 chapter-five/src/test/scala/example/travel/AppTest.scala
View
168 chapter-five/src/design/supplied/default.css
@@ -0,0 +1,168 @@
+/** BASIC */
+
+body {
+ margin: 0px;
+ padding: 0px;
+ background: #F9EEDD url(images/bg01.jpg) repeat left top;
+}
+
+/** FORMS */
+
+form {
+ margin: 0px;
+ padding: 0px;
+}
+
+/** HEADINGS */
+
+h1, h2 {
+ margin: 0px 0px 15px 0px;
+ font: bold 16px "Trebuchet MS", Arial, Helvetica, sans-serif;
+ color: #7E4E18;
+}
+
+h1 {
+}
+
+h2 {
+}
+
+h3 {
+ margin: 0px;
+ font-size: 11px;
+ color: #593915;
+}
+
+/** TEXTS */
+
+body, th, td, input, textarea, select {
+ font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+ font-size: 11px;
+ color: #5A4833;
+}
+
+p, blockquote, ul, ol, dl {
+ margin-top: 0px;
+ margin-bottom: 1em;
+ text-align: justify;
+}
+
+ul {
+ margin-left: 0px;
+ padding-left: 0px;
+ list-style: none;
+}
+
+ul li {
+ padding-left: 9px;
+ background: url(images/homepage11.gif) no-repeat left center;
+}
+
+ol {
+ margin-left: 0px;
+ padding-left: 0px;
+ list-style-position: inside;
+}
+
+.text1 {
+ font-size: 14px;
+ color: #4E3114;
+}
+
+.text2 {
+ text-align: center;
+ color: #B07D42;
+}
+
+.text3 {
+ margin: 0px;
+ font-size: 11px;
+ color: #593915;
+}
+
+.list1 li {
+ margin-bottom: 10px;
+}
+
+/** LINKS */
+
+a {
+ color: #FF7200;
+}
+
+a:hover {
+ text-decoration: none;
+}
+
+.link1 {
+ text-decoration: none;
+ font-size: 14px;
+ font-weight: bold;
+ color: #EDD7B6;
+}
+
+.link2 {
+ text-decoration: none;
+ font-size: 12px;
+ color: #964B00;
+}
+
+.link2:hover {
+ text-decoration: underline;
+}
+
+/** STYLES */
+
+.style1 {
+}
+
+.style1 a {
+}
+
+.style1 a:hover {
+}
+
+/** BACKGROUNDS */
+
+#wrapper { background: url(images/bg02.jpg) repeat-x left top; }
+#menu { background: url(images/bg03.jpg) no-repeat left top; }
+#page { background: url(images/bg04.jpg) repeat-y left top; }
+#page .topbg { background: url(images/bg05.jpg) no-repeat left top; }
+#page .bottombg { background: url(images/bg06.jpg) no-repeat left bottom; }
+#splash { background: url(images/homepage03.jpg) no-repeat left top; }
+#content { background: url(images/subpage1_02.jpg) repeat-y left top; }
+#content .topbg { background: url(images/subpage1_03.jpg) no-repeat left top; }
+.homepage #content .topbg { background: url(images/homepage08.jpg) no-repeat left top; }
+#content .bottombg { background: url(images/subpage1_04.jpg) no-repeat left bottom; }
+#content-wide { background: url(images/subpage2_01.jpg) repeat-y left top; }
+#content-wide .topbg { background: url(images/subpage2_02.jpg) no-repeat left top; }
+#content-wide .bottombg { background: url(images/subpage2_03.jpg) no-repeat left bottom; }
+.bg1 { background: url(images/homepage04.jpg) repeat-y left top; }
+.bg2 { background: url(images/homepage05.jpg) no-repeat left top; }
+.bg3 { background: url(images/homepage06.jpg) no-repeat left bottom; }
+.bg4 { background: url(images/subpage1_05.jpg) no-repeat left top; }
+
+/** MISC */
+
+.align-justify { text-align: justify; }
+.align-right { text-align: right; }
+
+img { border: none; }
+
+img.left {
+ float: left;
+ margin: 3px 15px 0px 0px;
+}
+
+img.right {
+ float: right;
+ margin: 3px 0px 0px 15px;
+}
+
+hr { display: none; }
+
+.hr1 {
+ height: 42px;
+ background: url(images/homepage12.gif) repeat-x left center;
+}
+
View
87 chapter-five/src/design/supplied/homepage.html
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!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>
+ <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+ <link href="default.css" rel="stylesheet" type="text/css" />
+ <link href="layout.css" rel="stylesheet" type="text/css" />
+</head>
+<body class="homepage">
+<div id="wrapper">
+ <div id="logo">
+ <h1>TravelSite.com</h1>
+ </div>
+ <!-- end logo -->
+ <div id="menu">
+ <ul>
+ <li class="first"><a href="#" id="menu1" accesskey="1" title="" class="link1">Home</a></li>
+ <li><a href="#" id="menu2" accesskey="2" title="" class="link1">Search</a></li>
+ <li><a href="#" id="menu3" accesskey="3" title="" class="link1">Tours</a></li>
+ <li><a href="#" id="menu4" accesskey="4" title="" class="link1">Customer Service</a></li>
+ <li><a href="#" id="menu5" accesskey="5" title="" class="link1">Contact</a></li>
+ </ul>
+ </div>
+ <!-- end menu -->
+ <div id="page">
+ <div class="topbg">
+ <div class="bottombg">
+ <div id="splash">
+ <h2>Lorem Ipsum Dolor</h2>
+ <p class="text1"><strong>Etiam dolore</strong> sectetuer adipiscing elit sed diam nonummy nibh blandit</p>
+ <p><a href="#" class="link2">Learn more &gt;&gt;</a></p>
+ </div>
+ <!-- end splash -->
+ <div id="content">
+ <div class="bottombg">
+ <div id="box1" class="topbg">
+ <h1>Blandit sit amet nullam</h1>
+ <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna <a href="#">aliquam erat volutpat</a>.</p>
+ <img src="images/homepage09.jpg" alt="" width="72" height="72" class="left" />
+ <p>Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea <a href="#">commodo consequat</a>. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse mole stie.</p>
+ </div>
+ <div id="box2">
+ <h3>Blandit et dolore</h3>
+ <p>Sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore <a href="#">magna aliquam</a>.</p>
+ <div class="hr1"></div>
+ <h3>Ut wisi enim ad</h3>
+ <p>Veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl.</p>
+ </div>
+ <div id="box3">
+ <p><img src="images/homepage10.jpg" alt="" width="128" height="79" /></p>
+ <ul class="list1">
+ <li><a href="#">Lorem ipsum dolor</a></li>
+ <li><a href="#">Sit amet nullam</a></li>
+ <li><a href="#">Consequat blandit</a></li>
+ <li><a href="#">Veroeros aliquip</a></li>
+ </ul>
+ </div>
+ <div style="clear: both;">&nbsp;</div>
+ </div>
+ </div>
+ <!-- end content -->
+ <div id="sidebar">
+ <div id="box4" class="bg1">
+ <div class="bg2">
+ <div class="bg3" style="padding: 35px 28px 0px 28px;">
+ <h2>Lorem ipsum</h2>
+ <p><img src="images/subpage1_01.jpg" alt="" width="138" height="79" /></p>
+ <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh sed aliquam erat volutpat.</p>
+ <br style="clear: both;" />
+ </div>
+ </div>
+ </div>
+ <div id="box5"><a href="#"><img src="images/homepage07.jpg" alt="" width="214" height="183" /></a></div>
+ </div>
+ <!-- end sidebar -->
+ <div style="clear: both; height: 50px;">&nbsp;</div>
+ </div>
+ </div>
+ </div>
+ <!-- end page -->
+</div>
+<!-- end wrapper -->
+<div id="footer">
+ <p class="text2">Copyright (c) 2007 Travelsite.com. All rights reserved.</p>
+</div>
+</body>
+</html>
View
BIN chapter-five/src/design/supplied/images/bg01.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/bg02.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/bg03.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/bg04.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/bg05.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/bg06.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage01.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage02.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage04.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage05.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage06.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage07.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage08.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage09.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage10.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage11.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/homepage12.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/spacer.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/subpage1_01.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/subpage1_02.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/subpage1_03.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/subpage1_04.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/subpage1_05.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/subpage2_01.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/subpage2_02.jpg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN chapter-five/src/design/supplied/images/subpage2_03.jpg
Diff not rendered.
View
135 chapter-five/src/design/supplied/layout.css
@@ -0,0 +1,135 @@
+/** BASIC */
+
+html, body {
+ height: 100%;
+}
+
+/** LOGO */
+
+#logo {
+ width: 720px;
+ height: 125px;
+ margin: 0px auto;
+ background: url(images/homepage01.jpg) no-repeat left top;
+}
+
+#logo h1 {
+ display: none;
+}
+
+/** MENU */
+
+#menu {
+ width: 720px;
+ height: 54px;
+ margin: 0px auto;
+}
+
+#menu ul {
+ margin: 0px;
+ padding: 12px 0px 0px 0px;
+ list-style: none;
+ text-align: center;
+}
+
+#menu li {
+ display: inline;
+ padding: 0px;
+ background: none;
+}
+
+#menu a {
+ padding: 0 18px 10px 34px;
+ background: url(images/homepage02.jpg) no-repeat left top;
+}
+
+#menu .first a {
+ background: none;
+ padding-left: 16px;
+}
+
+/** PAGE */
+
+#page {
+ width: 720px;
+ margin: 0px auto;
+}
+
+/** SPLASH */
+
+#splash {
+ width: 236px;
+ height: 93px;
+ margin: 0 77px;
+ padding: 100px 290px 0px 40px;
+}
+
+#splash h2 {
+ display: none;
+}
+
+/** CONTENT */
+
+#content {
+ float: right;
+ width: 346px;
+ padding: 0px 79px 0px 0px;
+}
+
+#content-wide {
+ width: 561px;
+ margin-left: 80px;
+}
+
+/** SIDEBAR */
+
+#sidebar {
+ float: left;
+ width: 281px;
+}
+
+/** FOOTER */
+
+#footer {
+ padding-bottom: 50px;
+}
+
+/** BOX1 */
+
+#box1 {
+ padding: 35px 30px 20px 30px;
+}
+
+/** BOX2 */
+
+#box2 {
+ float: left;
+ width: 129px;
+ padding: 0px 0px 0px 30px;
+}
+
+/** BOX3 */
+
+#box3 {
+ float: right;
+ width: 129px;
+ padding: 0px 30px 0px 0px;
+}
+
+/** BOX4 */
+
+#box4 {
+ width: 194px;
+ margin: 0px 0px 0px 77px;
+}
+
+/** BOX5 */
+
+#box5 {
+ padding: 10px 0px 0px 67px;
+}
+
+/** BOX6 */
+
+#box6 {
+}
View
86 chapter-five/src/design/supplied/subpage1.html
@@ -0,0 +1,86 @@
+<!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>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title></title>
+<meta name="keywords" content="" />
+<meta name="description" content="" />
+<link href="default.css" rel="stylesheet" type="text/css" />
+<style type="text/css">
+<!--
+ @import url("layout.css");
+-->
+</style>
+</head>
+<body>
+<div id="wrapper">
+ <div id="logo">
+ <h1>TravelSite.com</h1>
+ </div>
+ <!-- end logo -->
+ <div id="menu">
+ <ul>
+ <li class="first"><a href="#" id="menu1" accesskey="1" title="" class="link1">Home</a></li>
+ <li><a href="#" id="menu2" accesskey="2" title="" class="link1">Search</a></li>
+ <li><a href="#" id="menu3" accesskey="3" title="" class="link1">Tours</a></li>
+ <li><a href="#" id="menu4" accesskey="4" title="" class="link1">Customer Service</a></li>
+ <li><a href="#" id="menu5" accesskey="5" title="" class="link1">Contact</a></li>
+ </ul>
+ </div>
+ <!-- end menu -->
+ <div id="page">
+ <div class="topbg" style="padding-top: 36px;">
+ <div class="bottombg">
+ <div id="content">
+ <div class="bottombg">
+ <div id="box1" class="topbg">
+ <h1>Blandit sit amet nullam</h1>
+ <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
+ <img src="images/homepage09.jpg" alt="" width="72" height="72" class="left" />
+ <p>Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse mole stie.</p>
+ <p>Maecenas pede nisl, elementum eu, ornare ac, malesuada at, erat. Proin gravida orci porttitor enim accumsan lacinia. Donec condimentum, urna non molestie semper, ligula enim ornare nibh, quis laoreet eros quam eget ante. Aliquam libero. Vivamus nisl nibh, iaculis vitae, viverra sit amet, ullamcorper vitae, turpis. Aliquam erat volutpat. </p>
+ <h3>Aenean elementum facilisis</h3>
+ <p>Vestibulum dui sem, pulvinar sed, imperdiet nec, iaculis nec, leo. Fusce odio. Etiam arcu dui, faucibus eget, placerat vel, sodales eget, orci. Donec ornare neque ac sem. Mauris aliquet. Aliquam sem leo, vulputate sed, convallis at, ultricies quis, justo. Donec nonummy magna quis risus. </p>
+ <p>Quisque eleifend. Phasellus tempor vehicula justo. Aliquam lacinia metus ut elit. Suspendisse iaculis mauris nec lorem:</p>
+ <ol>
+ <li><a href="#"> Integer sit amet pede vel arcu aliquet pretium.</a></li>
+ <li><a href="#">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</a></li>
+ <li><a href="#">Phasellus nec erat sit amet nibh pellentesque congue.</a></li>
+ <li><a href="#">Pellentesque quis elit non lectus gravida blandit.</a></li>
+ <li><a href="#">Maecenas vitae orci vitae tellus feugiat eleifend.</a></li>
+ <li><a href="#">Duis non ante in metus commodo pellentesque.</a></li>
+ <li><a href="#">Cras vitae metus aliquam risus pellentesque pharetra.</a></li>
+ </ol>
+ </div>
+ <div style="clear: both;">&nbsp;</div>
+ </div>
+ </div>
+ <!-- end content -->
+ <div id="sidebar">
+ <div id="box4" class="bg1">
+ <div class="bg4">
+ <div class="bg3" style="padding: 35px 28px 0px 28px;">
+ <h2>Lorem ipsum</h2>
+ <p><img src="images/subpage1_01.jpg" alt="" width="138" height="79" /></p>
+ <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh sed aliquam erat volutpat.</p>
+ <p>Quisque dictum integer nisl risus, sagittis convallis, rutrum id, congue, and nibh.In posuere eleifend odio quisque semper augue mattis wisi maecenas ligula.</p>
+ <p>Donec leo, vivamus fermentum nibh in augue.</p>
+ <br style="clear: both;" />
+ </div>
+ </div>
+ </div>
+ <div id="box5"><a href="#"><img src="images/homepage07.jpg" alt="" width="214" height="183" /></a></div>
+ </div>
+ <!-- end sidebar -->
+ <div style="clear: both; height: 50px;">&nbsp;</div>
+ </div>
+ </div>
+ </div>
+ <!-- end page -->
+</div>
+<!-- end wrapper -->
+<div id="footer">
+ <p class="text2">Copyright (c) 2007 Travelsite.com. All rights reserved.</p>
+</div>
+</body>
+</html>
View
70 chapter-five/src/design/supplied/subpage2.html
@@ -0,0 +1,70 @@
+<!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>
+<meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title></title>
+<meta name="keywords" content="" />
+<meta name="description" content="" />
+<link href="default.css" rel="stylesheet" type="text/css" />
+<style type="text/css">
+<!--
+ @import url("layout.css");
+-->
+</style>
+</head>
+<body>
+<div id="wrapper">
+ <div id="logo">
+ <h1>TravelSite.com</h1>
+ </div>
+ <!-- end logo -->
+ <div id="menu">
+ <ul>
+ <li class="first"><a href="#" id="menu1" accesskey="1" title="" class="link1">Home</a></li>
+ <li><a href="#" id="menu2" accesskey="2" title="" class="link1">Search</a></li>
+ <li><a href="#" id="menu3" accesskey="3" title="" class="link1">Tours</a></li>
+ <li><a href="#" id="menu4" accesskey="4" title="" class="link1">Customer Service</a></li>
+ <li><a href="#" id="menu5" accesskey="5" title="" class="link1">Contact</a></li>
+ </ul>
+ </div>
+ <!-- end menu -->
+ <div id="page">
+ <div class="topbg" style="padding-top: 36px;">
+ <div class="bottombg">
+ <div id="content-wide">
+ <div class="bottombg">
+ <div id="box1" class="topbg">
+ <h1>Maecenas luctus lectus</h1>
+ <img src="images/homepage09.jpg" alt="" width="72" height="72" class="left" />
+ <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse mole stie. Aliquam sem leo, vulputate sed, convallis at, ultricies quis, justo. Aliquam sem leo, vulputate sed, convallis at, ultricies quis, justo.</p>
+ <p>Maecenas pede nisl, elementum eu, ornare ac, malesuada at, erat. Proin gravida orci porttitor enim accumsan lacinia. Donec condimentum, urna non molestie semper, ligula enim ornare nibh, quis laoreet eros quam eget ante. Aliquam libero. Vivamus nisl nibh, iaculis vitae, viverra sit amet, ullamcorper vitae, turpis. Aliquam erat volutpat. Pellentesque erat erat, tincidunt in, eleifend accumsan, malesuada eget, augue. Suspendisse sit amet tellus in eros bibendum condimentum. Vestibulum suscipit volutpat nulla.</p>
+ <p>Aenean elementum facilisis<br />
+ Vestibulum dui sem, pulvinar sed, imperdiet nec, iaculis nec, leo. Fusce odio. Etiam arcu dui, faucibus eget, placerat vel, sodales eget, orci. Donec ornare neque ac sem. Mauris aliquet. Aliquam sem leo, vulputate sed, convallis at, ultricies quis, justo. Donec nonummy magna quis risus. Pellentesque pede. Donec pulvinar ullamcorper metus. In eu odio at lectus pulvinar mollis. Vestibulum sem magna, elementum ut, vestibulum eu, facilisis quis, arcu. Mauris a dolor. Nulla facilisi. </p>
+ <p>Quisque eleifend. Phasellus tempor vehicula justo. Aliquam lacinia metus ut elit. estibulum sem magna, elementum ut, vestibulum eu, facilisis quis, arcu. Suspendisse iaculis mauris nec lorem:</p>
+ <ol>
+ <li><a href="#"> Integer sit amet pede vel arcu aliquet pretium.</a></li>
+ <li><a href="#">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</a></li>
+ <li><a href="#">Phasellus nec erat sit amet nibh pellentesque congue.</a></li>
+ <li><a href="#">Pellentesque quis elit non lectus gravida blandit.</a></li>
+ <li><a href="#">Maecenas vitae orci vitae tellus feugiat eleifend.</a></li>
+ <li><a href="#">Duis non ante in metus commodo pellentesque.</a></li>
+ <li><a href="#">Cras vitae metus aliquam risus pellentesque pharetra.</a></li>
+ </ol>
+ <p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed blandit. Phasellus pellentesque, ante nec iaculis dapibus, eros justo auctor lectus, a lobortis lorem mauris quis nunc. Praesent pellentesque facilisis elit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. In hac habitasse platea dictumst. Nullam id ante eget dui vulputate aliquam.</p>
+ </div>
+ <div style="clear: both;">&nbsp;</div>
+ </div>
+ </div>
+ <!-- end content -->
+ <div style="clear: both; height: 50px;">&nbsp;</div>
+ </div>
+ </div>
+ </div>
+ <!-- end page -->
+</div>
+<!-- end wrapper -->
+<div id="footer">
+ <p class="text2">Copyright (c) 2007 Travelsite.com. All rights reserved.</p>
+</div>
+</body>
+</html>
View
95 chapter-five/src/main/scala/bootstrap/liftweb/Boot.scala
@@ -0,0 +1,95 @@
+package bootstrap.liftweb
+
+// framework imports
+import net.liftweb.common._
+import net.liftweb.util._
+import net.liftweb.util.Helpers._
+import net.liftweb.http._
+import net.liftweb.sitemap._
+import net.liftweb.sitemap.Loc._
+import net.liftweb.mapper.{DB,Schemifier,DefaultConnectionIdentifier,StandardDBVendor}
+
+// app imports
+import example.travel.model.{Auction,Supplier,Customer,Bid,Order,OrderAuction}
+// import example.travel.lib.{Helpers}
+
+class Boot extends Loggable {
+ def boot {
+ LiftRules.addToPackages("example.travel")
+
+ /**** database settings ****/
+
+ // set the JNDI name that we'll be using
+ DefaultConnectionIdentifier.jndiName = "jdbc/liftinaction"
+
+ // handle JNDI not being avalible
+ if (!DB.jndiJdbcConnAvailable_?){
+ logger.error("No JNDI configured - using the default in-memory database.")
+ DB.defineConnectionManager(DefaultConnectionIdentifier, Application.database)
+ // make sure cyote unloads database connections before shutting down
+ LiftRules.unloadHooks.append(() => Application.database.closeAllConnections_!())
+ }
+
+ // automatically create the tables
+ Schemifier.schemify(true, Schemifier.infoF _,
+ Bid, Auction, Supplier, Customer, Order, OrderAuction)
+
+ // setup the loan pattern
+ S.addAround(DB.buildLoanWrapper)
+
+ /**** user experience settings ****/
+
+ // set the time that notices should be displayed and then fadeout
+ LiftRules.noticesAutoFadeOut.default.set((notices: NoticeType.Value) => Full(2 seconds, 2 seconds))
+
+ LiftRules.loggedInTest = Full(() => Customer.loggedIn_?)
+
+ /**** request settings ****/
+
+ // set the application sitemap
+ LiftRules.setSiteMap(SiteMap(Application.sitemap:_*))
+
+ // setup the 404 handler
+ LiftRules.uriNotFound.prepend(NamedPF("404handler"){
+ case (req,failure) => NotFoundAsTemplate(ParsePath(List("404"),"html",false,false))
+ })
+
+ // make requests utf-8
+ LiftRules.early.append(_.setCharacterEncoding("UTF-8"))
+
+ LiftRules.statelessRewrite.append {
+ case RewriteRequest(ParsePath("auction" :: key :: Nil,"",true,_),_,_) =>
+ RewriteResponse("auction" :: Nil, Map("id" -> key.split("-")(0)))
+ }
+
+ logger.debug("DEBUG MODE ENABLED!")
+ }
+}
+
+object Application {
+ val MustBeLoggedIn = If(() => Customer.loggedIn_?, "")
+
+ val sitemap = List(
+ Menu("Home") / "index" >> LocGroup("public"),
+ Menu("Auctions") / "auctions" >> LocGroup("public"),
+ Menu("Search") / "search" >> LocGroup("public") >> MustBeLoggedIn,
+ Menu("History") / "history" >> LocGroup("public") >> MustBeLoggedIn,
+ Menu("Auction Detail") / "auction" >> LocGroup("public") >> Hidden,
+ // admin
+ Menu("Admin") / "admin" / "index" >> LocGroup("admin"),
+ Menu("Suppliers") / "admin" / "suppliers" >> LocGroup("admin") submenus(Supplier.menus : _*),
+ Menu("Auction Admin") / "admin" / "auctions" >> LocGroup("admin") submenus(Auction.menus : _*)
+ ) ::: Customer.menus
+
+ val database = DBVendor
+
+ object DBVendor extends StandardDBVendor(
+ Props.get("db.class").openOr("com.mysql.jdbc.Driver"),
+ Props.get("db.url").openOr("jdbc:mysql://localhost/liftinaction?user=root"),
+ Props.get("db.user"),
+ Props.get("db.pass"))
+
+}
+
+
+
View
15 chapter-five/src/main/scala/bootstrap/liftweb/StaxLiftFilter.scala
@@ -0,0 +1,15 @@
+package bootstrap {
+package liftweb {
+
+ import _root_.net.liftweb.http.LiftFilter
+ import _root_.javax.servlet._
+ import _root_.javax.servlet.http._
+
+ class StaxLiftFilter extends LiftFilter {
+ override def init(config: FilterConfig){
+ System.setProperty("run.mode", "production")
+ super.init(config)
+ }
+ }
+
+}}
View
0 chapter-five/src/main/scala/example/travel/comet/.keep
No changes.
View
33 chapter-five/src/main/scala/example/travel/comet/AuctionServer.scala
@@ -0,0 +1,33 @@
+package example {
+package travel {
+package comet {
+
+ import scala.collection.immutable.Map
+ import net.liftweb.actor.LiftActor
+ import net.liftweb.http.CometActor
+
+ object AuctionServer extends LiftActor {
+ /**
+ * Internal state about who's listening for what and what is listening for who!
+ */
+ private var cometActorAuctions: Map[CometActor,List[Long]] = Map()
+ private def auctionCometActors: Map[Long, List[CometActor]] =
+ cometActorAuctions.foldLeft[Map[Long, List[CometActor]]](Map.empty withDefaultValue Nil){
+ case (prev, (k, vs)) => vs.foldLeft(prev)((prev, v) => prev + (v -> (k::prev(v))))
+ }
+
+ /**
+ * Handle the messages themselves
+ */
+ override def messageHandler = {
+ case ListenTo(actor,auctions) =>
+ println("Actor ("+actor.hashCode+") listening to: "+ auctions.map(_.toString).mkString(","))
+ cometActorAuctions = cometActorAuctions + (actor -> auctions)
+ case msg@NewBid(auction,amount,session) =>
+ println("New bid recived for auction " + auction.toString + ", " + amount.toString)
+ auctionCometActors(auction).foreach(_ ! msg)
+ }
+
+ }
+
+}}}
View
91 chapter-five/src/main/scala/example/travel/comet/AuctionUpdater.scala
@@ -0,0 +1,91 @@
+package example {
+package travel {
+package comet {
+
+ import scala.xml.{NodeSeq,Text}
+ import net.liftweb.common.{Full,Empty,Failure,Box}
+ import net.liftweb.http.CometActor
+ import net.liftweb.util.Helpers._
+ import net.liftweb.util.ActorPing
+ import net.liftweb.http.S
+ import net.liftweb.http.js.JsCmds._
+ import example.travel.model.{Auction,Customer}
+ import example.travel.lib.AuctionInstanceHelpers
+
+ // messages
+ case object CountdownTick
+ case class ListenTo(actor: CometActor, auctions: List[Long])
+ case class CurrentAuction(auction: Box[Auction])
+
+ // case class AuctionInfoFor(id: Long)
+ case class NewBid(auction: Long, amount: Double, fromsession: Box[String])
+
+ class AuctionUpdater extends CometActor with AuctionInstanceHelpers {
+ // element ids
+ private lazy val countdownId = "time_remaining"
+ private lazy val nextAmountId = "next_amount"
+ private lazy val currentAmountId = "current_amount"
+ private lazy val winningCustomerId = "winning_customer"
+ private lazy val amountId = "amount"
+ // helpers
+ private val server = AuctionServer
+ private var _auction: Box[Auction] = Empty
+ protected def auction = _auction
+ private def auctionId = auction.map(_.id.is).openOr(0L)
+
+ /**
+ * xhtml content
+ */
+ def countdown =
+ if(hasExpired_?) Text("This auction has ended.")
+ else Text(TimeSpan.format((auction.map(_.ends_at.is.getTime).openOr(now.getTime) - now.getTime) / 1000L * 1000L))
+
+ def notifyOtherAuctionUpdate {
+ warning("You have been outbid on an auction you are participating in")
+ }
+
+ def notifyThisAuctionUpdate {
+ partialUpdate {
+ SetHtml(currentAmountId, Text(leadingBid.toString)) &
+ SetHtml(nextAmountId, Text(minimumBid.toString)) &
+ SetHtml(winningCustomerId, winningCustomer) &
+ SetValueAndFocus(amountId,"")
+ }
+ }
+
+ def registerListeners {
+ auction.map(a =>
+ server ! ListenTo(this,(a.id.is :: Customer.currentUser.map(_.participatingIn).openOr(Nil)).removeDuplicates))
+ }
+
+ /**
+ * comet message handlers
+ */
+ override def lowPriority = {
+ case CountdownTick => {
+ partialUpdate(SetHtml(countdownId, countdown))
+ if(!hasExpired_?) ActorPing.schedule(this, CountdownTick, 5 seconds)
+ }
+ case CurrentAuction(a) =>
+ _auction = a
+ registerListeners
+ }
+
+ override def highPriority = {
+ case NewBid(auctionId,amount,fromsession) =>
+ notifyThisAuctionUpdate
+ if((S.session.map(_.uniqueId) equals fromsession) == false)
+ notifyOtherAuctionUpdate
+ }
+
+ override def render = {
+ // listen for bids on this current auction (and auctions the user is bidding on)
+ registerListeners
+ // need at least one ping after the intial render
+ ActorPing.schedule(this, CountdownTick, 2 seconds)
+ NodeSeq.Empty
+ }
+
+ }
+
+}}}
View
98 chapter-five/src/main/scala/example/travel/lib/AucationHelpers.scala
@@ -0,0 +1,98 @@
+package example.travel {
+package lib {
+
+ import example.travel.model.Auction
+ import scala.xml.{NodeSeq,Text}
+ import net.liftweb.util.Helpers._
+ import net.liftweb.textile.TextileParser
+ import net.liftweb.common.{Full,Box,Empty,Failure,Loggable}
+ import net.liftweb.mapper.{By}
+ import net.liftweb.http.{S,SessionVar}
+ import net.liftweb.http.js.JsCmd
+ import net.liftweb.http.js.JsCmds.Noop
+
+ trait AuctionInstanceHelpers extends AuctionHelpers {
+
+ /**
+ * Accessor for the CurrentAuction request state; if it is empty, attempt to assign it.
+ */
+ protected def auction: Box[Auction]
+
+ /**
+ * Has the auction in the auction in the current request expired?
+ */
+ protected def hasExpired_? : Boolean = hasExpired_?(auction)
+
+ /**
+ * Obtain the currently leading bid for the auction in the request scope
+ */
+ protected def leadingBid: Double = leadingBid(auction)
+
+ /**
+ * The minimum bid based on any incomming bids etc
+ */
+ protected def minimumBid: Double = minimumBid(auction)
+
+ /**
+ * Winning user name
+ */
+ protected def winningCustomer: NodeSeq = winningCustomer(auction)
+ }
+
+ /**
+ * common helpers for getting auctions and displaying them
+ */
+ trait AuctionHelpers extends Loggable {
+
+ protected def many(auctions: List[Auction], xhtml: NodeSeq): NodeSeq =
+ auctions.flatMap(a => single(a,xhtml))
+
+ protected def boxToNotice[T](sucsess: String, warning: String)(f: => Box[T]){
+ f match {
+ case Full(value) =>
+ S.notice(sucsess)
+ case Failure(msg,_,_) =>
+ S.error(msg)
+ case _ =>
+ S.warning(warning)
+ }
+ }
+
+ protected def single(auction: Auction, xhtml: NodeSeq): NodeSeq =
+ bind("a", xhtml,
+ "name" -> auction.name,
+ "description" -> TextileParser.toHtml(auction.description),
+ "winning_customer" -> winningCustomer(auction),
+ "travel_dates" -> auction.travelDates,
+ "link" -%> <a href={"/auction/" +
+ auction.id.toString+"-"+auction.permanent_link}>details >></a>
+ )
+
+
+ /**
+ * Has the auction in the auction in the current request expired?
+ */
+ protected def hasExpired_?(a: Box[Auction]) : Boolean = a.map(_.expired_?).openOr(true)
+
+ /**
+ * Obtain the currently leading bid for the auction in the request scope
+ */
+ protected def leadingBid(a: Box[Auction]): Double = a.flatMap(_.currentAmount).openOr(0D)
+
+ /**
+ * The minimum bid based on any incomming bids etc
+ */
+ protected def minimumBid(a: Box[Auction]): Double = a.flatMap(_.nextAmount).openOr(0D)
+
+ /**
+ * Winning user name
+ */
+ protected def winningCustomer(a: Box[Auction]): NodeSeq =
+ Text(a.flatMap(_.winningCustomer.map(_.shortName)).openOr("Unknown"))
+
+ protected def winningCustomer(a: Auction): NodeSeq =
+ winningCustomer(Full(a))
+
+ }
+
+}}
View
0 chapter-five/src/main/scala/example/travel/model/.keep
No changes.
View
86 chapter-five/src/main/scala/example/travel/model/Auction.scala
@@ -0,0 +1,86 @@
+package example.travel {
+package model {
+
+ import net.liftweb.common.{Full,Box,Empty,Failure}
+ import net.liftweb.sitemap.Loc._
+ import scala.xml.NodeSeq
+ import net.liftweb.mapper._
+ import net.liftweb.util.Helpers.{tryo,now}
+
+ object Auction
+ extends Auction
+ with LongKeyedMetaMapper[Auction]
+ with CRUDify[Long,Auction]{
+ override def dbTableName = "auctions"
+ override def fieldOrder = List(name,description,ends_at,
+ outbound_on,inbound_on,flying_from,permanent_link,is_closed)
+
+ // crudify
+ override def pageWrapper(body: NodeSeq) =
+ <lift:surround with="admin" at="content">{body}</lift:surround>
+ override def calcPrefix = List("admin",_dbTableNameLC)
+ override def displayName = "Auction"
+ override def showAllMenuLocParams = LocGroup("admin") :: Nil
+ override def createMenuLocParams = LocGroup("admin") :: Nil
+ override def viewMenuLocParams = LocGroup("admin") :: Nil
+ override def editMenuLocParams = LocGroup("admin") :: Nil
+ override def deleteMenuLocParams = LocGroup("admin") :: Nil
+ }
+
+ class Auction extends LongKeyedMapper[Auction] with IdPK with CreatedUpdated {
+ def getSingleton = Auction
+ // fields
+ object name extends MappedString(this, 150){
+ override def validations =
+ valMinLen(3, "Description must be 3 characters") _ ::
+ valUnique("That link URL has already been taken") _ ::
+ super.validations
+ }
+ object description extends MappedText(this)
+ object ends_at extends MappedDateTime(this)
+ object outbound_on extends MappedDateTime(this)
+ object inbound_on extends MappedDateTime(this)
+ object flying_from extends MappedString(this, 100)
+ object permanent_link extends MappedString(this, 150)
+ object is_closed extends MappedBoolean(this)
+
+ // relationships
+ object supplier extends LongMappedMapper(this, Supplier){
+ override def dbColumnName = "supplier_id"
+ override def validSelectValues =
+ Full(Supplier.findMap(OrderBy(Supplier.name, Ascending)){
+ case s: Supplier => Full(s.id.is -> s.name.is)
+ })
+ }
+
+ // helper: get all the bids for this auction
+ def bids = Bid.findAll(By(Bid.auction, this.id), OrderBy(Bid.amount, Descending))
+
+ def barter(next: Box[String]): Box[Bid] =
+ for(ass <- next ?~! "Amount is not a number";
+ amo <- tryo(BigDecimal(ass).doubleValue) ?~! "Amount is not a number";
+ nxt <- nextAmount;
+ vld <- tryo(amo).filter(_ >= nxt) ?~ "Your bid is lower than required!"
+ ) yield {
+ new Bid().auction(this).customer(Customer.currentUser).amount(vld).saveMe
+ }
+
+ def expired_? : Boolean = ends_at.is.getTime < now.getTime
+
+ def winningCustomer: Box[Customer] = topBid.flatMap(_.customer.obj)
+
+ private def topBid: Box[Bid] = bids match {
+ case list if list.length > 0 => Full(list.head)
+ case _ => Empty
+ }
+ def currentAmount: Box[Double] = topBid.map(_.amount.is)
+ def nextAmount: Box[Double] = currentAmount.map(_ + 1D)
+
+ def travelDates: String = (Box.!!(inbound_on.is), Box.!!(outbound_on.is)) match {
+ case (Full(in), Full(out)) => out.toString + ", returning " + in.toString
+ case (Empty,Full(out)) => out.toString + " (one way)"
+ case _ => "Travel dates not specified, call the vendor."
+ }
+ }
+
+}}
View
32 chapter-five/src/main/scala/example/travel/model/Bid.scala
@@ -0,0 +1,32 @@
+package example.travel {
+package model {
+
+ import scala.xml.{MetaData,Text,Null,UnprefixedAttribute}
+ import net.liftweb.common.{Full,Box,Empty,Failure}
+ import net.liftweb.mapper._
+
+ object Bid
+ extends Bid
+ with LongKeyedMetaMapper[Bid]{
+ override def dbTableName = "bids"
+ }
+
+ class Bid extends LongKeyedMapper[Bid] with IdPK with CreatedUpdated {
+ def getSingleton = Bid
+ // fields
+ object amount extends MappedDouble(this)
+
+ // relationship
+ object customer extends LongMappedMapper(this, Customer){
+ override def dbColumnName = "customer_id"
+ }
+ object auction extends LongMappedMapper(this, Auction){
+ override def dbColumnName = "auction_id"
+ }
+
+ // helpers
+ def nextBidValue: Double = amount.is + 1D
+ }
+
+
+}}
View
44 chapter-five/src/main/scala/example/travel/model/Customer.scala
@@ -0,0 +1,44 @@
+package example.travel {
+package model {
+
+ import net.liftweb.common.{Full,Box,Empty,Failure}
+ import net.liftweb.mapper._
+ import net.liftweb.sitemap.Loc._
+ import scala.xml.{NodeSeq,Node}
+
+ object Customer extends Customer
+ with KeyedMetaMapper[Long, Customer]
+ with MetaMegaProtoUser[Customer]{
+
+ override def dbTableName = "customers"
+ override def fieldOrder = id :: firstName :: lastName ::
+ email :: password :: Nil
+
+ // proto user
+ override val basePath = "account" :: Nil
+ override def homePage = "/"
+ override def skipEmailValidation = true
+ override def loginMenuLocParams = LocGroup("public") :: super.loginMenuLocParams
+ override def createUserMenuLocParams = LocGroup("public") :: super.createUserMenuLocParams
+ override def screenWrap: Box[Node] =
+ Full(
+ <lift:surround with="default" at="content">
+ <div id="box1" class="topbg">
+ <lift:bind />
+ </div>
+ <lift:with-param name="sidebar">
+ <lift:embed what="_light_basket" />
+ </lift:with-param>
+ </lift:surround>
+ )
+
+ }
+ class Customer extends MegaProtoUser[Customer] with CreatedUpdated {
+ def getSingleton = Customer
+
+ def participatingIn: List[Long] =
+ Bid.findAll(By(Bid.customer, this.id)).map(_.auction.obj)
+ .removeDuplicates.filter(!_.isEmpty).map(_.open_!.id.is)
+ }
+
+}}
View
26 chapter-five/src/main/scala/example/travel/model/Order.scala
@@ -0,0 +1,26 @@
+package example.travel {
+package model {
+
+ import net.liftweb.common.{Full,Box,Empty,Failure}
+ import net.liftweb.mapper._
+
+ object Order extends Order with LongKeyedMetaMapper[Order]{
+ override def dbTableName = "orders"
+ }
+
+ class Order extends LongKeyedMapper[Order]
+ with IdPK with OneToMany[Long, Order] with CreatedUpdated {
+ def getSingleton = Order
+ // fields
+ // object reference extends MappedString(this, 150)
+
+ // relationships
+ object customer extends LongMappedMapper(this, Customer){
+ override def dbColumnName = "customer_id"
+ }
+ object order_auctions extends MappedOneToMany(OrderAuction, OrderAuction.order)
+ with Owned[OrderAuction]
+ }
+
+
+}}
View
25 chapter-five/src/main/scala/example/travel/model/OrderAuction.scala
@@ -0,0 +1,25 @@
+package example.travel {
+package model {
+
+ import net.liftweb.common.{Full,Box,Empty,Failure}
+ import net.liftweb.mapper._
+
+ object OrderAuction extends OrderAuction with LongKeyedMetaMapper[OrderAuction]{
+ override def dbTableName = "order_auctions"
+ }
+
+ class OrderAuction extends LongKeyedMapper[OrderAuction]
+ with IdPK with CreatedUpdated {
+ def getSingleton = OrderAuction
+ // fields
+ object name extends MappedString(this, 150)
+
+ // relationships
+ object order extends LongMappedMapper(this, Order){
+ override def dbColumnName = "order_id"
+ }
+ // def auction =
+ }
+
+
+}}
View
44 chapter-five/src/main/scala/example/travel/model/Supplier.scala
@@ -0,0 +1,44 @@
+package example.travel {
+package model {
+
+ import net.liftweb.common.{Full,Box,Empty,Failure}
+ import net.liftweb.sitemap.Loc._
+ import net.liftweb.mapper._
+ import scala.xml.NodeSeq
+
+ object Supplier
+ extends Supplier
+ with LongKeyedMetaMapper[Supplier]
+ with CRUDify[Long,Supplier]{
+ override def dbTableName = "suppliers"
+ override def fieldOrder = name :: email :: address :: telephone :: opening_hours :: Nil
+ override def pageWrapper(body: NodeSeq) =
+ <lift:surround with="admin" at="content">{body}</lift:surround>
+ override def calcPrefix = List("admin",_dbTableNameLC)
+ override def displayName = "Supplier"
+ override def showAllMenuLocParams = LocGroup("admin") :: Nil
+ override def createMenuLocParams = LocGroup("admin") :: Nil
+ override def viewMenuLocParams = LocGroup("admin") :: Nil
+ override def editMenuLocParams = LocGroup("admin") :: Nil
+ override def deleteMenuLocParams = LocGroup("admin") :: Nil
+ }
+
+ class Supplier extends LongKeyedMapper[Supplier]
+ with IdPK with OneToMany[Long, Supplier] with CreatedUpdated {
+ def getSingleton = Supplier
+ // fields
+ object name extends MappedString(this, 150)
+ object telephone extends MappedString(this, 30)
+ object email extends MappedEmail(this, 200)
+ object address extends MappedText(this)
+ object opening_hours extends MappedString(this, 255)
+
+ // relationships
+ object auctions extends MappedOneToMany(Auction, Auction.supplier,
+ OrderBy(Auction.ends_at, Descending))
+ with Owned[Auction]
+ with Cascade[Auction]
+ }
+
+
+}}
View
0 chapter-five/src/main/scala/example/travel/snippet/.keep
No changes.
View
52 chapter-five/src/main/scala/example/travel/snippet/Details.scala
@@ -0,0 +1,52 @@
+package example.travel {
+package snippet {
+
+ import scala.xml.{NodeSeq,Text}
+ import net.liftweb.common.{Full,Box,Empty,Failure,Loggable}
+ import net.liftweb.util.Helpers._
+ import net.liftweb.http.{S,StatefulSnippet,SHtml}
+ import net.liftweb.http.js.JsCmds.{Noop}
+ import net.liftweb.mapper.{MaxRows,By,OrderBy,Descending,StartAt}
+ import example.travel.model.{Auction,Bid,Customer}
+ import example.travel.lib.AuctionInstanceHelpers
+ import example.travel.comet.{AuctionServer,NewBid,CurrentAuction}
+
+ class Details extends StatefulSnippet with AuctionInstanceHelpers with Loggable {
+
+ val dispatch: DispatchIt = {
+ case "show" => show _
+ case "bid" => bid _
+ }
+
+ lazy val auction = Auction.find(By(Auction.id,S.param("id").map(_.toLong).openOr(0L)))
+
+ def bid(xhtml: NodeSeq): NodeSeq = {
+ var amountBox: Box[String] = Empty
+ def submit = boxToNotice(
+ "Your bid was accepted!",
+ "Unable to place bid at this time."){
+ (for(a <- auction; v <- a.barter(amountBox)) yield v).pass(box =>
+ if(!box.isEmpty)
+ AuctionServer ! NewBid(auction.map(_.id.is).openOr(0L),
+ amountBox.openOr("0").toDouble, S.session.map(_.uniqueId)))
+ }
+ SHtml.ajaxForm(bind("b",xhtml,
+ "amount" -%> SHtml.text(amountBox.openOr(""), s => amountBox = Box.!!(s)) % ("id" -> "amount"),
+ "submit" -> SHtml.ajaxSubmit("Place Bid", { () => submit; Noop })
+ ))
+ }
+
+ def show(xhtml: NodeSeq): NodeSeq = {
+ println("Looking for comet: " + S.session.map(_.findComet("AuctionUpdater")).openOr(Nil).toString)
+
+ S.session.map(_.findComet("AuctionUpdater")).openOr(Nil).foreach(_ ! CurrentAuction(auction))
+ auction.map(a =>
+ bind("a", single(a, xhtml),
+ "current_amount" -> <span>{leadingBid.toString}</span> % ("id" -> "current_amount"),
+ "next_amount" -> <span>{minimumBid.toString}</span> % ("id" -> "next_amount")
+ )).openOr(Text("That auction does not exist"))
+ }
+
+ }
+
+}}
View
8 chapter-five/src/main/scala/example/travel/snippet/HelloWorld.scala
@@ -0,0 +1,8 @@
+package example.travel.snippet
+
+import net.liftweb.util.Props
+
+class HelloWorld {
+ def howdy = <span>Welcome to lift-travel at {new _root_.java.util.Date}. Mode is {Props.mode}</span>
+}
+
View
30 chapter-five/src/main/scala/example/travel/snippet/Listings.scala
@@ -0,0 +1,30 @@
+package example.travel {
+package snippet {
+
+ import scala.xml.{NodeSeq,Text}
+ import net.liftweb.util.Helpers._
+ import net.liftweb.http.{S,DispatchSnippet}
+ import net.liftweb.mapper.{MaxRows,By,OrderBy,Descending,StartAt}
+ import net.liftweb.mapper.view.{MapperPaginatorSnippet}
+ import example.travel.model.Auction
+ import example.travel.lib.AuctionHelpers
+
+ class Listings extends DispatchSnippet with AuctionHelpers {
+ override def dispatch = {
+ case "all" => all _
+ case "top" => top _
+ case "paginate" => paginator.paginate _
+ }
+
+ val paginator = new MapperPaginatorSnippet(Auction){
+ override def itemsPerPage = 5
+ constantParams = OrderBy(Auction.id, Descending) :: Nil
+ }
+
+ def all(xhtml: NodeSeq): NodeSeq = many(paginator.page, xhtml)
+
+ def top(xhtml: NodeSeq): NodeSeq =
+ many(Auction.findAll(MaxRows(3), OrderBy(Auction.id, Descending)), xhtml)
+ }
+
+}}
View
0 chapter-five/src/main/scala/example/travel/view/.keep
No changes.
View
11 chapter-five/src/main/webapp/404.html
@@ -0,0 +1,11 @@
+<lift:surround with="wide" at="content">
+
+<div id="box1" class="topbg">
+ <h1>Ooops!</h1>
+ <h3>We couldnt find the page you were looking for, either it has been moved or removed.</h3>
+ <p>Quisque eleifend. Phasellus tempor vehicula justo. Aliquam lacinia metus ut elit. estibulum sem magna, elementum ut, vestibulum eu, facilisis quis, arcu. Suspendisse iaculis mauris nec lorem:</p>
+ <p>Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed blandit. Phasellus pellentesque, ante nec iaculis dapibus, eros justo auctor lectus, a lobortis lorem mauris quis nunc. Praesent pellentesque facilisis elit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos hymenaeos. In hac habitasse platea dictumst. Nullam id ante eget dui vulputate aliquam.</p>
+</div>
+
+</lift:surround>
+
View
21 chapter-five/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd">
+<web-app>
+ <filter>
+ <filter-name>LiftFilter</filter-name>
+ <display-name>Lift Filter</display-name>
+ <description>The Filter that intercepts lift calls</description>
+ <filter-class>bootstrap.liftweb.StaxLiftFilter</filter-class>
+ <!-- <filter-class>net.liftweb.http.LiftFilter</filter-class> -->
+ </filter>
+ <!-- <resource-ref>
+ <res-ref-name>jdbc/liftinaction</res-ref-name>
+ <res-type>javax.sql.DataSource</res-type>
+ <res-auth>Container</res-auth>
+ </resource-ref> -->
+ <filter-mapping>
+ <filter-name>LiftFilter</filter-name>
+ <url-pattern>/*</url-pattern>
+ </filter-mapping>
+</web-app>
View
3 chapter-five/src/main/webapp/admin/auctions.html
@@ -0,0 +1,3 @@
+<lift:surround with="admin" at="content">
+ AUCTIONS
+</lift:surround>
View
311 chapter-five/src/main/webapp/admin/css/coolblue.css
@@ -0,0 +1,311 @@
+/* -----------------------------------------------------------------------------
+ Template Name : CoolBlue
+ Template Code : S-0031
+ Version : 1.0
+ Author : Erwin Aligam
+ Author URI : http://www.styleshout.com/
+ Last Date Modified : March 10, 2010
+ -------------------------------------------------------------------------------- */
+
+/* ------------------------------------------------------------------------------
+ G E N E R A L
+--------------------------------------------------------------------------------- */
+body {
+ font: 12px/170% 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, Sans-Serif;
+ color: #777;
+ margin: 0; padding: 0;
+}
+/* links */
+a:link, a:visited {
+ text-decoration: none;
+ color: #FF409F;
+}
+a:hover { color: #147DB6; }
+a:link.more, a:visited.more {
+ float: left;
+ margin-top: 20px;
+ margin-right: 5px;
+ padding: 6px 8px;
+ border: 1px solid #2177A5;
+ background-color: #227bad;
+ text-transform: lowercase;
+ text-decoration: none;
+ font-weight: bold;
+ color: #fff;
+}
+a:hover.more {
+ border: 1px solid #FF2B95;
+ background-color: #FF3399;
+}
+
+/* Headers */
+h1, h2, h3, h4 {
+ font: bold 1em/1.5em 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, Sans-Serif;
+ color: #555;
+ margin: 8px 25px;
+}
+h1 { font-size: 3.7em; font-weight: normal; letter-spacing: -2px; }
+h2 { font-size: 2.8em; font-weight: normal; }
+h3 { font-size: 2.2em; font-weight: normal; letter-spacing: -0.5px; padding-top: 15px; }
+h4 { font-size: 1.5em; }
+
+/* lists */
+ul, ol {
+ margin: 10px 25px;
+ padding: 0 20px;
+}
+ul { list-style: disc; }
+ol { list-style: decimal; }
+
+dt {
+ font-weight: bold;
+ color: #1980AF;
+}
+dd {
+ padding-left: 20px;
+}
+
+p, dl { margin: 10px 25px; }
+
+/* images */
+img {
+ background: #F3F4F5;
+ border: 1px solid #E2E4E7;
+ padding: 10px;
+}
+img.float-right { margin: 5px 0px 10px 10px; }
+img.float-left { margin: 5px 10px 10px 0px; }
+
+code {
+ margin: 3px 0;
+ padding: 20px;
+ text-align: left;
+ display: block;
+ overflow: auto;
+ font: 500 1em/1.5em 'Lucida Console', 'Courier New', Monospace;
+ /* white-space: pre; */
+ border: 1px solid #F0F0F0;
+ background: #F8F8F8;
+ color: #555;
+}
+acronym {
+ cursor: help;
+ border-bottom: 1px dotted #777;
+}
+blockquote {
+ margin: 10px 25px;
+ padding: 10px 20px 10px 32px;
+ border: 1px solid #F0F0F0;
+ background: #f8f8f8 url(/admin/images/quote.gif) no-repeat 12px 12px;
+ font-weight: normal;
+ font-size: 17px;
+ line-height: 1.5em;
+ font-style: italic;
+ font-family: Georgia, 'Times New Roman', Times, Serif;
+ color: #555;
+}
+strong { font-weight: bold; }
+
+/* table */
+table {
+ border-collapse: collapse;
+ margin: 10px 25px;
+}
+tr { background: #FFF; }
+th, td {
+ text-align: left;
+ border-width: 1px;
+ border-style: solid;
+}
+th {
+ padding: .8em 1em;
+ background: #2C76A6;
+ border-color: #308ABA #308ABA #246F97 #308ABA;
+ color: #fff;
+ font-weight: bold;
+}
+td {
+ border-color: #E9E9E9;
+ padding: .7em 1em;
+}
+
+/* form elements */
+form {
+ margin: 10px 25px 10px 25px;
+ padding: 10px 25px 25px 25px;
+ background: #F3F4F5;
+ border: 1px solid #E2E4E7;
+ width: 477px;
+}
+form p {
+ border-bottom: 1px solid #E6E6E6;
+ padding: 12px 0 5px 0; margin: 0;
+ color: #2C76A6;
+}
+label {
+ font-weight: bold;
+ color: #666666;
+}
+input, select, textarea {
+ margin: 5px 0;
+ padding: 7px 6px;
+ color: #6A6969;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #D4D4D4 #EBEBEB #EBEBEB #D4D4D4;
+ font: 11px 'Lucida Grande', Verdana, Helvetica, sans-serif;
+}
+input:focus, select:focus, textarea:focus {
+ color: #19465D;
+ background: #EEF8FB;
+}
+#name, #email, #message, #website {
+ width: 460px;
+}
+input.button {
+ font: bold 12px Arial, Sans-serif;
+ height: 30px;
+ margin: 0;
+ padding: 2px 3px;
+ color: #FFF;
+ background: #2C76A6;
+
+ border-width: 1px;
+ border-style: solid;
+ border-color: #86BBDF #245F86 #245F86 #86BBDF;
+ cursor: pointer;
+}
+
+/* ------------------------------------------------------------------------------
+ L A Y O U T
+--------------------------------------------------------------------------------- */
+
+/* header */
+#header-wrap {
+ float: left;
+ height: 100px;
+ width: 100%;
+ background: url(/admin/images/header-bg.jpg) repeat-x;
+}
+#header {
+ position: relative;
+ margin: 0 auto;
+ width: 1000px;
+}
+
+#header h1#logo-text { margin: 0; padding: 0; }
+#header h1#logo-text a {
+ position: absolute;
+ margin: 0; padding: 0 5px 0 0;
+ font: bold 55px 'Trebuchet MS', 'Helvetica Neue', Arial, Sans-Serif;
+ letter-spacing: -4px;
+ color: #333;
+ text-decoration: none;
+
+ /* change the values of top and left to adjust the position of the logo*/
+ top: 82px; left: 25px;
+}
+#header p#slogan {
+ position: absolute;
+ margin: 0; padding: 0 5px 0 0;
+ font-family: 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, Sans-Serif;
+ font-weight: bold;
+ font-size: 11px;
+ line-height: 1.8em;
+ font-style: normal;
+ letter-spacing: -.5px;
+ color: #0d6684;
+
+ /* change the values of top and left to adjust the position */
+ top: 142px; left: 30px;
+}
+
+
+/* navigation */
+#header #nav {
+ position: absolute;
+ left: 15px; top: 25px;
+ margin: 0; padding: 0;
+ width: 750px;
+}
+#header #nav ul {
+ float: left;
+ list-style: none;
+ margin: 0; padding: 0;
+ height: 45px;
+}
+#header #nav ul li {
+ float: left;
+ margin: 0; padding: 0;
+}
+#header #nav ul li a {
+ float:left;
+ margin: 0;
+ padding: 0 15px 29px 15px;
+ color: #baa7a7;
+ font: bold 12px 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, Sans-Serif;
+}
+#header #nav ul li a:hover,
+#header #nav ul li a:active {
+ border: none;
+ color: #fff;
+}
+#header #nav ul li#current a {
+ background: transparent url(/admin/images/current.gif) no-repeat center bottom;
+ color: #fff;
+}
+
+/* pagenavigation */
+.navigation {
+ margin: 10px 20px; padding: 0;
+ width: 560px;
+}
+.navigation a:link,
+.navigation a:visited {
+ float: left;
+ display: block;
+ margin: 10px 10px 0 0;
+ padding: 5px 7px;
+ text-transform: lowercase;
+ text-decoration: none;
+ font-weight: bold;
+ color: #fff;
+ background: #2C76A6;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #86BBDF #245F86 #245F86 #86BBDF;
+}
+.navigation a:hover {
+ background: #FF3399;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #FF75BA #EA0075 #EA0075 #FF75BA;
+}
+
+/* ------------------------------------------------------------------------------
+ M I S C
+--------------------------------------------------------------------------------- */
+
+/* alignment classes & additional classes */
+.float-left { float: left; }
+.float-right { float: right; }
+.align-left { text-align: left; }
+.align-right { text-align: right; }
+.no-border { border: none; }
+.no-bg { background: none; }
+
+/* clearing */
+.fix {
+ clear: both;
+ height: 1px;
+ margin: -1px 0 0;
+ overflow: hidden;
+}
+.clear { display:inline-block; }
+.clear:after {
+ display:block;
+ visibility:hidden;
+ clear:both;
+ height:0;
+ content: " ";
+}
View
42 chapter-five/src/main/webapp/admin/css/enhancements.css
@@ -0,0 +1,42 @@
+/* ------------------------------------------------------------------------------
+ E N H A N C E M E N T S
+--------------------------------------------------------------------------------- */
+
+/* css3 design enhancements */
+a:link.more, a:visited.more {
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+
+ text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
+}
+img {
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+}
+#header h1#logo-text a {
+ text-shadow: 1px 1px 0 #fff;
+}
+#header #nav ul,
+#header p#rss a {
+ text-shadow: 1px 2px 0 rgba(0,0,0,0.9);
+}
+
+p.thumbs img {
+ -moz-box-shadow: 1px 1px 3px #184569 ;
+ -webkit-box-shadow: 1px 1px 3px #184569;
+ box-shadow: 1px 1px 3px #184569;
+}
+.right .image-section img {
+ -moz-border-radius: 4px;
+ -webkit-border-radius: 4px;
+ border-radius: 4px;
+
+ -moz-box-shadow: 3px 3px 3px #F3F4F5, -3px -3px 3px #F3F4F5;
+ -webkit-box-shadow: 3px 3px 3px #F3F4F5, -3px -3px 3px#F3F4F5;
+ box-shadow: 3px 3px 3px#F3F4F5, -3px -3px 3px #F3F4F5;
+}
+.left p.dateinfo { text-shadow: 0 1px 1px rgba(0, 0, 0, 0.6); }
+.left p.dateinfo span { text-shadow: none; }
+
View
44 chapter-five/src/main/webapp/admin/css/reset.css
@@ -0,0 +1,44 @@
+/* http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/ */
+
+html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre,
+a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp,
+small, strike, strong, sub, sup, tt, var,dl, dt, dd, ol, ul, li, fieldset, form, label, legend,
+table, caption, tbody, tfoot, thead, tr, th, td {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ font-weight: inherit;
+ font-style: inherit;
+ font-size: 100%;
+ font-family: inherit;
+ vertical-align: baseline;
+}
+/* remember to define focus styles! */
+:focus {
+ outline: 0;
+}
+body {
+ line-height: 1;
+ color: black;
+ background: white;
+}
+ol, ul {
+ list-style: none;
+}
+/* tables still need 'cellspacing="0"' in the markup */
+table {
+ border-collapse: separate;
+ border-spacing: 0;
+}
+caption, th, td {
+ text-align: left;
+ font-weight: normal;
+}
+blockquote:before, blockquote:after,
+q:before, q:after {
+ content: "";
+}
+blockquote, q {
+ quotes: "" "";
+}
View
23 chapter-five/src/main/webapp/admin/css/screen.css
@@ -0,0 +1,23 @@
+/* theme screen stylesheets */
+
+/* import stylesheets and hide from IE/Mac \*/
+@import url("reset.css");
+@import url("coolblue.css");
+@import url("enhancements.css");
+/* end import/hide */
+
+/* content */
+#content-wrap {
+ clear: both;
+ margin: 0; padding: 0;
+ background: #fff;
+ width: 100%;
+ float: left;
+}
+#content {
+ width: 1000px;
+ margin: 0 auto;
+ padding: 0 0 20px 0;
+ background: #FFF url(../images/content.gif) repeat-y center top;
+/* overflow: hidden;*/
+}
View
BIN chapter-five/src/main/webapp/admin/images/current.gif
Diff not rendered.
View
BIN chapter-five/src/main/webapp/admin/images/header-bg.jpg
Diff not rendered.
View
BIN chapter-five/src/main/webapp/admin/images/header-bg.png
Diff not rendered.
View
5 chapter-five/src/main/webapp/admin/index.html
@@ -0,0 +1,5 @@
+<lift:surround with="admin" at="content">
+ <h2>Welcome</h2>
+ <p>This is the basic administration interface for the Lift travel example.</p>
+ <p>Choose an option from the top menu to get started</p>
+</lift:surround>
View
8 chapter-five/src/main/webapp/admin/login.html
@@ -0,0 +1,8 @@
+<lift:surround with="admin" at="content">
+
+ <h2>Login</h2>
+ <p>Please login with some valid credentials to continue</p>
+
+
+
+</lift:surround>
View
3 chapter-five/src/main/webapp/admin/suppliers.html
@@ -0,0 +1,3 @@
+<lift:surround with="admin" at="content">
+ SUPPLIERS
+</lift:surround>
View
45 chapter-five/src/main/webapp/auction.html
@@ -0,0 +1,45 @@
+<lift:surround with="wide" at="content">
+ <div class="auction">
+
+ <!-- <lift:comet type="AuctionUpdater"><live:countdown /></lift:comet> -->
+ <lift:comet type="AuctionUpdater" />