odania_profile 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +25 -0
- data/app/assets/javascripts/odania_profile/application.js +13 -0
- data/app/assets/javascripts/odania_profile/controllers/profile/edit_profile_controller.js +79 -0
- data/app/assets/javascripts/odania_profile/controllers/profile/profile_controller.js +11 -0
- data/app/assets/javascripts/odania_profile/resoures/profile_resource.js +5 -0
- data/app/assets/stylesheets/odania_profile/application.css +15 -0
- data/app/assets/stylesheets/odania_profile/protected/profiles.scss +3 -0
- data/app/controllers/odania_profile/application_controller.rb +4 -0
- data/app/controllers/odania_profile/profiles_controller.rb +10 -0
- data/app/controllers/protected/api/odania_profile/profiles_controller.rb +48 -0
- data/app/helpers/odania_profile/application_helper.rb +4 -0
- data/app/models/odania_profile.rb +5 -0
- data/app/models/odania_profile/profile.rb +24 -0
- data/app/models/odania_profile/skill.rb +3 -0
- data/app/views/layouts/odania_profile/application.html.erb +14 -0
- data/app/views/odania_profile/profiles/index.html.erb +7 -0
- data/app/views/odania_profile/profiles/show.html.erb +56 -0
- data/app/views/protected/api/odania_profile/profiles/_inital_data.json.jbuilder +1 -0
- data/app/views/protected/api/odania_profile/profiles/_show.json.jbuilder +13 -0
- data/app/views/protected/api/odania_profile/profiles/index.json.jbuilder +7 -0
- data/app/views/protected/api/odania_profile/skills/_show.json.jbuilder +3 -0
- data/app/views/protected/odania_profile/profiles/_choose_profile.html.erb +5 -0
- data/app/views/protected/odania_profile/profiles/_choose_profiles.html.erb +0 -0
- data/app/views/protected/template/templates/odania_profile/profile/_edit.html.erb +43 -0
- data/app/views/protected/template/templates/odania_profile/profile/_index.html.erb +43 -0
- data/app/views/protected/template/templates/odania_profile/profile/_tab_description.html.erb +7 -0
- data/app/views/protected/template/templates/odania_profile/profile/_tab_general.html.erb +47 -0
- data/app/views/protected/template/templates/odania_profile/profile/_tab_skills.html.erb +24 -0
- data/app/views/protected/template/templates/odania_profile/profile/_tab_social.html.erb +39 -0
- data/config/locales/de.yml +7 -0
- data/config/locales/en.yml +7 -0
- data/config/routes.rb +24 -0
- data/db/migrate/20150323144052_create_odania_profile_profiles.rb +22 -0
- data/db/migrate/20150323144146_create_odania_profile_skills.rb +11 -0
- data/lib/odania_profile.rb +9 -0
- data/lib/odania_profile/engine.rb +30 -0
- data/lib/odania_profile/engine_target_type.rb +22 -0
- data/lib/odania_profile/version.rb +3 -0
- data/lib/tasks/odania_profile_tasks.rake +4 -0
- metadata +127 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b55b6fb11aeb532405e9f9467ee20108cde02d12
|
4
|
+
data.tar.gz: 1c3d2cc53606edccfb79a0c91f4f4012e89b1ea8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3afef46d874c0934d49d5a1914d590c3fd9e893edf460f820b3ce7b7094d72d1b619ebc556c484e14dd2d1ddbc8ee3bd6c8fa4388e9ce2cdb1a768e7a1e128a0
|
7
|
+
data.tar.gz: 91a4653032d76d2dd984b308711b721a353ad46e68cb84d3b8204a530b47fcdc228675a6530f1e3edcd7f2c1cf73196232f9ec532b2f458949c9850436d12fdc
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015 Mike Petersen
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'OdaniaProfile'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.rdoc')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
Bundler::GemHelper.install_tasks
|
25
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,79 @@
|
|
1
|
+
app.controller('OdaniaProfileEditProfileController', ['$location', '$scope', '$rootScope', 'OdaniaProfileProfileResource', '$http', function ($location, $scope, $rootScope, OdaniaProfileProfileResource, $http) {
|
2
|
+
console.log("controller :: OdaniaProfileEditProfileController");
|
3
|
+
|
4
|
+
function loadProfile() {
|
5
|
+
OdaniaProfileProfileResource.get().$promise.then(function (data) {
|
6
|
+
$scope.profile = data.profile;
|
7
|
+
$scope.profile.skillSelection = prepareSkillData(data.profile.skills);
|
8
|
+
$scope.data = data.data;
|
9
|
+
});
|
10
|
+
}
|
11
|
+
|
12
|
+
function saveProfile() {
|
13
|
+
// Create upload
|
14
|
+
var fd = new FormData(),
|
15
|
+
uploadUrl = config.getApiPath('odania_profile/profiles');
|
16
|
+
|
17
|
+
if ($scope.upload.file) {
|
18
|
+
fd.append('profile[image]', $scope.upload.file);
|
19
|
+
}
|
20
|
+
|
21
|
+
angular.forEach($scope.profile, function (value, key) {
|
22
|
+
if (key === 'skillSelection') {
|
23
|
+
var val = [];
|
24
|
+
|
25
|
+
for (var i=0 ; i<value.length ; i++) {
|
26
|
+
val.push(value[i][0]+':'+value[i][1]);
|
27
|
+
}
|
28
|
+
|
29
|
+
console.warn("HERE", key, value, val);
|
30
|
+
|
31
|
+
fd.append('profile[skillSelection]', val.join(','));
|
32
|
+
} else {
|
33
|
+
fd.append('profile[' + key + ']', value);
|
34
|
+
}
|
35
|
+
});
|
36
|
+
|
37
|
+
$http.post(uploadUrl, fd, {
|
38
|
+
transformRequest: angular.identity,
|
39
|
+
headers: {'Content-Type': undefined}
|
40
|
+
}).success(function () {
|
41
|
+
$location.path('/odania_profile/profile/index');
|
42
|
+
}).error(function (data) {
|
43
|
+
$scope.errors = data.errors;
|
44
|
+
});
|
45
|
+
}
|
46
|
+
|
47
|
+
function prepareSkillData(skills) {
|
48
|
+
var data = [], skill;
|
49
|
+
|
50
|
+
for (var i = 0; i < skills.length; i++) {
|
51
|
+
skill = skills[i];
|
52
|
+
|
53
|
+
data.push([skill.name, skill.percent]);
|
54
|
+
}
|
55
|
+
|
56
|
+
return data;
|
57
|
+
}
|
58
|
+
|
59
|
+
/**
|
60
|
+
* File handling
|
61
|
+
*/
|
62
|
+
$scope.setFile = function (element) {
|
63
|
+
$scope.$apply(function() {
|
64
|
+
$scope.upload.file = element.files[0];
|
65
|
+
});
|
66
|
+
};
|
67
|
+
// End file handling
|
68
|
+
|
69
|
+
$scope.saveProfile = saveProfile;
|
70
|
+
$scope.profile = {
|
71
|
+
'title': null,
|
72
|
+
'published': true
|
73
|
+
};
|
74
|
+
$scope.upload = {
|
75
|
+
'file': null
|
76
|
+
};
|
77
|
+
|
78
|
+
loadProfile();
|
79
|
+
}]);
|
@@ -0,0 +1,11 @@
|
|
1
|
+
app.controller('OdaniaProfileProfileController', ['$location', '$scope', '$rootScope', 'OdaniaProfileProfileResource', function ($location, $scope, $rootScope, OdaniaProfileProfileResource) {
|
2
|
+
console.log("controller :: OdaniaProfileProfileController");
|
3
|
+
|
4
|
+
function loadProfile() {
|
5
|
+
OdaniaProfileProfileResource.get().$promise.then(function (data) {
|
6
|
+
$scope.profile = data.profile;
|
7
|
+
});
|
8
|
+
}
|
9
|
+
|
10
|
+
loadProfile();
|
11
|
+
}]);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class OdaniaProfile::ProfilesController < ApplicationController
|
2
|
+
def index
|
3
|
+
@profiles = OdaniaProfile::Profile.where(published: true).order('updated_at DESC')
|
4
|
+
end
|
5
|
+
|
6
|
+
def show
|
7
|
+
@profile = OdaniaProfile::Profile.where(published: true, id: params[:id].to_i).first
|
8
|
+
redirect_to odania_profile_profiles_path if @profile.nil?
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class Protected::Api::OdaniaProfile::ProfilesController < Protected::ApiController
|
2
|
+
before_action :load_profile
|
3
|
+
|
4
|
+
def index
|
5
|
+
@timelines = OdaniaTimeline::Timeline.where(user_id: current_user.id, language_id: @profile.language_id)
|
6
|
+
end
|
7
|
+
|
8
|
+
def update
|
9
|
+
if @profile.update(profile_attributes)
|
10
|
+
update_skills
|
11
|
+
render action: :index
|
12
|
+
else
|
13
|
+
render json: {errors: @profile.errors}, status: :bad_request
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def profile_attributes
|
20
|
+
params.require(:profile).permit(:title, :name, :profession, :description, :published, :image, :timeline_id, :social => [:linked_in, :facebook, :google_plus, :twitter, :rss])
|
21
|
+
end
|
22
|
+
|
23
|
+
def load_profile
|
24
|
+
language_id = params[:language_id].nil? ? current_site.default_language_id : params[:language_id]
|
25
|
+
language_id = current_site.default_language_id unless current_site.menus.pluck(:language_id).include? language_id
|
26
|
+
@profile = OdaniaProfile::Profile.where(user_id: current_user.id, language_id: language_id).first
|
27
|
+
@profile = OdaniaProfile::Profile.new(user_id: current_user.id, language_id: language_id) if @profile.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
def update_skills
|
31
|
+
skill_ids = []
|
32
|
+
unless params[:profile][:skillSelection].nil?
|
33
|
+
params[:profile][:skillSelection].split(',').each do |data|
|
34
|
+
data = data.split(':')
|
35
|
+
|
36
|
+
skill = @profile.skills.where(name: data[0]).first
|
37
|
+
skill = @profile.skills.new(name: data[0]) if skill.nil?
|
38
|
+
skill.percent = data[1].to_i
|
39
|
+
skill.percent = 0 if skill.percent < 0
|
40
|
+
skill.percent = 100 if skill.percent > 100
|
41
|
+
skill.save!
|
42
|
+
skill_ids << skill.id
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
@profile.skills.where('id NOT IN (?)', skill_ids).destroy_all
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class OdaniaProfile::Profile < ActiveRecord::Base
|
2
|
+
serialize :social, JSON
|
3
|
+
|
4
|
+
belongs_to :site, :class_name => 'Odania::Site'
|
5
|
+
belongs_to :user, class_name: 'Odania::User'
|
6
|
+
belongs_to :language, class_name: 'Odania::Language'
|
7
|
+
has_many :skills, class_name: 'OdaniaProfile::Skill'
|
8
|
+
belongs_to :timeline, class_name: 'OdaniaTimeline::Timeline'
|
9
|
+
|
10
|
+
has_attached_file :image, :styles => {:medium => '300x300>', :thumb => '100x100>'},
|
11
|
+
default_url: '/images/odania_profile/defaults/profile_:style.jpg'
|
12
|
+
validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
|
13
|
+
|
14
|
+
def to_param
|
15
|
+
"#{self.id}-#{self.title.parameterize}"
|
16
|
+
end
|
17
|
+
|
18
|
+
before_save do
|
19
|
+
self.published = false if self.published.nil?
|
20
|
+
self.social = {none: ''} if self.social.nil?
|
21
|
+
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>OdaniaProfile</title>
|
5
|
+
<%= stylesheet_link_tag "odania_profile/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "odania_profile/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
@@ -0,0 +1,56 @@
|
|
1
|
+
<% content_for(:page_header) do %>
|
2
|
+
<div class="container">
|
3
|
+
<div class="row">
|
4
|
+
<div class="col-md-6 col-md-push-6">
|
5
|
+
<h1 class="animated fadeInDown animation-delay-1"><%= @profile.name %></h1>
|
6
|
+
|
7
|
+
<h2 class="animated fadeInDown animation-delay-2"><%= @profile.profession %></h2>
|
8
|
+
|
9
|
+
<div class="profile-header-btn text-center">
|
10
|
+
<!--
|
11
|
+
<a href="#" class="btn btn-ar btn-primary btn-lg"><i class="fa fa-desktop"></i> View Portfolio</a>
|
12
|
+
<a href="#" class="btn btn-ar btn-danger btn-lg"><i class="fa fa-download"></i> Download CV</a>
|
13
|
+
-->
|
14
|
+
</div>
|
15
|
+
<div class="profile-header-social">
|
16
|
+
<%= render partial: 'odania/common/social', locals: {social: @profile.social} %>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
<div class="col-md-6 col-md-pull-6">
|
20
|
+
<div class="home-profile-img center-block text-center animated fadeInDown animation-delay-6">
|
21
|
+
<%= image_tag @profile.image.url(:medium), {alt: @profile.name, title: @profile.title} %>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
<% end %>
|
27
|
+
|
28
|
+
<div class="container margin-bottom">
|
29
|
+
<div class="row">
|
30
|
+
<div class="col-md-12">
|
31
|
+
<h2 class="right-line no-margin-bottom"><%= @profile.title %></h2>
|
32
|
+
</div>
|
33
|
+
<div class="col-md-6 animated fadeInLeft animation-delay-8">
|
34
|
+
<%= raw @profile.description %>
|
35
|
+
</div>
|
36
|
+
<div class="col-md-6">
|
37
|
+
<h3><%= t('odania_profile.skills') %></h3>
|
38
|
+
|
39
|
+
<% @profile.skills.each do |skill| %>
|
40
|
+
<div class="progress progress-lg">
|
41
|
+
<div class="progress-bar" role="progressbar" aria-valuenow="<%= skill.percent %>" aria-valuemin="0" aria-valuemax="100" style="width: <%= skill.percent %>%;">
|
42
|
+
<%= skill.name %>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
<% end %>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
|
49
|
+
<div class="row">
|
50
|
+
<div class="col-md-12">
|
51
|
+
<% unless @profile.timeline.nil? %>
|
52
|
+
<%= render partial: 'odania_timeline/timelines/show', locals: {timeline: @profile.timeline} %>
|
53
|
+
<% end %>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
</div> <!-- container -->
|
@@ -0,0 +1 @@
|
|
1
|
+
json.profiles OdaniaProfile::Profile.where(published: true), partial: 'protected/api/odania_profile/profiles/show', as: :profile
|
@@ -0,0 +1,13 @@
|
|
1
|
+
json.id profile.id
|
2
|
+
json.title profile.title
|
3
|
+
json.name profile.name
|
4
|
+
json.profession profile.profession
|
5
|
+
json.description profile.description
|
6
|
+
json.social profile.social
|
7
|
+
json.published profile.published
|
8
|
+
json.image_url profile.image.url
|
9
|
+
json.image_thumb_url profile.image.url(:thumb)
|
10
|
+
json.image_medium_url profile.image.url(:medium)
|
11
|
+
json.timeline_id profile.timeline_id
|
12
|
+
|
13
|
+
json.skills profile.skills, partial: 'protected/api/odania_profile/skills/show', as: :skill
|
File without changes
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<form class="form-horizontal" role="form">
|
2
|
+
<div class="row-fluid">
|
3
|
+
<div class="col-md-9">
|
4
|
+
<h1>Editing Site {{ site.name }}</h1>
|
5
|
+
|
6
|
+
<tabset>
|
7
|
+
<tab heading="General"><%= render partial: '/protected/template/templates/odania_profile/profile/tab_general' %></tab>
|
8
|
+
<tab heading="Description"><%= render partial: '/protected/template/templates/odania_profile/profile/tab_description' %></tab>
|
9
|
+
<tab heading="Social"><%= render partial: '/protected/template/templates/odania_profile/profile/tab_social' %></tab>
|
10
|
+
<tab heading="Skills"><%= render partial: '/protected/template/templates/odania_profile/profile/tab_skills' %></tab>
|
11
|
+
</tabset>
|
12
|
+
</div>
|
13
|
+
<div class="col-md-3">
|
14
|
+
<div class="form-group">
|
15
|
+
<div class="col-sm-offset-2 col-sm-10">
|
16
|
+
<button data-ng-click="saveProfile()" class="btn btn-primary"><%= t('general.save') %></button>
|
17
|
+
|
18
|
+
<span data-ng-if="errors" style="color: red;"><%= t('general.Please correct the errors') %></span>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div class="form-group">
|
23
|
+
<label class="col-sm-2 control-label">Published</label>
|
24
|
+
|
25
|
+
<div class="col-sm-10">
|
26
|
+
<input type="checkbox" data-ng-model="profile.published">
|
27
|
+
</div>
|
28
|
+
</div>
|
29
|
+
|
30
|
+
<div class="form-group">
|
31
|
+
<label class="col-sm-2 control-label">Timeline</label>
|
32
|
+
|
33
|
+
<div class="col-sm-10">
|
34
|
+
<div class="form-control">
|
35
|
+
<select data-ng-model="profile.timeline_id" data-ng-options="timeline.id as timeline.title for timeline in data.timelines">
|
36
|
+
<option value="">-</option>
|
37
|
+
</select>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
</form>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<div class="row-fluid">
|
2
|
+
<div class="col-md-9">
|
3
|
+
<table class="table">
|
4
|
+
<tr>
|
5
|
+
<th>Title</th>
|
6
|
+
<td>{{ profile.title }}</td>
|
7
|
+
</tr>
|
8
|
+
<tr>
|
9
|
+
<th>Image</th>
|
10
|
+
<td>
|
11
|
+
<img data-ng-src="{{ profile.image_thumb_url }}"/>
|
12
|
+
</td>
|
13
|
+
</tr>
|
14
|
+
<tr>
|
15
|
+
<th>Name</th>
|
16
|
+
<td>{{ profile.name }}</td>
|
17
|
+
</tr>
|
18
|
+
<tr>
|
19
|
+
<th>Profession</th>
|
20
|
+
<td>{{ profile.profession }}</td>
|
21
|
+
</tr>
|
22
|
+
<tr>
|
23
|
+
<th>Description</th>
|
24
|
+
<td>{{ profile.description }}</td>
|
25
|
+
</tr>
|
26
|
+
<tr>
|
27
|
+
<th>Skills</th>
|
28
|
+
<td>
|
29
|
+
<span data-ng-repeat="skill in profile.skills">{{ skill.name }} - {{ skill.percent }}% </span>
|
30
|
+
</td>
|
31
|
+
</tr>
|
32
|
+
<tr>
|
33
|
+
<th>Social</th>
|
34
|
+
<td>
|
35
|
+
<span data-ng-repeat="(key, value) in profile.social">{{ key }}: {{ value }}<br/></span>
|
36
|
+
</td>
|
37
|
+
</tr>
|
38
|
+
</table>
|
39
|
+
</div>
|
40
|
+
<div class="col-md-3">
|
41
|
+
<%= link_to t('general.edit'), '#/odania_profile/profile/edit', {class: 'btn btn-primary'} %>
|
42
|
+
</div>
|
43
|
+
</div>
|
@@ -0,0 +1,47 @@
|
|
1
|
+
<div class="form-group">
|
2
|
+
<label class="col-sm-2 control-label" for="site_title">Title</label>
|
3
|
+
|
4
|
+
<div class="col-sm-10">
|
5
|
+
<input type="text" id="site_title" class="form-control" data-ng-model="profile.title" placeholder="Profile Title"/>
|
6
|
+
<span data-ng-if="errors.title" style="color: red;">{{ printErrors(errors.title) }}</span>
|
7
|
+
</div>
|
8
|
+
</div>
|
9
|
+
<div class="form-group">
|
10
|
+
<label class="col-sm-2 control-label" for="site_name">Name</label>
|
11
|
+
|
12
|
+
<div class="col-sm-10">
|
13
|
+
<input type="text" id="site_name" class="form-control" data-ng-model="profile.name" placeholder="Profile Name"/>
|
14
|
+
<span data-ng-if="errors.name" style="color: red;">{{ printErrors(errors.name) }}</span>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
<div class="form-group">
|
18
|
+
<label class="col-sm-2 control-label" for="profile_profession">Profession</label>
|
19
|
+
|
20
|
+
<div class="col-sm-10">
|
21
|
+
<input type="text" id="profile_profession" class="form-control" data-ng-model="profile.profession" placeholder="Softwaredeveloper"/>
|
22
|
+
<span data-ng-if="errors.profession" style="color: red;">{{ printErrors(errors.profession) }}</span>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
<div class="form-group">
|
26
|
+
<label class="col-sm-2 control-label">Image</label>
|
27
|
+
|
28
|
+
<div class="col-sm-10">
|
29
|
+
<div data-ng-if="media.image_thumb_url">
|
30
|
+
<%= t('odania_profile.current_image') %>
|
31
|
+
<img data-ng-src="{{ media.image_thumb_url }}" alt="{{ media.title }}" title="{{ media.title }}"/>
|
32
|
+
</div>
|
33
|
+
|
34
|
+
<div data-ng-if="upload.file">
|
35
|
+
<span>{{ upload.file.webkitRelativePath || upload.file.name }}</span>
|
36
|
+
(
|
37
|
+
<span ng-switch="upload.file.size > 1024*1024">
|
38
|
+
<span ng-switch-when="true">{{upload.file.size / 1024 / 1024 | number:2}} MB</span>
|
39
|
+
<span ng-switch-default>{{upload.file.size / 1024 | number:2}} kB</span>
|
40
|
+
</span>
|
41
|
+
)
|
42
|
+
</div>
|
43
|
+
|
44
|
+
<input type="file" data-ng-model-instant onchange="angular.element(this).scope().setFile(this)" />
|
45
|
+
<span data-ng-if="errors.image" style="color: red;">{{ printErrors(errors.image) }}</span>
|
46
|
+
</div>
|
47
|
+
</div>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<div class="well">
|
2
|
+
<h3>Skills</h3>
|
3
|
+
|
4
|
+
<div class="form-group">
|
5
|
+
<div class="skill-selection">
|
6
|
+
Name: <input type="text" data-ng-model="addSkillInput" name="skill_ids" />
|
7
|
+
|
8
|
+
Percent: <input type="text" data-ng-model="addSkillPercent" name="skill_percents" />
|
9
|
+
<button class="btn btn-default" data-ng-click="addToArray(profile.skillSelection, [addSkillInput, addSkillPercent]);">
|
10
|
+
Add
|
11
|
+
</button>
|
12
|
+
|
13
|
+
<p class="form-control">
|
14
|
+
<span data-ng-repeat="skill in profile.skillSelection">
|
15
|
+
<a data-ng-click="profile.skillSelection.splice($index, 1);">
|
16
|
+
<i class="fa fa-minus-square"></i>
|
17
|
+
</a> {{ skill[0] }} - {{ skill[1] }}%
|
18
|
+
</span>
|
19
|
+
</p>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
|
23
|
+
<span data-ng-if="errors.skills" style="color: red;">{{ printErrors(errors.skills) }}</span>
|
24
|
+
</div>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<div class="form-group">
|
2
|
+
<label class="col-sm-2 control-label">Facebook</label>
|
3
|
+
|
4
|
+
<div class="col-sm-10">
|
5
|
+
<input type="text" class="form-control" data-ng-model="profile.social.facebook" placeholder="https://www.facebook.com/pages/Odania-IT/113349882108655"/>
|
6
|
+
</div>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<div class="form-group">
|
10
|
+
<label class="col-sm-2 control-label">Twitter</label>
|
11
|
+
|
12
|
+
<div class="col-sm-10">
|
13
|
+
<input type="text" class="form-control" data-ng-model="profile.social.twitter" placeholder="https://twitter.com/OdaniaIT"/>
|
14
|
+
</div>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div class="form-group">
|
18
|
+
<label class="col-sm-2 control-label">Google+</label>
|
19
|
+
|
20
|
+
<div class="col-sm-10">
|
21
|
+
<input type="text" class="form-control" data-ng-model="profile.social.google_plus" placeholder="https://plus.google.com/110850943371659722554/posts"/>
|
22
|
+
</div>
|
23
|
+
</div>
|
24
|
+
|
25
|
+
<div class="form-group">
|
26
|
+
<label class="col-sm-2 control-label">LinkedIn</label>
|
27
|
+
|
28
|
+
<div class="col-sm-10">
|
29
|
+
<input type="text" class="form-control" data-ng-model="profile.social.linked_in" placeholder="http://de.linkedin.com/in/mikepetersen79"/>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
|
33
|
+
<div class="form-group">
|
34
|
+
<label class="col-sm-2 control-label">RSS</label>
|
35
|
+
|
36
|
+
<div class="col-sm-10">
|
37
|
+
<input type="text" class="form-control" data-ng-model="profile.social.rss" placeholder="http://de.onlinegames-info.com/games.xml"/>
|
38
|
+
</div>
|
39
|
+
</div>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Rails.application.routes.draw do
|
2
|
+
namespace :odania_profile do
|
3
|
+
namespace :protected do
|
4
|
+
get 'profiles' => 'profiles#index'
|
5
|
+
post 'profiles' => 'profiles#update'
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
namespace :protected do
|
10
|
+
namespace :api, defaults: {format: :json} do
|
11
|
+
namespace :odania_profile do
|
12
|
+
get 'profiles' => 'profiles#index'
|
13
|
+
post 'profiles' => 'profiles#update'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
scope '/:locale', constraints: {locale: /[a-z][a-z]/} do
|
19
|
+
namespace :odania_profile do
|
20
|
+
get 'profiles' => 'profiles#index'
|
21
|
+
get 'profiles/:id' => 'profiles#show'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class CreateOdaniaProfileProfiles < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :odania_profile_profiles do |t|
|
4
|
+
t.references :user, index: true
|
5
|
+
t.references :language, index: true
|
6
|
+
t.references :site, index: true
|
7
|
+
t.references :timeline, index: true
|
8
|
+
t.string :title
|
9
|
+
t.string :name
|
10
|
+
t.string :profession
|
11
|
+
t.text :social
|
12
|
+
t.text :description
|
13
|
+
t.boolean :published
|
14
|
+
t.timestamps null: false
|
15
|
+
end
|
16
|
+
add_foreign_key :odania_profile_profiles, :odania_sites, column: :site_id
|
17
|
+
add_foreign_key :odania_profile_profiles, :odania_users, column: :user_id
|
18
|
+
add_foreign_key :odania_profile_profiles, :odania_languages, column: :language_id
|
19
|
+
add_foreign_key :odania_profile_profiles, :odania_timeline_timelines, column: :timeline_id
|
20
|
+
add_attachment :odania_profile_profiles, :image
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateOdaniaProfileSkills < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :odania_profile_skills do |t|
|
4
|
+
t.references :profile, index: true
|
5
|
+
t.string :name
|
6
|
+
t.integer :percent
|
7
|
+
t.timestamps null: false
|
8
|
+
end
|
9
|
+
add_foreign_key :odania_profile_skills, :odania_profile_profiles, column: :profile_id
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'odania_core'
|
2
|
+
require 'odania'
|
3
|
+
require 'odania_timeline'
|
4
|
+
|
5
|
+
module OdaniaProfile
|
6
|
+
PLUGIN_NAME = 'odania_profile'
|
7
|
+
|
8
|
+
class Engine < ::Rails::Engine
|
9
|
+
config.generators do |g|
|
10
|
+
g.test_framework :rspec
|
11
|
+
g.fixture_replacement :factory_girl, :dir => 'spec/factories'
|
12
|
+
end
|
13
|
+
|
14
|
+
Odania.protected.plugins << OdaniaProfile::PLUGIN_NAME
|
15
|
+
Odania.protected.pages << {name: 'Personal Profile', in_menu: true, path: '/odania_profile/profile/index', controller: 'OdaniaProfileProfileController',
|
16
|
+
template: 'odania_profile/profile/index', active: OdaniaProfile::PLUGIN_NAME}
|
17
|
+
Odania.protected.pages << {name: 'Edit Personal Profile', in_menu: false, path: '/odania_profile/profile/edit', controller: 'OdaniaProfileEditProfileController',
|
18
|
+
template: 'odania_profile/profile/edit', active: OdaniaProfile::PLUGIN_NAME}
|
19
|
+
|
20
|
+
# Add content types
|
21
|
+
Odania::TargetType.targets['PROFILES'] = {type: 'PROFILES',
|
22
|
+
module: 'OdaniaProfile::EngineTargetType', validator_func: 'validate_profiles',
|
23
|
+
render_func: '', selector: 'protected/odania_profile/profiles/choose_profiles',
|
24
|
+
initial_data: 'admin/api/menu_items/empty_inital_data'}
|
25
|
+
Odania::TargetType.targets['PROFILE'] = {type: 'PROFILE',
|
26
|
+
module: 'OdaniaProfile::EngineTargetType', validator_func: 'validate_profile',
|
27
|
+
render_func: '', selector: 'protected/odania_profile/profiles/choose_profile',
|
28
|
+
initial_data: 'protected/api/odania_profile/profiles/inital_data'}
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module OdaniaProfile
|
2
|
+
module EngineTargetType
|
3
|
+
class << self
|
4
|
+
def validate_profiles(menu_item, target_data)
|
5
|
+
menu_item.full_path = 'odania_profile/profiles'
|
6
|
+
|
7
|
+
nil
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate_profile(menu_item, target_data)
|
11
|
+
return 'invalid profile id' if target_data['id'].nil?
|
12
|
+
|
13
|
+
profile = OdaniaProfile::Profile.where(id: target_data['id']).first
|
14
|
+
return 'invalid profile id' if profile.nil?
|
15
|
+
|
16
|
+
menu_item.full_path = "odania_profile/profiles/#{profile.to_param}"
|
17
|
+
|
18
|
+
return nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: odania_profile
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mike Petersen
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: odania_core
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: odania_timeline
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: The Odania Portal is an open source portal system with strong focus on
|
56
|
+
the usage on different domains with different layout/setup.
|
57
|
+
email:
|
58
|
+
- mike@odania-it.de
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- MIT-LICENSE
|
64
|
+
- README.rdoc
|
65
|
+
- Rakefile
|
66
|
+
- app/assets/javascripts/odania_profile/application.js
|
67
|
+
- app/assets/javascripts/odania_profile/controllers/profile/edit_profile_controller.js
|
68
|
+
- app/assets/javascripts/odania_profile/controllers/profile/profile_controller.js
|
69
|
+
- app/assets/javascripts/odania_profile/resoures/profile_resource.js
|
70
|
+
- app/assets/stylesheets/odania_profile/application.css
|
71
|
+
- app/assets/stylesheets/odania_profile/protected/profiles.scss
|
72
|
+
- app/controllers/odania_profile/application_controller.rb
|
73
|
+
- app/controllers/odania_profile/profiles_controller.rb
|
74
|
+
- app/controllers/protected/api/odania_profile/profiles_controller.rb
|
75
|
+
- app/helpers/odania_profile/application_helper.rb
|
76
|
+
- app/models/odania_profile.rb
|
77
|
+
- app/models/odania_profile/profile.rb
|
78
|
+
- app/models/odania_profile/skill.rb
|
79
|
+
- app/views/layouts/odania_profile/application.html.erb
|
80
|
+
- app/views/odania_profile/profiles/index.html.erb
|
81
|
+
- app/views/odania_profile/profiles/show.html.erb
|
82
|
+
- app/views/protected/api/odania_profile/profiles/_inital_data.json.jbuilder
|
83
|
+
- app/views/protected/api/odania_profile/profiles/_show.json.jbuilder
|
84
|
+
- app/views/protected/api/odania_profile/profiles/index.json.jbuilder
|
85
|
+
- app/views/protected/api/odania_profile/skills/_show.json.jbuilder
|
86
|
+
- app/views/protected/odania_profile/profiles/_choose_profile.html.erb
|
87
|
+
- app/views/protected/odania_profile/profiles/_choose_profiles.html.erb
|
88
|
+
- app/views/protected/template/templates/odania_profile/profile/_edit.html.erb
|
89
|
+
- app/views/protected/template/templates/odania_profile/profile/_index.html.erb
|
90
|
+
- app/views/protected/template/templates/odania_profile/profile/_tab_description.html.erb
|
91
|
+
- app/views/protected/template/templates/odania_profile/profile/_tab_general.html.erb
|
92
|
+
- app/views/protected/template/templates/odania_profile/profile/_tab_skills.html.erb
|
93
|
+
- app/views/protected/template/templates/odania_profile/profile/_tab_social.html.erb
|
94
|
+
- config/locales/de.yml
|
95
|
+
- config/locales/en.yml
|
96
|
+
- config/routes.rb
|
97
|
+
- db/migrate/20150323144052_create_odania_profile_profiles.rb
|
98
|
+
- db/migrate/20150323144146_create_odania_profile_skills.rb
|
99
|
+
- lib/odania_profile.rb
|
100
|
+
- lib/odania_profile/engine.rb
|
101
|
+
- lib/odania_profile/engine_target_type.rb
|
102
|
+
- lib/odania_profile/version.rb
|
103
|
+
- lib/tasks/odania_profile_tasks.rake
|
104
|
+
homepage: http://www.odania.de
|
105
|
+
licenses: []
|
106
|
+
metadata: {}
|
107
|
+
post_install_message:
|
108
|
+
rdoc_options: []
|
109
|
+
require_paths:
|
110
|
+
- lib
|
111
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
requirements:
|
118
|
+
- - ">="
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0'
|
121
|
+
requirements: []
|
122
|
+
rubyforge_project:
|
123
|
+
rubygems_version: 2.4.6
|
124
|
+
signing_key:
|
125
|
+
specification_version: 4
|
126
|
+
summary: 'Odania Portal Template: ArtificalReason'
|
127
|
+
test_files: []
|