Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

much more

  • Loading branch information...
commit 06845a8fb4b660292a5a7bd56087ae13ffacd326 1 parent bdf2d20
@kristianmandrup authored
Showing with 1,994 additions and 9,984 deletions.
  1. +4 −1 www/app.js
  2. +3 −0  www/app.rb
  3. +6 −5 www/app/model/Account.js
  4. +5 −4 www/app/model/ContactInfo.js
  5. +6 −6 www/app/model/Mail.js
  6. +6 −3 www/app/model/Photo.js
  7. +1 −1  www/app/model/Property.js
  8. +22 −0 www/app/model/Settings.js
  9. +8 −4 www/app/model/User.js
  10. +2 −3 www/app/model/account/Landlord.js
  11. +2 −1  www/app/model/account/Tenant.js
  12. +8 −7 www/app/model/mail/Box.js
  13. +11 −11 www/app/model/mail/System.js
  14. +1 −3 www/app/model/payment/CreditCard.js
  15. +1 −3 www/app/model/photo/Gallery.js
  16. +1 −3 www/app/model/property/Details.js
  17. +2 −3 www/app/model/property/Location.js
  18. +4 −6 www/app/model/property/RentalPeriod.js
  19. +33 −7 www/app/model/property/rental_period/Costs.js
  20. +35 −0 www/app/model/search/Criteria.js
  21. +18 −0 www/app/model/search/Favorite.js
  22. +7 −5 www/app/model/{Preferences.js → settings/Account.js}
  23. +0 −24 www/app/view/Map.js
  24. +4 −49 www/app/view/Navigation.js
  25. +0 −20 www/app/view/PropertyList.js
  26. +0 −33 www/app/view/TopBar.js
  27. +1 −0  www/app/view/home/Page.js
  28. +2 −2 www/app/view/home/TopBar.js
  29. +8 −0 www/app/view/home/btn/About.js
  30. +2 −2 www/app/view/{nav/button/Home.js → home/btn/New.js}
  31. +8 −0 www/app/view/home/btn/Settings.js
  32. +7 −0 www/app/view/logo/Image.js
  33. 0  www/app/view/{nav/button/mail → mail/btn}/Inbox.js
  34. +1 −1  www/app/view/mail/inbox/Content.js
  35. +13 −0 www/app/view/mail/inbox/messages/List.js
  36. +2 −2 www/app/view/registration/landlord/register/Content.js
  37. +11 −0 www/app/view/registration/login/Facebook.js
  38. +13 −0 www/app/view/registration/login/Twitter.js
  39. +2 −2 www/app/view/registration/tenant/register/Content.js
  40. 0  www/app/view/{ → sandbox}/Main.js
  41. +34 −3 www/app/view/search/Content.js
  42. +8 −10 www/app/view/search/agents/Content.js
  43. +8 −0 www/app/view/search/btn/Agents.js
  44. +8 −0 www/app/view/search/btn/Favorites.js
  45. +8 −0 www/app/view/search/btn/History.js
  46. +8 −0 www/app/view/search/btn/Property.js
  47. +8 −0 www/app/view/search/btn/Search.js
  48. +9 −0 www/app/view/search/criteria/Furnishment.js
  49. +3 −4 www/app/view/search/criteria/Location.js
  50. +27 −19 www/app/view/search/criteria/Page.js
  51. +6 −8 www/app/view/search/criteria/PropertyType.js
  52. +10 −0 www/app/view/search/criteria/Radius.js
  53. +12 −0 www/app/view/search/criteria/RentalCost.js
  54. +10 −0 www/app/view/search/criteria/RentalPeriod.js
  55. +10 −0 www/app/view/search/criteria/Rooms.js
  56. +21 −0 www/app/view/search/criteria/Rules.js
  57. +11 −0 www/app/view/search/criteria/Size.js
  58. +8 −10 www/app/view/search/favorites/Content.js
  59. +22 −0 www/app/view/settings/account/mail/Options.js
  60. +27 −0 www/app/view/settings/currency/List.js
  61. +15 −0 www/app/view/settings/language/List.js
  62. +16 −0 www/app/view/settings/map/Options.js
  63. +18 −0 www/app/view/settings/search/Page.js
  64. +7 −0 www/app/view/start/Image.js
  65. +11 −0 www/app/view/start/Languages.js
  66. +15 −0 www/app/view/start/Page.js
  67. +11 −0 www/app/view/util/FloatingTooltip.js
  68. +0 −17 www/config.rb
  69. +7 −0 www/docs/Command line.md
  70. 0  www/docs/{ccustomize_sencha.md → Customize_sencha.md}
  71. +13 −2 www/index.html
  72. +163 −0 www/lib/plugins/SliderFieldInput.js
  73. +138 −0 www/lib/plugins/SliderFieldText.js
  74. +1 −9,694 www/resources/css/app.css
  75. BIN  www/resources/images/FriendlyRentTrans.png
  76. BIN  www/resources/images/flags64.png
  77. BIN  www/resources/images/flags64_semi.png
  78. +531 −0 www/resources/javascript/i18n.js
  79. +4 −0 www/resources/javascript/locale_da.js
  80. BIN  www/resources/sass/.sass-cache/02e2acbad075adbb3c3e4710f24ffcb09bc097bb/_float.scssc
  81. BIN  www/resources/sass/.sass-cache/02e2acbad075adbb3c3e4710f24ffcb09bc097bb/_hacks.scssc
  82. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_buttons.scssc
  83. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_carousel.scssc
  84. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_form-sliders.scssc
  85. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_form.scssc
  86. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_img.scssc
  87. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_indexbar.scssc
  88. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_list.scssc
  89. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_loading-spinner.scssc
  90. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_map.scssc
  91. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_media.scssc
  92. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_msgbox.scssc
  93. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_panel.scssc
  94. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_picker.scssc
  95. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_sheets.scssc
  96. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_tabs.scssc
  97. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_toolbar-forms.scssc
  98. BIN  www/resources/sass/.sass-cache/0cc059c506fe0611e713576e7fe12df278dbc2d7/_toolbar.scssc
  99. BIN  www/resources/sass/.sass-cache/130337b5cfa526abe3670cc721f9cf39ba0d638d/_css3.scssc
  100. BIN  www/resources/sass/.sass-cache/130337b5cfa526abe3670cc721f9cf39ba0d638d/_support.scssc
  101. BIN  www/resources/sass/.sass-cache/2f86792dce7d2835f047eb3809642bb97536b0e6/app.scssc
  102. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_blueprint-grid.scssc
  103. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_carbon-fiber.scssc
  104. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_checkerboard.scssc
  105. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_cicada.scssc
  106. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_gradients.scssc
  107. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_houndstooth.scssc
  108. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_lined-paper.scssc
  109. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_madras.scssc
  110. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_noise.scssc
  111. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_polka-dot.scssc
  112. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_radial-overlay.scssc
  113. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_striped.scssc
  114. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_stripes.scssc
  115. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_tablecloth.scssc
  116. BIN  www/resources/sass/.sass-cache/3ac0f11328ff0693a8843e69028dd58800082fa2/_tartan.scssc
  117. BIN  www/resources/sass/.sass-cache/504a8af0937cbeacde56c7855c79c9bf1c58fe50/_all.scssc
  118. BIN  www/resources/sass/.sass-cache/504a8af0937cbeacde56c7855c79c9bf1c58fe50/_core.scssc
  119. BIN  www/resources/sass/.sass-cache/504a8af0937cbeacde56c7855c79c9bf1c58fe50/_global.scssc
  120. BIN  www/resources/sass/.sass-cache/504a8af0937cbeacde56c7855c79c9bf1c58fe50/_mixins.scssc
  121. BIN  www/resources/sass/.sass-cache/504a8af0937cbeacde56c7855c79c9bf1c58fe50/_variables.scssc
  122. BIN  www/resources/sass/.sass-cache/504a8af0937cbeacde56c7855c79c9bf1c58fe50/_widgets.scssc
  123. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_appearance.scssc
  124. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_background-clip.scssc
  125. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_background-origin.scssc
  126. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_background-size.scssc
  127. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_border-radius.scssc
  128. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_box-shadow.scssc
  129. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_box-sizing.scssc
  130. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_box.scssc
  131. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_columns.scssc
  132. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_font-face.scssc
  133. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_images.scssc
  134. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_inline-block.scssc
  135. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_opacity.scssc
  136. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_shared.scssc
  137. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_text-shadow.scssc
  138. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_transform.scssc
  139. BIN  www/resources/sass/.sass-cache/77a3949ea5bb3fba437fda459882aa277bd33040/_transition.scssc
  140. BIN  www/resources/sass/.sass-cache/ac4d8f820baeccd56133b29f2021fd76fdfa698b/_core.scssc
  141. BIN  www/resources/sass/.sass-cache/ac4d8f820baeccd56133b29f2021fd76fdfa698b/_layout.scssc
  142. BIN  www/resources/sass/.sass-cache/ac4d8f820baeccd56133b29f2021fd76fdfa698b/_reset.scssc
  143. BIN  www/resources/sass/.sass-cache/bd6e6cdce418ffeb82268dfe170c53a1dda06e31/_link-colors.scssc
  144. BIN  www/resources/sass/.sass-cache/d468a8f2324bff09adcbd0d8e818ede0414dc825/_background.scssc
  145. BIN  www/resources/sass/.sass-cache/d468a8f2324bff09adcbd0d8e818ede0414dc825/_color.scssc
  146. BIN  www/resources/sass/.sass-cache/d79bed92216a4e49563ad1bb13638270fd3743c8/_colors.scssc
  147. BIN  www/resources/sass/.sass-cache/d79bed92216a4e49563ad1bb13638270fd3743c8/_typography.scssc
  148. +22 −6 www/resources/sass/app.scss
  149. +253 −0 www/resources/sass/flags64-semi.scss
  150. +251 −0 www/resources/sass/flags64.scss
