plan_b 0.0.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +43 -0
- data/Rakefile +13 -0
- data/app/assets/images/plan_b/plan_b.png +0 -0
- data/app/assets/javascripts/plan_b/application.js +9 -0
- data/app/assets/javascripts/plan_b/itineraries/controllers.js +67 -0
- data/app/assets/javascripts/plan_b/itineraries/services.js +4 -0
- data/app/assets/javascripts/plan_b/plan_b.js +53 -0
- data/app/assets/stylesheets/plan_b/application.css.scss +2 -0
- data/app/assets/stylesheets/plan_b/foundation_and_overrides.scss +1015 -0
- data/app/assets/templates/plan_b/itineraries/edit.html.erb +87 -0
- data/app/assets/templates/plan_b/itineraries/new.html.erb +22 -0
- data/app/controllers/plan_b/angular_controller.rb +16 -0
- data/app/controllers/plan_b/application_controller.rb +5 -0
- data/app/controllers/plan_b/hiking_profiles_controller.rb +59 -0
- data/app/controllers/plan_b/itineraries_controller.rb +46 -0
- data/app/helpers/plan_b/application_helper.rb +4 -0
- data/app/helpers/plan_b/itineraries_helper.rb +4 -0
- data/app/models/plan_b/hiking_template.rb +7 -0
- data/app/models/plan_b/itinerary.rb +15 -0
- data/app/models/plan_b/itinerary_template.rb +8 -0
- data/app/models/plan_b/template_creator.rb +25 -0
- data/app/views/plan_b/angular/index.html.haml +38 -0
- data/config/initializers/haml.rb +1 -0
- data/config/initializers/wrap_parameters.rb +14 -0
- data/config/locales/plan_b.en.yml +31 -0
- data/config/routes.rb +20 -0
- data/db/migrate/20130408193857_create_plan_b_itineraries.rb +16 -0
- data/db/migrate/20130408193858_create_plan_b_itinerary_templates.rb +10 -0
- data/db/migrate/20130408193859_create_plan_b_hiking_templates.rb +10 -0
- data/lib/plan_b/config.rb +10 -0
- data/lib/plan_b/engine.rb +12 -0
- data/lib/plan_b/version.rb +3 -0
- data/lib/plan_b.rb +5 -0
- metadata +161 -0
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# Plan B
|
2
|
+
|
3
|
+
Plan B is a Rails engine that offers flexible itinerary planning.
|
4
|
+
|
5
|
+
## Why?
|
6
|
+
|
7
|
+
I'm a big planner. When I go on a trip, I do a thorough amount of research to ensure I don't return from a trip and say, "man, I wish I had seen that". Unfortunately, the trip planners out there try to throw a one size fits all package that doesn't provide the granular detail that I require when say: planning a 3 day backpacking trip. In the end, I usually end up resorting to an unstructured Google spreadsheet, but then I can't go back and perform analytics since I have little control over the data. Hence, Plan B.
|
8
|
+
|
9
|
+
Totally a work in progress. Don't use this.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
In your `Gemfile`, add the following:
|
14
|
+
|
15
|
+
gem 'plan_b'
|
16
|
+
|
17
|
+
Run:
|
18
|
+
|
19
|
+
bundle install
|
20
|
+
|
21
|
+
In `config/routes.rb`:
|
22
|
+
|
23
|
+
mount PlanB::Engine, at: "/plan_b"
|
24
|
+
|
25
|
+
Finally, install and run the migrations:
|
26
|
+
|
27
|
+
rake plan_b:install:migrations
|
28
|
+
rake db:migrate SCOPE=plan_b
|
29
|
+
|
30
|
+
## Bring your own authentication
|
31
|
+
|
32
|
+
in `config/initializer/plan_b.rb`
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
PlanB::Config.authenticate_with do |config|
|
36
|
+
redirect_to main_app.root_path unless current_user
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
## TODO
|
41
|
+
|
42
|
+
How do you run konacha tests from a rails engine:
|
43
|
+
https://github.com/jfirebaugh/konacha/issues/46
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
2
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
3
|
+
|
4
|
+
Dir['lib/tasks/*.rake'].each { |rake| load rake }
|
5
|
+
|
6
|
+
require 'bundler'
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
|
9
|
+
require 'rspec/core/rake_task'
|
10
|
+
RSpec::Core::RakeTask.new(:spec)
|
11
|
+
|
12
|
+
task :test => :spec
|
13
|
+
task :default => :spec
|
Binary file
|
@@ -0,0 +1,67 @@
|
|
1
|
+
angular.module('plan-b.itineraries.controllers', ['plan-b.itineraries.services'])
|
2
|
+
.controller('ItinerariesCtrl', function($scope, Itinerary) {
|
3
|
+
|
4
|
+
$scope.loadItineraries = function() {
|
5
|
+
Itinerary.query(function(itineraries) {
|
6
|
+
$scope.itineraries = itineraries;
|
7
|
+
}, function(err) {
|
8
|
+
console.log("Failed to retrieve itineraries");
|
9
|
+
});
|
10
|
+
};
|
11
|
+
|
12
|
+
$scope.$on('itineraryUpdate', function() {
|
13
|
+
$scope.loadItineraries();
|
14
|
+
});
|
15
|
+
|
16
|
+
$scope.loadItineraries();
|
17
|
+
})
|
18
|
+
.controller('NewItineraryCtrl', function($rootScope, $location, $scope, itinerary, Itinerary) {
|
19
|
+
$scope.itinerary = itinerary;
|
20
|
+
|
21
|
+
$scope.save = function() {
|
22
|
+
$scope.resetFlash();
|
23
|
+
Itinerary.save({itinerary: $scope.itinerary}, function(itinerary) {
|
24
|
+
$rootScope.$broadcast('itineraryUpdate');
|
25
|
+
$location.path($rootScope.mountPath + '/itineraries/' + itinerary.id + '/edit');
|
26
|
+
}, function(response) {
|
27
|
+
angular.forEach(response.data.errors, function(k,v) {
|
28
|
+
$scope.flash.error += v + " " + k;
|
29
|
+
});
|
30
|
+
});
|
31
|
+
};
|
32
|
+
|
33
|
+
$scope.resetFlash = function() {
|
34
|
+
$scope.flash = { error: '', success: ''};
|
35
|
+
};
|
36
|
+
})
|
37
|
+
.controller('EditItineraryCtrl', function($rootScope, $location, $scope, itinerary, Itinerary) {
|
38
|
+
$scope.itinerary = itinerary;
|
39
|
+
|
40
|
+
$scope.save = function() {
|
41
|
+
$scope.resetFlash();
|
42
|
+
$scope.itinerary.$update(function() {
|
43
|
+
$rootScope.$broadcast('itineraryUpdate');
|
44
|
+
$scope.flash.success = 'Updated!';
|
45
|
+
}, function(response) {
|
46
|
+
angular.forEach(response.data.errors, function(k,v) {
|
47
|
+
$scope.flash.error += v + " " + k;
|
48
|
+
});
|
49
|
+
});
|
50
|
+
};
|
51
|
+
|
52
|
+
$scope.resetFlash = function() {
|
53
|
+
$scope.flash = { error: '', success: ''};
|
54
|
+
};
|
55
|
+
|
56
|
+
$scope.addTemplate = function(type) {
|
57
|
+
if (type === 'hiking') {
|
58
|
+
$scope.itinerary.hiking_templates.push({distance: 0});
|
59
|
+
}
|
60
|
+
};
|
61
|
+
|
62
|
+
$scope.removeTemplate = function(index) {
|
63
|
+
$scope.itinerary.hiking_templates.splice(index, 1);
|
64
|
+
};
|
65
|
+
|
66
|
+
$('.date').fdatepicker();
|
67
|
+
});
|
@@ -0,0 +1,53 @@
|
|
1
|
+
angular.module('plan-b', ['plan-b.itineraries.controllers', 'plan-b.itineraries.services']);
|
2
|
+
angular.module('plan-b').config(function ($routeProvider, $locationProvider) {
|
3
|
+
var mountPath = $('html').attr('mount-path');
|
4
|
+
|
5
|
+
$routeProvider.when(mountPath + '/itineraries/new', {
|
6
|
+
templateUrl: '/assets' + mountPath + '/itineraries/new.html'
|
7
|
+
, controller: 'NewItineraryCtrl'
|
8
|
+
, resolve: {
|
9
|
+
itinerary: function(Itinerary) {
|
10
|
+
return new Itinerary();
|
11
|
+
}
|
12
|
+
}
|
13
|
+
});
|
14
|
+
|
15
|
+
$routeProvider.when(mountPath + '/itineraries/:id/edit', {
|
16
|
+
templateUrl: '/assets' + mountPath + '/itineraries/edit.html'
|
17
|
+
, controller: 'EditItineraryCtrl'
|
18
|
+
, resolve: {
|
19
|
+
itinerary: function($q, $route, Itinerary) {
|
20
|
+
var deferred = $q.defer()
|
21
|
+
, onSuccess = function(result) { deferred.resolve(result); }
|
22
|
+
, onError = function(result) { deferred.reject(result); };
|
23
|
+
Itinerary.get({id: $route.current.params.id }, onSuccess, onError);
|
24
|
+
return deferred.promise;
|
25
|
+
}
|
26
|
+
}
|
27
|
+
});
|
28
|
+
|
29
|
+
$locationProvider.html5Mode(true);
|
30
|
+
})
|
31
|
+
.config(["$httpProvider", function(provider) {
|
32
|
+
provider.defaults.headers.common['X-CSRF-Token'] = $('meta[name=csrf-token]').attr('content');
|
33
|
+
}])
|
34
|
+
.run(function($rootScope, $location) {
|
35
|
+
$rootScope.mountPath = $('html').attr('mount-path');
|
36
|
+
|
37
|
+
$rootScope.$on("$routeChangeStart", function (event, next, current) {
|
38
|
+
$rootScope.alertMessage = "Loading...";
|
39
|
+
$rootScope.alertType = "secondary";
|
40
|
+
$rootScope.alertShow = true;
|
41
|
+
});
|
42
|
+
$rootScope.$on("$routeChangeError", function (event, next, current) {
|
43
|
+
$rootScope.alertMessage = "There was a problem :(";
|
44
|
+
$rootScope.alertType = "alert";
|
45
|
+
$rootScope.alertShow = true;
|
46
|
+
});
|
47
|
+
$rootScope.$on("$routeChangeSuccess", function (event, next, current) {
|
48
|
+
$rootScope.alertMessage = "";
|
49
|
+
$rootScope.alertType = "";
|
50
|
+
$rootScope.alertShow = false;
|
51
|
+
});
|
52
|
+
|
53
|
+
});
|