View
5 www/app.js
@@ -2,7 +2,7 @@ Ext.application({
name: "FriendlyRent",
requires: [
- 'Ext.MessageBox', 'FriendlyRent.view.Navigation'
+ 'FriendlyRent.view.Navigation'
],
// models: ["Note"],
@@ -42,6 +42,9 @@ Ext.application({
console.log('mainLaunch');
// if (!device || !this.launched) { return; }
+ I18n.defaultLocale = "da";
+ I18n.locale = "da";
+
console.log('Launched!');
// Destroy the #appLoadingIndicator element
View
3  www/app.rb
@@ -4,6 +4,9 @@
# Make sure our assets reload on every request.
set :static_cache_control, [:public, :max_age => 0]
+# set :bind, 'localhost'
+set :port, 4567
+
# Pick which set of files get served depending
# on our environment
case ENV["RACK_ENV"] || "development"
View
11 www/app/model/Account.js
@@ -2,15 +2,16 @@ Ext.define('FriendlyRent.model.Account', {
extend: 'Ext.data.Model',
config: {
- identifier: 'account',
-
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
- {name: 'dateCreated', type: 'date', dateFormat: 'c' },
- {name: 'favorites', type: 'favorites'},
- {name: 'mail_system', type: 'mail_system'}
+ {name: 'dateCreated', type: 'date', dateFormat: 'c' }
+ ],
+ hasMany: [
+ {name: 'favorites', model: 'search.Favorite'}
],
+ hasOne: {name: 'mailSystem', model: 'mail.System'},
+
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'dateCreated' }
View
9 www/app/model/ContactInfo.js
@@ -1,4 +1,4 @@
-Ext.define('FriendlyRent.model.ContactInfo', {
+Ext.define('model.ContactInfo', {
extend: 'Ext.data.Model',
config: {
@@ -8,9 +8,10 @@ Ext.define('FriendlyRent.model.ContactInfo', {
fields: [
{name: 'id', type: 'int'},
{name: 'dateCreated', type: 'date', dateFormat: 'c' },
- {name: 'contact_hours', type: 'auto'},
- {name: 'phone', type: 'auto'},
- {name: 'alt_phone', type: 'auto'}
+
+ {name: 'contact_hours', type: 'string'},
+ {name: 'phone', type: 'string'},
+ {name: 'alt_phone', type: 'string'}
],
validations: [
{ type: 'presence', field: 'id' },
View
12 www/app/model/Mail.js
@@ -1,4 +1,4 @@
-Ext.define('FriendlyRent.model.Mail', {
+Ext.define('model.Mail', {
extend: 'Ext.data.Model',
config: {
@@ -6,16 +6,16 @@ Ext.define('FriendlyRent.model.Mail', {
fields: [
{name: 'id', type: 'int'},
{name: 'dateCreated', type: 'date', dateFormat: 'c' },
- {name: 'subject', type: 'auto'},
- {name: 'body', type: 'auto'},
- {name: 'type', type: 'auto'}, // # payment, services, contacts, legal
- {name: 'sender', type: 'account'},
- {name: 'receivers', type: 'array'}
+ {name: 'subject', type: 'string'},
+ {name: 'body', type: 'string'},
+ {name: 'type', type: 'string'}, // # payment, services, contacts, legal
// IMPORTANT: can't have a status like bookmarked or replied, as a message
// will appear in multiple accounts and for each account have a uniques status
],
+ hasOne: {name: 'sender', type: 'account'},
+ hasMany: {name: 'receivers', type: 'array'},
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'dateCreated' },
View
9 www/app/model/Photo.js
@@ -1,4 +1,4 @@
-Ext.define('FriendlyRent.model.Photo', {
+Ext.define('model.Photo', {
extend: 'Ext.data.Model',
config: {
@@ -6,8 +6,11 @@ Ext.define('FriendlyRent.model.Photo', {
fields: [
{name: 'id', type: 'int'},
{name: 'dateCreated', type: 'date', dateFormat: 'c' },
- {name: 'name', type: 'auto'},
- {name: 'description', type: 'auto'}
+
+ {name: 'name', type: 'string'},
+ {name: 'description', type: 'string'},
+ // base 64 encoded image
+ {name: 'image', type: 'string'}
],
validations: [
{ type: 'presence', field: 'id' },
View
2  www/app/model/Property.js
@@ -1,4 +1,4 @@
-Ext.define('FriendlyRent.model.Property', {
+Ext.define('model.Property', {
extend: 'Ext.data.Model',
config: {
View
22 www/app/model/Settings.js
@@ -0,0 +1,22 @@
+Ext.define('model.Settings', {
+ extend: 'Ext.data.Model',
+
+ config: {
+ idProperty: 'id',
+ fields: [
+ {name: 'id', type: 'int'},
+ {name: 'dateCreated', type: 'date', dateFormat: 'c' },
+
+ {name: 'languageCode', type: 'string'},
+ {name: 'currencyCodeISO', type: 'string'},
+ ],
+ hasOne: [
+ {name: 'account', model: 'FriendlyRent.model.settings.Account'}
+ ],
+ validations: [
+ { type: 'presence', field: 'id' },
+ { type: 'presence', field: 'dateCreated' },
+ { type: 'presence', field: 'subject', message: 'Please enter a subject for this mail' }
+ ]
+ },
+});
View
12 www/app/model/User.js
@@ -1,4 +1,4 @@
-Ext.define('FriendlyRent.model.User', {
+Ext.define('model.User', {
extend: 'Ext.data.Model',
config: {
@@ -11,11 +11,15 @@ Ext.define('FriendlyRent.model.User', {
{name: 'email', type: 'email'},
{name: 'password', type: 'auto'},
- {name: 'landlord_account', type: 'landlord_account'},
- {name: 'tenant_account', type: 'tenant_account'}
-
// {name: 'address', type: 'address'},
],
+ hasOne: [
+ {name: 'landlord_account', model: 'account.Landlord'}
+ ]
+ ,
+ {name: 'tenant_account', type: 'account.Tenant'}
+
+
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'dateCreated' }
View
5 www/app/model/account/Landlord.js
@@ -1,15 +1,14 @@
-Ext.define('FriendlyRent.model.account.Landlord', {
+Ext.define('account.Landlord', {
extend: 'Ext.data.Model',
config: {
- identifier: 'landlord_account',
-
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
{name: 'dateCreated', type: 'date', dateFormat: 'c' },
{name: 'contact_info', type: 'contact_info'}
],
+ belongsTo: 'User',
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'dateCreated' }
View
3  www/app/model/account/Tenant.js
@@ -1,4 +1,4 @@
-Ext.define('FriendlyRent.model.account.Tenant', {
+Ext.define('account.Tenant', {
extend: 'Ext.data.Model',
config: {
@@ -10,6 +10,7 @@ Ext.define('FriendlyRent.model.account.Tenant', {
{name: 'dateCreated', type: 'date', dateFormat: 'c' },
{name: 'contact_requests_made', type: 'int'}
],
+ belongsTo: 'User',
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'dateCreated' }
View
15 www/app/model/mail/Box.js
@@ -1,16 +1,17 @@
-Ext.define('FriendlyRent.model.mail.Box', {
+Ext.define('mail.Box', {
extend: 'Ext.data.Model',
config: {
- identifier: 'mailbox',
-
idProperty: 'id',
fields: [
- {name: 'id', type: 'int'}
-
- {name: 'messages', type: 'array'},
- {name: 'bookmarks', type: 'array'}
+ {name: 'id', type: 'int'}
],
+ hasMany: [
+ {name: 'messages', model: 'Mail'},
+ {name: 'bookmarks', model: 'Mail'}
+ ]
+
+ belongsTo: 'mail.System',
validations: [
{ type: 'presence', field: 'id' }
]
View
22 www/app/model/mail/System.js
@@ -1,22 +1,22 @@
-Ext.define('FriendlyRent.model.mail.System', {
+Ext.define('mail.System', {
extend: 'Ext.data.Model',
config: {
- identifier: 'mail_system',
-
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
{name: 'dateCreated', type: 'date', dateFormat: 'c' }
-
- {name: 'inbox', type: 'mail_box'},
- {name: 'sentbox', type: 'mail_box'},
- {name: 'trashbox', type: 'mail_box'}
-
- {name: 'replied', type: 'array'},
- {name: 'received_reply', type: 'array'}
-
],
+ hasOne: [
+ {name: 'inbox', model: 'mail.Box'},
+ {name: 'sentbox', model: 'mail.Box'},
+ {name: 'trashbox', model: 'mail.box'}
+ ],
+ hasMany: [
+ {name: 'replied', model: 'Mail'},
+ {name: 'received_reply', model: 'Mail'}
+ ],
+
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'dateCreated' }
View
4 www/app/model/payment/CreditCard.js
@@ -1,9 +1,7 @@
-Ext.define('FriendlyRent.model.payment.CreditCard', {
+Ext.define('payment.CreditCard', {
extend: 'Ext.data.Model',
config: {
- identifier: 'credit_card',
-
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
View
4 www/app/model/photo/Gallery.js
@@ -1,9 +1,7 @@
-Ext.define('FriendlyRent.model.photo.Gallery', {
+Ext.define('photo.Gallery', {
extend: 'Ext.data.Model',
config: {
- identifier: 'photo_gallery',
-
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
View
4 www/app/model/property/Details.js
@@ -1,9 +1,7 @@
-Ext.define('FriendlyRent.model.property.Details', {
+Ext.define('property.Details', {
extend: 'Ext.data.Model',
config: {
- identifier: 'property_details',
-
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
View
5 www/app/model/property/Location.js
@@ -1,9 +1,7 @@
-Ext.define('FriendlyRent.model.property.Location', {
+Ext.define('property.Location', {
extend: 'Ext.data.Model',
config: {
- identifier: 'location',
-
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
@@ -14,6 +12,7 @@ Ext.define('FriendlyRent.model.property.Location', {
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'dateCreated' },
+
{ type: 'presence', field: 'lat' },
{ type: 'presence', field: 'long' }
]
View
10 www/app/model/property/RentalPeriod.js
@@ -1,16 +1,12 @@
-Ext.define('FriendlyRent.model.property.RentalPeriod', {
+Ext.define('property.RentalPeriod', {
extend: 'Ext.data.Model',
config: {
- identifier: 'rental_period',
-
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
{name: 'dateCreated', type: 'date', dateFormat: 'c' },
-
- {name: 'rental_costs', type: 'rental_costs'}
-
+
{name: 'duration', type: 'int'}, // seconds
{name: 'start_date', type: 'date', dateFormat: 'c' },
{name: 'end_date' type: 'date', dateFormat: 'c' },
@@ -18,6 +14,8 @@ Ext.define('FriendlyRent.model.property.RentalPeriod', {
{name: 'publish_at', type: 'date', dateFormat: 'c' }
],
+ hasOne: {name: 'rental_costs', model: 'property.rental_period.costs'}
+
validations: [
{ type: 'presence', field: 'id' },
{ type: 'presence', field: 'dateCreated' },
View
40 www/app/model/property/rental_period/Costs.js
@@ -1,24 +1,21 @@
-Ext.define('FriendlyRent.model.property.rental_period.Costs', {
+Ext.define('property.rental_period.Costs', {
extend: 'Ext.data.Model',
config: {
- identifier: 'rental_costs',
-
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
{name: 'dateCreated', type: 'date', dateFormat: 'c' },
+
{name: 'rent', type: 'int'},
{name: 'utilities', type: 'int'},
- {name: 'tv', type: 'int'},
+ {name: 'tvLicense', type: 'int'},
{name: 'internet', type: 'int'},
{name: 'other' type: 'int'},
+ {name: 'totalRent' type: 'int'},
{name: 'deposit', type: 'int'},
{name: 'prepaid_rent', type: 'int'}
-
-duration, :start_date, :end_date
-
],
validations: [
{ type: 'presence', field: 'id' },
@@ -26,4 +23,33 @@ duration, :start_date, :end_date
{ type: 'presence', field: 'rent' }
]
},
+ // ensure Total Rent is recalculated on any change
+ changeRent: function() {
+ calculateTotalRent();
+ },
+ changeUtilities: function() {
+ calculateTotalRent();
+ },
+ changeTvLicense: function() {
+ calculateTotalRent();
+ },
+ changeInternet: function() {
+ calculateTotalRent();
+ },
+ changeOther: function() {
+ calculateTotalRent();
+ },
+ // Total Rent
+ calculateTotalRent: function() {
+ var calculatedTotalRent = this.getRent() + this.getUtilities() + this.getTvLicense() + this.getInternet() + this.getOther();
+ this.set('totalRent', calculatedTotalRent);
+ calculatedTotalRent;
+ },
+ calculateTotalFirstPayment: function() {
+ this.getDeposit() + this.getPrepaidRent();
+ },
+ // ensure Total Rent is set
+ constructor: function() {
+ calculateTotalRent();
+ }
});
View
35 www/app/model/search/Criteria.js
@@ -0,0 +1,35 @@
+Ext.define('search.Criteria', {
+ extend: 'Ext.data.Model',
+
+ config: {
+ identifier: 'criteria',
+
+ idProperty: 'id',
+ fields: [
+ {name: 'id', type: 'int'},
+ {name: 'dateCreated', type: 'date', dateFormat: 'c' },
+
+ {name: 'location', type: 'string'},
+ {name: 'radius', type: 'int'},
+
+ // comma separated
+ {name: 'propertyTypes', type: 'string'},
+
+ {name: 'sizeMin', type: 'int'},
+ {name: 'sizeMax', type: 'int'},
+
+ {name: 'roomsMin', type: 'int'},
+ {name: 'roomsMax', type: 'int'},
+
+ {name: 'rentalCostMin', type: 'int'},
+ {name: 'rentalCostMax', type: 'int'},
+
+ {name: 'furnishment', type: 'string'},
+ ]
+ validations: [
+ { type: 'presence', field: 'id' },
+ { type: 'presence', field: 'dateCreated' }
+ { type: 'presence', field: 'location' }
+ ]
+ },
+});
View
18 www/app/model/search/Favorite.js
@@ -0,0 +1,18 @@
+Ext.define('search.Favorite', {
+ extend: 'Ext.data.Model',
+
+ config: {
+ idProperty: 'id',
+ fields: [
+ {name: 'id', type: 'int'},
+ {name: 'dateCreated', type: 'date', dateFormat: 'c' },
+
+ {name: 'rating', type: 'int'},
+ {name: 'propertyId', type: 'int'}
+ ],
+ validations: [
+ { type: 'presence', field: 'id' },
+ { type: 'presence', field: 'dateCreated' }
+ ]
+ },
+});
View
12 www/app/model/Preferences.js → www/app/model/settings/Account.js
@@ -1,15 +1,17 @@
-Ext.define('FriendlyRent.model.Preferences', {
+Ext.define('settings.Account', {
extend: 'Ext.data.Model',
config: {
- identifier: 'preferences',
-
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
{name: 'dateCreated', type: 'date', dateFormat: 'c' },
- {name: 'subject', type: 'auto'},
- {name: 'body', type: 'auto'}
+
+ {name: 'languageCode', type: 'string'},
+ {name: 'currencyCodeISO', type: 'string'},
+ ],
+ hasOne: [
+ {name: 'account', model: 'settings.Account'}
],
validations: [
{ type: 'presence', field: 'id' },
View
24 www/app/view/Map.js
@@ -1,24 +0,0 @@
-Ext.define("FriendlyRent.view.Map", {
- extend: 'Ext.navigation.View',
- config: {
- fullscreen: true,
- title: 'Map',
- iconCls: 'maps',
- html: 'map here...',
- items: [
- {
- xtype: 'titlebar',
- docked: 'top',
- title: 'Map'
- },
- {
- xtype: 'map',
- useCurrentLocation: true
- },
- {
- xtype: 'bottombar',
- docked: 'bottom'
- }
- ]
- }
-});
View
53 www/app/view/Navigation.js
@@ -1,58 +1,13 @@
Ext.define('FriendlyRent.view.Navigation', {
extend: 'Ext.navigation.View',
- xtype: 'mainnav',
-
- requires: ['Ext.field.Search', 'Ext.TitleBar'],
+ xtype: 'navigation',
config: {
fullscreen: true,
-
navigationBar: {
- layout: {
- align: 'stretch'
- },
- items: [
- {
- xtype: 'spacer'
- },
- {
- xtype: 'searchfield',
- placeHolder: 'Search...',
- }
- // ,
- // {
- // xtype: 'spacer'
- // },
- // {
- // title: 'Login',
- // iconCls: 'user'
- // }
- ]
- },
- items: [
- {
- xtype: 'panel',
- html: 'test'
- },
- {
- xtype: 'list',
- fullscreen: true,
-
- store: {
- fields: ['name', 'number'],
- sorters: 'name',
- data: [
- {name: 'bla', number: 0},
- {name: 'blo', number: 1},
- {name: 'bliblo', number: 2},
- {name: 'Bliblablo', number: 3},
- {name: 'bliboasdas', number: 4},
- ]
- },
-
- itemTpl: '{name}'
- }
- ]
+ ui: 'dark',
+ docked: 'top'
+ }
}
});
View
20 www/app/view/PropertyList.js
@@ -1,20 +0,0 @@
-Ext.define("FriendlyRent.view.PropertyList", {
- extend: 'Ext.Panel',
- config: {
- items: [
- {
- xtype: 'topbar',
- docked: 'top'
- },
- {
- xtype: 'map',
- useCurrentLocation: true
- }
- ]
- },
-
- launch: function () {
- this.callParent(arguments);
- // add map bottombar
- }
-});
View
33 www/app/view/TopBar.js
@@ -1,33 +0,0 @@
-Ext.define("FriendlyRent.view.TopBar", {
- extend: 'Ext.tab.Panel',
- alias: "widget.topbar",
- config: {
- tabBarPosition: 'top',
- defaults: {
- html: 'text',
- styleHtmlContent: true
- },
- layout: {
- pack: 'center',
- animation: {type: 'slide', duration: 500 }
- },
- items: [
- {
- title: 'Logo',
- iconCls: 'home',
- align: 'left'
- },
- {
- title: 'Search',
- iconCls: 'search',
- align: 'right'
- }
- // {
- // xtype: 'spacer'
- // },
- // {
- // title: 'Login'
- // },
- ]
- }
-});
View
1  www/app/view/home/Page.js
@@ -1,6 +1,7 @@
Ext.define('FriendlyRent.view.home.Page', {
extend: 'Ext.Panel',
alias: 'widget.home.page',
+ requires: ['FriendlyRent.view.home.TopBar', 'FriendlyRent.view.home.NavBar']
config: {
layout: 'vbox'
},
View
4 www/app/view/home/TopBar.js
@@ -12,7 +12,7 @@ Ext.define("FriendlyRent.view.home.TopBar", {
},
items: [
{
- xtype: 'logo'
+ xtype: 'logo.image'
},
{
xtype: 'loginBtn'
@@ -22,4 +22,4 @@ Ext.define("FriendlyRent.view.home.TopBar", {
}
]
}
-});
+});
View
8 www/app/view/home/btn/About.js
@@ -0,0 +1,8 @@
+Ext.define("FriendlyRent.view.home.btn.About", {
+ extend: 'Ext.Button',
+ alias: "widget.home.btn.about",
+ config: {
+ iconCls: 'info_plain2',
+ iconMask: true
+ }
+});
View
4 www/app/view/nav/button/Home.js → www/app/view/home/btn/New.js
@@ -1,6 +1,6 @@
-Ext.define("FriendlyRent.view.button.Home", {
+Ext.define("FriendlyRent.view.home.btn.New", {
extend: 'Ext.Button',
- alias: "widget.homeBtn",
+ alias: "widget.home.btn.new",
config: {
iconCls: 'home',
iconMask: true
View
8 www/app/view/home/btn/Settings.js
@@ -0,0 +1,8 @@
+Ext.define("FriendlyRent.view.home.btn.Settings", {
+ extend: 'Ext.Button',
+ alias: "widget.home.btn.settings",
+ config: {
+ iconCls: 'settings',
+ iconMask: true
+ }
+});
View
7 www/app/view/logo/Image.js
@@ -0,0 +1,7 @@
+Ext.define('FriendlyRent.view.logo.Image', {
+ extend: 'Ext.Img',
+ xtype: 'logo.img',
+ config: {
+ src: 'http://src.sencha.io/http://friendlyrent.dk/resources/images/FriendlyRentTrans.png'
+ }
+});
View
0  www/app/view/nav/button/mail/Inbox.js → www/app/view/mail/btn/Inbox.js
File renamed without changes
View
2  www/app/view/mail/inbox/Content.js
@@ -5,7 +5,7 @@ Ext.define('FriendlyRent.view.mail.inbox.Content', {
layout: 'vbar',
items: [
{
- html: 'Inbox'
+ html: I18n.t('mail.inbox')
},
{
html: 'received mail'
View
13 www/app/view/mail/inbox/messages/List.js
@@ -0,0 +1,13 @@
+Ext.define('FriendlyRent.view.properties.list.item.Content', {
+ extend: 'Ext.List',
+ alias: 'widget.properties.list.item.content',
+ config: {
+ xtype: 'list',
+ itemTpl: '{title} {sender}',
+ data: [
+ { title: 'Beautiful place', sender: 'Griffenfeldsgade 11b' },
+ { title: 'Come see it this weekend', sender: 'Griffenfeldsgade 11b' },
+ { title: '2 rooms available!', sender: 'Griffenfeldsgade 11b' }
+ ]
+ }
+});
View
4 www/app/view/registration/landlord/register/Content.js
@@ -8,10 +8,10 @@ Ext.define('FriendlyRent.view.registration.landlord.register.Content', {
html: 'Register Landlord'
},
{
- html: 'Facebook'
+ xtype: 'registration.login.facebook'
},
{
- html: 'Twitter'
+ xtype: 'registration.login.twitter'
}
]
}
View
11 www/app/view/registration/login/Facebook.js
@@ -0,0 +1,11 @@
+Ext.define('FriendlyRent.view.registration.login.Facebook', {
+ extend: 'Ext.Panel',
+ alias: 'widget.registration.login.facebook',
+ config: {
+ items: [
+ {
+ html: '<div class="fb-login-button"></div>'
+ }
+ ]
+ }
+});
View
13 www/app/view/registration/login/Twitter.js
@@ -0,0 +1,13 @@
+Ext.define('FriendlyRent.view.registration.login.Facebook', {
+ extend: 'Ext.Panel',
+ alias: 'widget.registration.login.facebook',
+ config: {
+ items: [
+ {
+ xtype: 'button'
+ iconCls: 'twitter',
+ title: 'Login'
+ }
+ ]
+ }
+});
View
4 www/app/view/registration/tenant/register/Content.js
@@ -8,10 +8,10 @@ Ext.define('FriendlyRent.view.registration.tenant.register.Content', {
html: 'Register Tenant'
},
{
- html: 'Facebook'
+ xtype: 'registration.login.facebook'
},
{
- html: 'Twitter'
+ xtype: 'registration.login.twitter'
}
]
}
View
0  www/app/view/Main.js → www/app/view/sandbox/Main.js
File renamed without changes
View
37 www/app/view/search/Content.js
@@ -5,11 +5,42 @@ Ext.define('FriendlyRent.view.search.Content', {
layout: 'vbox',
items: [{
{
- html: 'Search criteria'
+ xtype: 'search.criteria.location'
+ name: 'location'
},
{
- html: 'Create agent btn'
- }
+ xtype: 'search.criteria.radius'
+ name: 'radius'
+ },
+ {
+ xtype: 'search.criteria.property_type'
+ name: 'property_type'
+ },
+ {
+ xtype: 'search.criteria.furnishment'
+ name: 'furnishment'
+ },
+ {
+ xtype: 'search.criteria.size'
+ name: 'size'
+ },
+ {
+ xtype: 'search.criteria.rental_cost'
+ name: 'cost'
+ },
+ {
+ xtype: 'search.criteria.rental_period'
+ name: 'period'
+ },
+ {
+ xtype: 'search.criteria.rules'
+ name: 'rules'
+ },
+ {
+ xtype: 'button',
+ name: 'create_agent',
+ label: 'Create agent'
+ }
}]
}
});
View
18 www/app/view/search/agents/Content.js
@@ -1,15 +1,13 @@
Ext.define('FriendlyRent.view.search.agents.Content', {
- extend: 'Ext.Panel',
+ extend: 'Ext.dataview.List',
alias: 'widget.search.agents.content',
config: {
- layout: 'vbar',
- items: [
- {
- html: 'Agents'
- },
- {
- html: 'List of agents'
- }
- ]
+ store: "Agents",
+ itemId:"agentsList",
+ loadingText: "Loading Agents...",
+ emptyText: '<div class="agents-list empty-text">No agents found.</div>',
+ onItemDisclosure: true,
+ grouped: true,
+ itemTpl: '<div class="list-item agent"><span class="criteria">{criteria}</span><span class="trash">Delete</span></div>'
}
});
View
8 www/app/view/search/btn/Agents.js
@@ -0,0 +1,8 @@
+Ext.define("FriendlyRent.view.search.btn.Agents", {
+ extend: 'Ext.Button',
+ alias: "widget.search.btn.agents",
+ config: {
+ iconCls: 'user_fave', // or business
+ iconMask: true
+ }
+});
View
8 www/app/view/search/btn/Favorites.js
@@ -0,0 +1,8 @@
+Ext.define("FriendlyRent.view.search.btn.Favorites", {
+ extend: 'Ext.Button',
+ alias: "widget.search.btn.favorites",
+ config: {
+ iconCls: 'favorite',
+ iconMask: true
+ }
+});
View
8 www/app/view/search/btn/History.js
@@ -0,0 +1,8 @@
+Ext.define("FriendlyRent.view.search.btn.History", {
+ extend: 'Ext.Button',
+ alias: "widget.search.btn.history",
+ config: {
+ iconCls: 'list',
+ iconMask: true
+ }
+});
View
8 www/app/view/search/btn/Property.js
@@ -0,0 +1,8 @@
+Ext.define("FriendlyRent.view.search.btn.Property", {
+ extend: 'Ext.Button',
+ alias: "widget.search.btn.property",
+ config: {
+ iconCls: 'home2',
+ iconMask: true
+ }
+});
View
8 www/app/view/search/btn/Search.js
@@ -0,0 +1,8 @@
+Ext.define("FriendlyRent.view.search.btn.Search", {
+ extend: 'Ext.Button',
+ alias: "widget.search.btn.search",
+ config: {
+ iconCls: 'search',
+ iconMask: true
+ }
+});
View
9 www/app/view/search/criteria/Furnishment.js
@@ -0,0 +1,9 @@
+Ext.define("FriendlyRent.view.search.criteria.Furnishment", {
+ extend: 'Ext.field.SliderText',
+ alias: "widget.search.criteria.furnishment",
+ config: {
+ label: 'Furnished',
+ autoValues: true,
+ valueMap: ['Any', 'None', 'Fully']
+ }
+});
View
7 www/app/view/search/criteria/Location.js
@@ -1,8 +1,7 @@
Ext.define("FriendlyRent.view.search.criteria.Location", {
- extend: 'Ext.field.search',
- alias: "widget.criteria_field.location",
- {
- xtype 'Ext.field.search'
+ extend: 'Ext.field.Search',
+ alias: "widget.search.criteria.location",
+ config: {
name: 'location',
label: 'Location',
required: true
View
46 www/app/view/search/criteria/Page.js
@@ -1,30 +1,38 @@
Ext.define("FriendlyRent.view.search.criteria.Page", {
extend: 'Ext.Panel',
alias: "widget.search_criteria.page",
+ requires: ['Ext.field.Search'],
config: {
layout: {
},
items: [
{
- xtype 'Ext.field.search'
- },
- {
- xtype 'field.criteria.radius'
- },
- {
- xtype 'field.criteria.property_type'
- },
- {
- xtype 'field.criteria.furnished'
- },
- {
- xtype 'field.criteria.rooms'
- },
- {
- xtype 'field.criteria.size'
- },
- {
- xtype 'field.criteria.rental_period'
+ xtype: "fieldset",
+ title: 'Search',
+ instructions: 'Enter your search criteria to find properties',
+ items: [
+ {
+ xtype 'Ext.field.search'
+ },
+ {
+ xtype 'field.criteria.radius'
+ },
+ {
+ xtype 'field.criteria.property_type'
+ },
+ {
+ xtype 'field.criteria.furnished'
+ },
+ {
+ xtype 'field.criteria.rooms'
+ },
+ {
+ xtype 'field.criteria.size'
+ },
+ {
+ xtype 'field.criteria.rental_period'
+ }
+ ]
}
}
}
View
14 www/app/view/search/criteria/PropertyType.js
@@ -1,11 +1,9 @@
Ext.define("FriendlyRent.view.search.criteria.PropertyType", {
- extend: 'Ext.field.search',
- alias: "widget.field.criteria.property_type",
- {
- xtype 'Ext.field.search'
- name: 'location',
- label: 'Location',
- required: true
-
+ extend: 'Ext.field.SliderText',
+ alias: "widget.search.criteria.property_type",
+ config: {
+ label: 'Property type',
+ autoValues: true,
+ valueMap: ['Any', 'Room', 'Apartment', 'House', 'Independent house', 'House boat']
}
});
View
10 www/app/view/search/criteria/Radius.js
@@ -0,0 +1,10 @@
+Ext.define("FriendlyRent.view.search.criteria.Radius", {
+ extend: 'Ext.field.SliderInput',
+ alias: "widget.search.criteria.radius",
+ config: {
+ minValue: 1,
+ value: 5,
+ maxValue: 50,
+ label: 'Radius'
+ }
+});
View
12 www/app/view/search/criteria/RentalCost.js
@@ -0,0 +1,12 @@
+Ext.define("FriendlyRent.view.search.criteria.RentalCost", {
+ extend: 'Ext.field.SliderInput',
+ alias: "widget.search.criteria.rental_cost",
+ config: {
+ minValue: 1500,
+ value: 3000,
+ maxValue: 20000,
+ increment: 500,
+ labelText: 'Rental cost',
+ label: 'Rental cost',
+ }
+});
View
10 www/app/view/search/criteria/RentalPeriod.js
@@ -0,0 +1,10 @@
+Ext.define("FriendlyRent.view.search.criteria.RentalPeriod", {
+ extend: 'Ext.field.SliderInput',
+ alias: "widget.search.criteria.rental_period",
+ config: {
+ label: 'Rental period',
+ autoValues: true,
+ values: [0, 2],
+ valueMap: ['ASAP', '14 days', '1 month', '2 months', '3 months', '6 months', '9 months', '1 year', '18 months', '2 years']
+ }
+});
View
10 www/app/view/search/criteria/Rooms.js
@@ -0,0 +1,10 @@
+Ext.define("FriendlyRent.view.search.criteria.Rooms", {
+ extend: 'Ext.field.SliderInput',
+ alias: "widget.search.criteria.rooms",
+ config: {
+ value: 1,
+ minValue: 1,
+ maxValue: 8,
+ label: 'Rooms'
+ }
+});
View
21 www/app/view/search/criteria/Rules.js
@@ -0,0 +1,21 @@
+Ext.define("FriendlyRent.view.search.criteria.Rules", {
+ extend: 'Ext.Panel',
+ alias: "widget.search.criteria.rules",
+ config: {
+ name: 'location',
+ label: 'Location',
+ required: true
+ },
+ items: [
+ {
+ xtype: 'checkboxfield',
+ name: 'pets',
+ label: 'Pets'
+ },
+ {
+ xtype: 'checkboxfield',
+ name: 'smoking',
+ label: 'Smoking'
+ }
+ ]
+});
View
11 www/app/view/search/criteria/Size.js
@@ -0,0 +1,11 @@
+Ext.define("FriendlyRent.view.search.criteria.Rooms", {
+ extend: 'Ext.field.Slider',
+ alias: "widget.search.criteria.rooms",
+ config: {
+ minValue: 10,
+ maxValue: 300,
+ values: [60, 100], // double slider (2 thumbs)
+ increment: 10,
+ label: 'Size'
+ }
+});
View
18 www/app/view/search/favorites/Content.js
@@ -1,15 +1,13 @@
Ext.define('FriendlyRent.view.search.favorites.Content', {
- extend: 'Ext.Panel',
+ extend: 'Ext.dataview.List',
alias: 'widget.search.favorites.content',
config: {
- layout: 'vbar',
- items: [
- {
- html: 'Favorites'
- },
- {
- html: 'List of favorites'
- }
- ]
+ store: "Favorites",
+ itemId:"favoritesList",
+ loadingText: "Loading Favorites...",
+ emptyText: '<div class="favorites-list empty-text">No favorites found.</div>',
+ onItemDisclosure: true,
+ grouped: true,
+ itemTpl: '<div class="list-item favorite image">{image.src}</div><div class="list-item content">{title}</div>'
}
});
View
22 www/app/view/settings/account/mail/Options.js
@@ -0,0 +1,22 @@
+Ext.define('FriendlyRent.view.settings.account.mail.Options', {
+ extend: 'Ext.Panel',
+ alias: 'widget.settings.account.mail.options',
+ config: {
+ layout: 'vbar',
+ items: [
+ {
+ xtype: 'textfield',
+ label: 'e-mail',
+ name: 'email',
+ maxLength: 40,
+ placeHolder: 'Enter your e-mail'
+ }
+ {
+ html: 'Erase mail after 30 days'
+ },
+ {
+ html: 'Unsubscribe from Friendlyrent'
+ }
+ ]
+ }
+});
View
27 www/app/view/settings/currency/List.js
@@ -0,0 +1,27 @@
+Ext.define('FriendlyRent.view.settings.currency.List', {
+ extend: 'Ext.Panel',
+ alias: 'widget.settings.currency.list',
+ config: {
+ layout: 'vbar',
+ items: [
+ {
+ html: 'Euro €'
+ },
+ {
+ html: 'Pound £'
+ },
+ {
+ html: 'Dollar $'
+ },
+ {
+ html: 'Danish Kroner (DKK)'
+ },
+ {
+ html: 'Swedish Kroner (SEK)'
+ },
+ {
+ html: 'Norwegian Kroner (NOK)'
+ }
+ ]
+ }
+});
View
15 www/app/view/settings/language/List.js
@@ -0,0 +1,15 @@
+Ext.define('FriendlyRent.view.settings.language.List', {
+ extend: 'Ext.Panel',
+ alias: 'widget.settings.language.list',
+ config: {
+ layout: 'vbar',
+ items: [
+ {
+ html: 'English'
+ },
+ {
+ html: 'Danish'
+ }
+ ]
+ }
+});
View
16 www/app/view/settings/map/Options.js
@@ -0,0 +1,16 @@
+Ext.define('FriendlyRent.view.settings.map.Options', {
+ extend: 'Ext.Panel',
+ alias: 'widget.settings.map.options',
+ config: {
+ layout: 'vbar',
+ items: [
+ {
+ html: 'Allow sharing my location'
+ },
+ // http://www.daftlogic.com/sandbox-google-maps-remember-last-location.htm
+ {
+ html: 'Remember my last map position'
+ }
+ ]
+ }
+});
View
18 www/app/view/settings/search/Page.js
@@ -0,0 +1,18 @@
+Ext.define('FriendlyRent.view.settings.Page', {
+ extend: 'Ext.Panel',
+ alias: 'widget.settings.page',
+ config: {
+ layout: 'vbox'
+ },
+ items: [
+ {
+ xtype 'settings.topbar'
+ },
+ {
+ xtype 'search.content'
+ },
+ {
+ xtype 'settings.navbar'
+ }
+ }
+});
View
7 www/app/view/start/Image.js
@@ -0,0 +1,7 @@
+Ext.define('FriendlyRent.view.start.Image', {
+ extend: 'Ext.Img',
+ xtype: 'start.img',
+ config: {
+ src: 'http://src.sencha.io/http://friendlyrent.dk/resources/images/FriendlyRentTrans.png'
+ }
+});
View
11 www/app/view/start/Languages.js
@@ -0,0 +1,11 @@
+Ext.define('FriendlyRent.view.start.Image', {
+ extend: 'Ext.Panel',
+ xtype: 'start.img',
+ config: {
+ items: [
+ {
+ html: '<div class="f64 dk"></div><div class="f64 gb"></div>'
+ }
+ ]
+ }
+});
View
15 www/app/view/start/Page.js
@@ -0,0 +1,15 @@
+Ext.define('FriendlyRent.view.start.Page', {
+ extend: 'Ext.Panel',
+ alias: 'widget.start.page',
+ config: {
+ layout: 'vbar',
+ items: [
+ {
+ xtype: 'start.image'
+ },
+ {
+ xtype: 'start.languages'
+ }
+ ]
+ }
+});
View
11 www/app/view/util/FloatingTooltip.js
@@ -0,0 +1,11 @@
+Ext.define("FriendlyRent.view.util.FloatingTooltip", {
+ extend: 'Ext.Panel',
+ alias: "widget.field.FloatingTooltip",
+ config: {
+ floating: true,
+ width: 50,
+ height: 30,
+ styleHtmlContent: true,
+ style: "background-color: #FFF;"
+ }
+});
View
17 www/config.rb
@@ -1,17 +0,0 @@
-# http://www.sencha.com/blog/an-introduction-to-theming-sencha-touch
-
-# Delineate the directory for our SASS/SCSS files (this directory)
-sass_path = File.dirname(__FILE__)
-
-# Delineate the CSS directory (under resources/css in this demo)
-css_path = File.join(sass_path, "..", "css")
-
-# Delinate the images directory
-images_dir = File.join(sass_path, "..", "img")
-
-# Load the sencha-touch framework
-load File.join(sass_path, '..', '..', '..', '..', 'resources', 'themes')
-
-# Specify the output style/environment
-output_style = :compressed
-environment = :production
View
7 www/docs/Command line.md
@@ -0,0 +1,7 @@
+# Compile SASS
+
+Run the command “compass compile” in the Terminal from within the resources/sass directory.
+
+# Run Sinatra server
+
+$ rake serve:development
View
0  www/docs/ccustomize_sencha.md → www/docs/Customize_sencha.md
File renamed without changes
View
15 www/index.html
@@ -2,8 +2,7 @@
<html manifest="" lang="en-US">
<head>
<meta charset="UTF-8">
- <title>FriendlyRent</title>
- <link rel="stylesheet" href="resources/css/notes.css">
+ <title>FriendlyRent</title>
<style type="text/css">
/**
* Example of an initial loading indicator.
@@ -51,6 +50,18 @@
}
</style>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
+
+ <!-- resources -->
+ <script type="text/javascript" src="resources/javascript/i18n.js">
+ </script>
+ <script type="text/javascript" src="resources/javascript/locale_da.js">
+ </script>
+ <!-- plugins -->
+ <script type="text/javascript" src="lib/plugins/SliderFieldInput.js">
+ </script>
+ <script type="text/javascript" src="lib/plugins/SliderFieldText.js">
+ </script>
+ <!-- phonegap -->
<script id="cordova" type="text/javascript" src="cordova-1.8.0.js"></script>
<!-- The line below must be kept intact for Sencha Command to build your application -->
<script id="microloader" type="text/javascript" src="sdk/microloader/development.js"></script>
View
163 www/lib/plugins/SliderFieldInput.js
@@ -0,0 +1,163 @@
+// https://github.com/kristianmandrup/Sencha-Touch-2-SliderExtended
+// http://www.geektantra.com/2012/04/sencha-touch-2-slider-field-extended-component/
+// http://www.devguy.org/2011/05/sencha-touch-slider-with-tooltip.html
+// http://www.codeproject.com/Articles/245717/Create-a-Plugin-to-Sencha-Touch-Ext-form-Slider-Cl
+
+Ext.define('Ext.field.SliderInput', {
+ extend : 'Ext.field.Field',
+ xtype : 'sliderfieldinput',
+ requires: [
+ 'Ext.slider.Slider'
+ ],
+ alternateClassName: 'Ext.form.SliderInput',
+
+ config: {
+ cls: Ext.baseCSSPrefix + 'slider-field-input',
+ tabIndex: -1,
+ helperPosition: 'right',
+ valueMapper: function(value) {
+ if (self.config.valueMap) {
+ self.config.valueMap[value];
+ } else {
+ value;
+ }
+ }
+ },
+
+ proxyConfig: {
+ value: 0,
+ minValue: 0,
+ maxValue: 100,
+ increment: 1
+ },
+
+ constructor: function(config) {
+ config = config || {};
+
+ if (config.hasOwnProperty('values')) {
+ config.value = config.values;
+ }
+
+ if (config.hasOwnProperty('valueMap')) {
+ if (config.autoValues == true) {
+ config.value = config.defaultValue || 0;
+ config.minValue = 0;
+ config.maxValue = config.valueMap.size -1;
+ config.increment = 1;
+ }
+ }
+
+ this.callParent([config]);
+ },
+
+ initialize: function() {
+ this.callParent();
+
+ this.getComponent().on({
+ scope: this,
+ change: 'onSliderChange',
+ dragstart: 'onSliderDragStart',
+ drag: 'onSliderDrag',
+ dragend: 'onSliderDragEnd'
+ });
+ },
+
+ getElementConfig: function() {
+ var self = this;
+ var originalConfig = self.callParent();
+
+ originalConfig.children[1].children = [{
+ reference: 'helper',
+ tag: 'div',
+ cls: Ext.baseCSSPrefix + 'slider-helper',
+ children: [
+ {
+ reference: 'helperInput',
+ tag: 'input',
+ type: 'number',
+ cls: Ext.baseCSSPrefix + 'slider-helper-input'
+ }
+ ]
+ }];
+
+ return originalConfig;
+ },
+
+ setHelperValue: function(value) {
+ var valueMapper = self.config.valueMapper;
+ var value = valueMapper ? valueMapper(value) : value;
+ this.helperInput.dom.value = value;
+ },
+
+ // @private
+ applyComponent: function(config) {
+ var self = this;
+ self.helper.setStyle('float', self.config.helperPosition);
+ var changeValue = function(e) {
+ var keycode = e.which || window.event.keyCode;
+ if( [8, 9, 13, 37, 38, 39, 40, 46].indexOf(Number(keycode)) !== -1 ) return true;
+ var helperInputValue = Number(self.helperInput.getValue());
+ if(helperInputValue < self.config.minValue || isNaN(helperInputValue))
+ helperInputValue = self.config.minValue;
+ else if(helperInputValue > self.config.maxValue)
+ helperInputValue = self.config.maxValue;
+ this.value = helperInputValue;
+ self.setValue(helperInputValue);
+ };
+ self.helperInput.dom.onkeydown = function(e) {
+ var keycode = e.which || window.event.keyCode;
+ if( [8, 9, 13, 37, 38, 39, 40, 46, 190].indexOf(Number(keycode)) !== -1 ) return true;
+ if( keycode > 57 || keycode < 48 ) return false;
+ };
+ self.helperInput.dom.onchange = changeValue;
+ self.helperInput.dom.onclick = changeValue;
+ self.helperInput.dom.onkeyup = changeValue;
+ self.setHelperValue(self.config.value);
+ return Ext.factory(config, Ext.slider.Slider);
+ },
+
+ onSliderChange: function(me, thumb, newValue, oldValue) {
+ this.setHelperValue(newValue);
+ this.fireEvent('change', this, thumb, newValue, oldValue);
+ },
+
+ onSliderDragStart: function(me, thumb, newValue, oldValue) {
+ this.fireEvent('dragstart', this, thumb, newValue, oldValue);
+ },
+
+ onSliderDrag: function(me, thumb, newValue, oldValue) {
+ this.setHelperValue(newValue);
+ this.fireEvent('drag', this, thumb, newValue, oldValue);
+ },
+
+ onSliderDragEnd: function(me, thumb, newValue, oldValue) {
+ this.fireEvent('dragend', this, thumb, newValue, oldValue);
+ },
+
+ /**
+ * Convience method. Calls {@link #setValue}
+ */
+ setValues: function(value) {
+ this.setValue(value);
+ },
+
+ /**
+ * Convience method. Calls {@link #getValue}
+ */
+ getValues: function() {
+ return this.getValue();
+ },
+
+ reset: function() {
+ var config = this.config,
+ initialValue = (this.config.hasOwnProperty('values')) ? config.values : config.value;
+
+ this.setValue(initialValue);
+ },
+
+ doSetDisabled: function(disabled) {
+ this.callParent(arguments);
+
+ this.getComponent().setDisabled(disabled);
+ }
+});
View
138 www/lib/plugins/SliderFieldText.js
@@ -0,0 +1,138 @@
+Ext.define('Ext.field.SliderText', {
+ extend : 'Ext.field.Field',
+ xtype : 'sliderfieldtext',
+ requires: [
+ 'Ext.slider.Slider'
+ ],
+ alternateClassName: 'Ext.form.SliderText',
+
+ config: {
+ cls: Ext.baseCSSPrefix + 'slider-field-text',
+ tabIndex: -1,
+ helperPosition: 'right',
+ valueMapper: function(value) {
+ if (self.config.valueMap) {
+ self.config.valueMap[value];
+ } else {
+ value;
+ }
+ }
+ },
+
+ proxyConfig: {
+ value: 0,
+ minValue: 0,
+ maxValue: 100,
+ increment: 1
+ },
+
+ constructor: function(config) {
+ config = config || {};
+
+ if (config.hasOwnProperty('values')) {
+ config.value = config.values;
+ }
+
+ if (config.hasOwnProperty('valueMap')) {
+ if (config.autoValues == true) {
+ config.value = config.defaultValue || 0;
+ config.minValue = 0;
+ config.maxValue = config.valueMap.size -1;
+ config.increment = 1;
+ }
+ }
+
+ this.callParent([config]);
+ },
+
+ initialize: function() {
+ this.callParent();
+
+ this.getComponent().on({
+ scope: this,
+ change: 'onSliderChange',
+ dragstart: 'onSliderDragStart',
+ drag: 'onSliderDrag',
+ dragend: 'onSliderDragEnd'
+ });
+ },
+
+ getElementConfig: function() {
+ var self = this;
+ var originalConfig = self.callParent();
+
+ originalConfig.children[1].children = [{
+ reference: 'helper',
+ tag: 'div',
+ cls: Ext.baseCSSPrefix + 'slider-helper',
+ children: [
+ {
+ reference: 'helperInput',
+ tag: 'div',
+ cls: Ext.baseCSSPrefix + 'slider-helper-input'
+ }
+ ]
+ }];
+
+ return originalConfig;
+ },
+
+ setHelperValue: function(value) {
+ var valueMapper = self.config.valueMapper;
+ var value = valueMapper ? valueMapper(value) : value;
+ this.helperInput.dom.text = value;
+ },
+
+ // @private
+ applyComponent: function(config) {
+ var self = this;
+ self.helper.setStyle('float', self.config.helperPosition);
+ self.setHelperValue(self.config.value);
+ return Ext.factory(config, Ext.slider.Slider);
+ },
+
+ onSliderChange: function(me, thumb, newValue, oldValue) {
+ this.setHelperValue(newValue);
+ this.fireEvent('change', this, thumb, newValue, oldValue);
+ },
+
+ onSliderDragStart: function(me, thumb, newValue, oldValue) {
+ this.fireEvent('dragstart', this, thumb, newValue, oldValue);
+ },
+
+ onSliderDrag: function(me, thumb, newValue, oldValue) {
+ this.setHelperValue(newValue);
+ this.fireEvent('drag', this, thumb, newValue, oldValue);
+ },
+
+ onSliderDragEnd: function(me, thumb, newValue, oldValue) {
+ this.fireEvent('dragend', this, thumb, newValue, oldValue);
+ },
+
+ /**
+ * Convience method. Calls {@link #setValue}
+ */
+ setValues: function(value) {
+ this.setValue(value);
+ },
+
+ /**
+ * Convience method. Calls {@link #getValue}
+ */
+ getValues: function() {
+ return this.getValue();
+ },
+
+ reset: function() {
+ var config = this.config,
+ initialValue = (this.config.hasOwnProperty('values')) ? config.values : config.value;
+
+ this.setValue(initialValue);
+ },
+
+ doSetDisabled: function(disabled) {
+ this.callParent(arguments);
+
+ this.getComponent().setDisabled(disabled);
+ }
+});
View
9,695 www/resources/css/app.css
1 addition, 9,694 deletions not shown
View
BIN  www/resources/images/FriendlyRentTrans.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  www/resources/images/flags64.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  www/resources/images/flags64_semi.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
531 www/resources/javascript/i18n.js
<
@@ -0,0 +1,531 @@
+// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
+if (!Array.prototype.indexOf) {
+ Array.prototype.indexOf = function(searchElement /*, fromIndex */) {
+ "use strict";
+
+ if (this === void 0 || this === null) {
+ throw new TypeError();
+ }
+
+ var t = Object(this);
+ var len = t.length >>> 0;
+
+ if (len === 0) {
+ return -1;
+ }
+
+ var n = 0;
+ if (arguments.length > 0) {
+ n = Number(arguments[1]);
+ if (n !== n) { // shortcut for verifying if it's NaN
+ n = 0;
+ } else if (n !== 0 && n !== (Infinity) && n !== -(Infinity)) {
+ n = (n > 0 || -1) * Math.floor(Math.abs(n));
+ }
+ }
+
+ if (n >= len) {
+ return -1;
+ }
+
+ var k = n >= 0
+ ? n
+ : Math.max(len - Math.abs(n), 0);
+
+ for (; k < len; k++) {
+ if (k in t && t[k] === searchElement) {
+ return k;
+ }
+ }
+
+ return -1;
+ };
+}
+
+// Instantiate the object
+var I18n = I18n || {};
+
+// Set default locale to english
+I18n.defaultLocale = "en";
+
+// Set default handling of translation fallbacks to false
+I18n.fallbacks = false;
+
+// Set default separator
+I18n.defaultSeparator = ".";
+
+// Set current locale to null
+I18n.locale = null;
+
+// Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`.
+I18n.PLACEHOLDER = /(?:\{\{|%\{)(.*?)(?:\}\}?)/gm;
+
+I18n.fallbackRules = {
+};
+
+I18n.pluralizationRules = {
+ en: function (n) {
+ return n == 0 ? ["zero", "none", "other"] : n == 1 ? "one" : "other";
+ }
+};
+
+I18n.getFallbacks = function(locale) {
+ if (locale === I18n.defaultLocale) {
+ return [];
+ } else if (!I18n.fallbackRules[locale]) {
+ var rules = []
+ , components = locale.split("-");
+
+ for (var l = 1; l < components.length; l++) {
+ rules.push(components.slice(0, l).join("-"));
+ }
+
+ rules.push(I18n.defaultLocale);
+
+ I18n.fallbackRules[locale] = rules;
+ }
+
+ return I18n.fallbackRules[locale];
+}
+
+I18n.isValidNode = function(obj, node, undefined) {
+ return obj[node] !== null && obj[node] !== undefined;
+};
+
+I18n.lookup = function(scope, options) {
+ var options = options || {}
+ , lookupInitialScope = scope
+ , translations = this.prepareOptions(I18n.translations)
+ , locale = options.locale || I18n.currentLocale()
+ , messages = translations[locale] || {}
+ , options = this.prepareOptions(options)
+ , currentScope
+ ;
+
+ if (typeof(scope) == "object") {
+ scope = scope.join(this.defaultSeparator);
+ }
+
+ if (options.scope) {
+ scope = options.scope.toString() + this.defaultSeparator + scope;
+ }
+
+ scope = scope.split(this.defaultSeparator);
+
+ while (messages && scope.length > 0) {
+ currentScope = scope.shift();
+ messages = messages[currentScope];
+ }
+
+ if (!messages) {
+ if (I18n.fallbacks) {
+ var fallbacks = this.getFallbacks(locale);
+ for (var fallback = 0; fallback < fallbacks.length; fallbacks++) {
+ messages = I18n.lookup(lookupInitialScope, this.prepareOptions({locale: fallbacks[fallback]}, options));
+ if (messages) {
+ break;
+ }
+ }
+ }
+
+ if (!messages && this.isValidNode(options, "defaultValue")) {
+ messages = options.defaultValue;
+ }
+ }
+
+ return messages;
+};
+
+// Merge serveral hash options, checking if value is set before
+// overwriting any value. The precedence is from left to right.
+//
+// I18n.prepareOptions({name: "John Doe"}, {name: "Mary Doe", role: "user"});
+// #=> {name: "John Doe", role: "user"}
+//
+I18n.prepareOptions = function() {
+ var options = {}
+ , opts
+ , count = arguments.length
+ ;
+
+ for (var i = 0; i < count; i++) {
+ opts = arguments[i];
+
+ if (!opts) {
+ continue;
+ }
+
+ for (var key in opts) {
+ if (!this.isValidNode(options, key)) {
+ options[key] = opts[key];
+ }
+ }
+ }
+
+ return options;
+};
+
+I18n.interpolate = function(message, options) {
+ options = this.prepareOptions(options);
+ var matches = message.match(this.PLACEHOLDER)
+ , placeholder
+ , value
+ , name
+ ;
+
+ if (!matches) {
+ return message;
+ }
+
+ for (var i = 0; placeholder = matches[i]; i++) {
+ name = placeholder.replace(this.PLACEHOLDER, "$1");
+
+ value = options[name];
+
+ if (!this.isValidNode(options, name)) {
+ value = "[missing " + placeholder + " value]";
+ }
+
+ regex = new RegExp(placeholder.replace(/\{/gm, "\\{").replace(/\}/gm, "\\}"));
+ message = message.replace(regex, value);
+ }
+
+ return message;
+};
+
+I18n.translate = function(scope, options) {
+ options = this.prepareOptions(options);
+ var translation = this.lookup(scope, options);
+
+ try {
+ if (typeof(translation) == "object") {
+ if (typeof(options.count) == "number") {
+ return this.pluralize(options.count, scope, options);
+ } else {
+ return translation;
+ }
+ } else {
+ return this.interpolate(translation, options);
+ }
+ } catch(err) {
+ return this.missingTranslation(scope);
+ }
+};
+
+I18n.localize = function(scope, value) {
+ switch (scope) {
+ case "currency":
+ return this.toCurrency(value);
+ case "number":
+ scope = this.lookup("number.format");
+ return this.toNumber(value, scope);
+ case "percentage":
+ return this.toPercentage(value);
+ default:
+ if (scope.match(/^(date|time)/)) {
+ return this.toTime(scope, value);
+ } else {
+ return value.toString();
+ }
+ }
+};
+
+I18n.parseDate = function(date) {
+ var matches, convertedDate;
+
+ // we have a date, so just return it.
+ if (typeof(date) == "object") {
+ return date;
+ };
+
+ // it matches the following formats:
+ // yyyy-mm-dd
+ // yyyy-mm-dd[ T]hh:mm::ss
+ // yyyy-mm-dd[ T]hh:mm::ss
+ // yyyy-mm-dd[ T]hh:mm::ssZ
+ // yyyy-mm-dd[ T]hh:mm::ss+0000
+ //
+ matches = date.toString().match(/(\d{4})-(\d{2})-(\d{2})(?:[ T](\d{2}):(\d{2}):(\d{2}))?(Z|\+0000)?/);
+
+ if (matches) {
+ for (var i = 1; i <= 6; i++) {
+ matches[i] = parseInt(matches[i], 10) || 0;
+ }
+
+ // month starts on 0
+ matches[2] -= 1;
+
+ if (matches[7]) {
+ convertedDate = new Date(Date.UTC(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6]));
+ } else {
+ convertedDate = new Date(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6]);
+ }
+ } else if (typeof(date) == "number") {
+ // UNIX timestamp
+ convertedDate = new Date();
+ convertedDate.setTime(date);
+ } else if (date.match(/\d+ \d+:\d+:\d+ [+-]\d+ \d+/)) {
+ // a valid javascript format with timezone info
+ convertedDate = new Date();
+ convertedDate.setTime(Date.parse(date))
+ } else {
+ // an arbitrary javascript string
+ convertedDate = new Date();
+ convertedDate.setTime(Date.parse(date));
+ }
+
+ return convertedDate;