Преглед на файлове

All sections included. Basque translation added.

Iñigo Valentin преди 4 години
родител
ревизия
9d3ca1443b
променени са 45 файла, в които са добавени 944 реда и са изтрити 83 реда
  1. 1 0
      app/assets/config/manifest.js
  2. 16 0
      app/assets/javascripts/help.js
  3. 29 0
      app/assets/stylesheets/help.css
  4. 111 0
      app/assets/stylesheets/profile.css
  5. 0 0
      app/assets/stylesheets/profiles.scss
  6. 51 0
      app/assets/stylesheets/projects.css
  7. 0 3
      app/assets/stylesheets/projects.scss
  8. 10 2
      app/controllers/application_controller.rb
  9. 4 0
      app/controllers/help_controller.rb
  10. 0 1
      app/controllers/main_controller.rb
  11. 2 1
      app/controllers/profile_controller.rb
  12. 1 1
      app/controllers/projects_controller.rb
  13. 2 0
      app/helpers/help_helper.rb
  14. 4 0
      app/models/resume.rb
  15. 6 0
      app/models/social_link.rb
  16. 2 0
      app/models/user.rb
  17. 7 0
      app/models/user_social_link.rb
  18. 41 0
      app/views/help/index.html.erb
  19. 27 19
      app/views/layouts/_footer.html.erb
  20. 1 1
      app/views/layouts/_header.html.erb
  21. 1 1
      app/views/main/index.html.erb
  22. 44 0
      app/views/profile/index.html.erb
  23. 32 10
      app/views/projects/index.html.erb
  24. 9 0
      config/application.rb
  25. 40 5
      config/locales/en.yml
  26. 50 7
      config/locales/es.yml
  27. 214 0
      config/locales/eu.yml
  28. 5 13
      config/routes.rb
  29. 0 18
      db/migrate/20211212114959_dummy.rb
  30. 12 0
      db/migrate/20211213092427_create_social_links.rb
  31. 12 0
      db/migrate/20211213094550_create_user_social_links.rb
  32. 13 0
      db/migrate/20211213105552_create_resumes.rb
  33. 35 1
      db/schema.rb
  34. BIN
      public/fonts/Latin-Modern-Mono-Light-Bold.otf
  35. BIN
      public/fonts/Nunito-Bold.ttf
  36. BIN
      public/fonts/Nunito-Light.ttf
  37. BIN
      public/fonts/Nunito-Regular.ttf
  38. 93 0
      public/fonts/OFL.txt
  39. 7 0
      test/controllers/help_controller_test.rb
  40. 15 0
      test/fixtures/resumes.yml
  41. 13 0
      test/fixtures/social_links.yml
  42. 13 0
      test/fixtures/user_social_links.yml
  43. 7 0
      test/models/resume_test.rb
  44. 7 0
      test/models/social_link_test.rb
  45. 7 0
      test/models/user_social_link_test.rb

+ 1 - 0
app/assets/config/manifest.js

@@ -1,2 +1,3 @@
 //= link_tree ../images
 //= link_directory ../stylesheets .css
+//= link_directory ../javascripts .js

+ 16 - 0
app/assets/javascripts/help.js

@@ -0,0 +1,16 @@
+function toggleHelp(id){
+    var helps = document.getElementsByClassName("help");
+    for (var i = 0; i < helps.length; i++) {
+        if (helps[i].id == id){
+            if (helps[i].classList.contains("selected")){
+                helps[i].classList.remove("selected");
+            }
+            else{
+                helps[i].classList.add("selected");
+            }
+        }
+        else{
+            helps[i].classList.remove("selected");
+        }
+    }
+}

+ 29 - 0
app/assets/stylesheets/help.css

@@ -0,0 +1,29 @@
+section{
+    padding: 0;
+    max-height: 2.8em;
+    overflow-y: hidden;
+    border-bottom-right-radius: 0.5em;
+    border-bottom-left-radius: 0.5em;
+    transition: all .5s ease-in-out;
+}
+section.selected{
+    max-height: 30em;
+    border-bottom-right-radius: 1.5em;
+    border-bottom-left-radius: 1.5em;
+}
+section h3{
+    margin: 0;
+}
+section h3 img.slider{
+    width: 1em;
+    height: 1em;
+    transition: all .3s ease-in-out;
+    float: left;
+    margin-left: -2em;
+}
+section.selected h3 img.slider{
+    transform: rotate(90deg);
+}
+section p{
+    margin: 1em 2em;
+}

+ 111 - 0
app/assets/stylesheets/profile.css

@@ -0,0 +1,111 @@
+main{
+    text-align: center;
+}
+
+section#info{
+    text-align: left;
+    display: inline-block;
+    vertical-align: top;
+    width: 30%;
+    margin: auto 2em auto auto;
+}
+@media screen and (max-width : 800px){
+    section#info{
+        width: 90%;
+        margin: auto;
+        text-align: center;
+    }
+    section#info h3{
+        text-align: left;
+    }
+}
+
+section#info img#profile_image{
+    display: block;
+    margin: 0.5em auto;
+    max-width: 10em;
+    max-height: 10em;
+    border-radius: 1.2em;
+    box-shadow: 0 0 0 0.1em #000000, 0 0 0 0.3em #66bf38, 0 0 0 0.4em #000000;
+}
+@media screen and (max-width : 800px){
+    section#info img#profile_image{
+        display: inline-block;
+        vertical-align: middle;
+        width: 30%;
+        max-width: 12em;
+        max-height: 12em;
+    }
+}
+section#info div#social{
+    text-align: center;
+    margin: auto;
+}
+@media screen and (max-width : 800px){
+    section#info div#social{
+        display: inline-block;
+        vertical-align: middle;
+        width: 40%;
+        margin: auto;
+    }
+}
+section#info div#social img{
+    width: 60px;
+    height: 60px;
+    margin: 10px;
+    vertical-align: middle;
+    background-color: #ffffff;
+    border: 0.2em solid #ffffff;
+    border-radius: 0.4em;
+    box-shadow: 0 0 0.3em #003300;
+    transition: all .2s ease-in-out;
+}
+section#info div#social img:hover{
+    width: 70px;
+    height: 70px;
+    margin: 5px;
+    border-radius: 50%;
+    box-shadow: 0 0 0.5em #55aa55;
+}
+
+section#about{
+    text-align: left;
+    display: inline-block;
+    vertical-align: top;
+    width: 50%;
+    margin: auto;
+}
+@media screen and (max-width : 800px){
+    section#about{
+        width: 90%;
+        margin: 2em auto auto auto;
+    }
+}
+section#about p{
+    font-style: italic;
+    text-indent: 1em;
+    margin: 2em 4em;
+    color: #335333;
+}
+section#about div#resume_download{
+    text-align: center;
+}
+section#about div#resume_download a.a_button{
+    display: inline-block;
+    vertical-align: top;
+    margin: auto 3em 1.5em auto;
+}
+section#about div#resume_download details{
+    display: inline-block;
+    vertical-align: top;
+    font-style: italic;
+    margin-top: 0.5em;
+}
+section#about div#resume_download details summary{
+    color: #777777;
+    font-size: 90%;
+}
+section#about div#resume_download details ul{
+    text-align: left;
+    margin: 0.1em;
+}

+ 0 - 0
app/assets/stylesheets/profile.scss → app/assets/stylesheets/profiles.scss


+ 51 - 0
app/assets/stylesheets/projects.css

@@ -0,0 +1,51 @@
+/* Projects page */
+section{
+    width: 90%;
+    margin: auto;
+    text-align: center;
+}
+section h3{
+    text-align: left;
+}
+
+section article.project{
+    position: relative;
+    display: inline-block;
+    vertical-align: top;
+    width: 40%;
+    margin: 2em 3%;
+    padding: 1em;
+    text-align: left;
+    border-left: 0.1em solid #aacaaa;
+    border-right: 0.1em solid #aacaaa;
+    background: linear-gradient(to bottom, #e5f0e500 0%, #e5f0e5ff 20%, #e5f0e5ff 80%, #e5f0e500 100%);
+}
+@media screen and (max-width : 800px){
+	section article.project{
+	    width: 90%;
+	    margin: 1em auto;
+	}
+}
+
+section article.project table{
+    width: 100%;
+}
+
+section article.project table img.project_image{
+    padding: 0.5em;
+    width: 7em;
+    height: 7em;
+    background-color: #cccccc;
+    border: 0.1em solid #60ae29;
+    box-shadow: inset 0 0 0.5em #00220077;
+    border-radius: 1em;
+}
+
+div#project_list article.project table td.project_details{
+    padding-left: 1.5em;
+}
+
+div#project_list article.project table span.project_tagline{
+    font-size: 80%;
+    font-style: italic;
+}

+ 0 - 3
app/assets/stylesheets/projects.scss

@@ -1,3 +0,0 @@
-// Place all the styles related to the Projects controller here.
-// They will automatically be included in application.css.
-// You can use Sass (SCSS) here: https://sass-lang.com/

+ 10 - 2
app/controllers/application_controller.rb

@@ -1,16 +1,24 @@
 class ApplicationController < ActionController::Base
 
     before_action :set_locale
+    before_action :set_user
+
+    
 
     private
+    
+    def set_user
+        @user = User.find(1)
+    end
+    
     def set_locale
         I18n.locale = extract_locale || I18n.default_locale
-        logger.debug "LOCALE SET TO " + I18n.locale.to_s
+        Rails.application.reload_routes!
     end
 
     def extract_locale
-        logger.debug "Extracting locale: "
         parsed_locale = params[:locale]
         I18n.available_locales.map(&:to_s).include?(parsed_locale) ? parsed_locale : nil
     end
+    
 end

+ 4 - 0
app/controllers/help_controller.rb

@@ -0,0 +1,4 @@
+class HelpController < ApplicationController
+  def index
+  end
+end

+ 0 - 1
app/controllers/main_controller.rb

@@ -1,6 +1,5 @@
 class MainController < ApplicationController
     def index
-        @user = User.find(1)
         @projects = Project.where(user_id: @user.id).order(priority: :desc).limit(3)
     end
 end

+ 2 - 1
app/controllers/profile_controller.rb

@@ -1,5 +1,6 @@
 class ProfileController < ApplicationController
     def index
-        @user = User.find(1)
+        @resume_main = @user.resumes.where(user_id: @user.id, language: I18n.locale).order(priority: :desc)[0]
+        @resume_languages = @user.resumes.where(user_id: @user.id, priority: @resume_main.priority).where.not(language: I18n.locale)
     end
 end

+ 1 - 1
app/controllers/projects_controller.rb

@@ -1,6 +1,6 @@
 class ProjectsController < ApplicationController
     def index
-        @projects = Project.all
+        @projects = Project.where(user_id: @user.id).order(priority: :desc)
     end
     def show
         @project = Project.where(permalink: params[:permalink])[0]

+ 2 - 0
app/helpers/help_helper.rb

@@ -0,0 +1,2 @@
+module HelpHelper
+end

+ 4 - 0
app/models/resume.rb

@@ -0,0 +1,4 @@
+class Resume < ApplicationRecord
+  belongs_to :user
+  has_one_attached :file
+end

+ 6 - 0
app/models/social_link.rb

@@ -0,0 +1,6 @@
+class SocialLink < ApplicationRecord
+    has_one_attached :logo
+    def i18n_link_title
+        return Text.where(language: I18n.locale, key: self.link_title)[0].text
+    end
+end

+ 2 - 0
app/models/user.rb

@@ -1,7 +1,9 @@
 class User < ApplicationRecord
     has_many :mail_adresses
+    has_many :resumes
     has_many_attached :picture
     has_and_belongs_to_many :technologies
+    has_many :user_social_links
     def i18n_tagline
         return Text.where(user_id: self.id, language: I18n.locale, key: self.tagline)[0].text
     end

+ 7 - 0
app/models/user_social_link.rb

@@ -0,0 +1,7 @@
+class UserSocialLink < ApplicationRecord
+    belongs_to :user
+    belongs_to :social_link
+    def generate_link
+        return self.social_link.pattern.sub("*", self.link)
+    end
+end

+ 41 - 0
app/views/help/index.html.erb

@@ -0,0 +1,41 @@
+<% content_for :head do %>
+    <%= stylesheet_link_tag 'help', media: 'all', 'data-turbolinks-track': 'reload' %>
+    <%= javascript_include_tag 'help', 'data-turbolinks-track' => true  %>
+<% end %>
+<section id='about' class='help'>
+    <h3 class='pointer' onClick='toggleHelp("about");'>
+        <%= image_tag("control/slid_r.svg", class: "slider") %>
+        <%= t("help.about_title") %>
+    </h3>
+    <p>
+        <%= t("help.about_text").html_safe %>
+    </p>
+</section>
+<section id='privacy' class='help'>
+    <h3 class='pointer' onClick='toggleHelp("privacy");'>
+        <%= image_tag("control/slid_r.svg", class: "slider") %>
+        <%= t("help.privacy_title") %>
+    </h3>
+    <p>
+        <%= t("help.privacy_text").html_safe %>
+    </p>
+</section>
+<section id='cookies' class='help'>
+    <h3 class='pointer' onClick='toggleHelp("cookies");'>
+        <%= image_tag("control/slid_r.svg", class: "slider") %>
+        <%= t("help.cookies_title") %>
+    </h3>
+    <p>
+        <%= t("help.cookies_text").html_safe %>
+    </p>
+</section>
+<section id='license' class='help'>
+    <h3 class='pointer' onClick='toggleHelp("license");'>
+        <%= image_tag("control/slid_r.svg", class: "slider") %>
+        <%= t("help.license_title") %>
+    </h3>
+    <p>
+        <%= t("help.license_text").html_safe %>
+    </p>
+</section>
+

+ 27 - 19
app/views/layouts/_footer.html.erb

@@ -7,31 +7,39 @@
                 <span id='footer_follow' class='desktop'>
                     <%= t('footer.follow') %>
                 </span>
-                <a target='_blank' title='eMail' href='mailto:i@inigovalentin.com'>
-                    <%= image_tag ("social/email.svg"), class: "footer_social_icon", alt: t('social.mail') , title: t('social.mail') %>
-                </a>
-                <a target='_blank' title='Telegram' href='https://telegram.me/InigoValentin'>
-                    <%= image_tag ("social/telegram.svg"), class: "footer_social_icon", alt: t('social.telegram') , title: t('social.telegram') %>
-                </a>
-                <a target='_blank' title='Github' href='https://github.com/InigoValentin'>
-                    <%= image_tag ("social/github.svg"), class: "footer_social_icon", alt: t('social.github') , title: t('social.github') %>
-                </a>
-                <a target='_blank' title='LinkedIn' href='https://www.linkedin.com/in/ivalentin'>
-                    <%= image_tag ("social/linkedin.svg"), class: "footer_social_icon", alt: t('social.linkedin') , title: t('social.linkedin') %>
-                </a>
+                <% @user.user_social_links.each do |link| %>
+                <%= link_to(
+                    image_tag(link.social_link.logo, class: "footer_social_icon", alt: link.social_link.i18n_link_title, title: link.social_link.i18n_link_title),
+                    link.generate_link,
+                    target: "_blank",
+                    title: link.social_link.i18n_link_title
+                ) %>
+            <% end %>
             </td>
             <td id='footer_center'>
-                <%= t('footer.copy', year: Date.today.year) %>
+                <%= t('footer.copy', name: @user.full_name, year: Date.today.year) %>
             </td>
             <td id='footer_right'>
-                <a id='footer_help' href='<?=URL::BASE?>/help/'>
-                    <%= t('footer.help') %>
-                </a>
+                <%= link_to(
+                    t("footer.help"),
+                    help_path,
+                    id: "footer_help",
+                    title: t("footer.help")
+                ) %>
                 <br/><br/>
+                <%
+                    path = request.fullpath
+                    if path.to_s[0..4] =~ /[a-z]{2}/ then
+                        path = path[3..] + "/"
+                    end
+                %>
                 <% I18n.available_locales.each do |locale| %>
-                    <a class='lang' href='<?=$dest?>'>
-                        <%= image_tag ("lang/" + locale.to_s + ".svg") %>
-                    </a>
+                    <%= link_to(
+                        image_tag("lang/#{locale.to_s}.svg", alt: t("footer.lang_#{locale.to_s}"), title: t("footer.lang_#{locale.to_s}")),
+                        request.protocol + request.host_with_port + "/" + locale.to_s + path,
+                        class: "lang",
+                        title: t("footer.lang_#{locale.to_s}")
+                    ) %>
                 <% end %>
             </td>
         </tr>

+ 1 - 1
app/views/layouts/_header.html.erb

@@ -13,7 +13,7 @@
         ) %>
         <%= link_to(
             image_tag("icon/project.svg") + t('header.projects'),
-            projects_path()
+            project_index_url()
         ) %>
     </nav>
 </header>

+ 1 - 1
app/views/main/index.html.erb

@@ -6,7 +6,7 @@
         <%= @user.full_name %>
     </h3>
     <article>
-        <%=image_tag(@user.picture[0], id: "profile_image")%>
+        <%= image_tag(@user.picture[0], id: "profile_image")%>
         <div id='profile_content'>
             <h4 id='tagline'><%= @user.i18n_tagline %></h4>
             <p id='bio'><%= @user.i18n_bio %></p>

+ 44 - 0
app/views/profile/index.html.erb

@@ -8,6 +8,50 @@
     <article>
         <%=image_tag(@user.picture[0], id: "profile_image")%>
         <div id='social'>
+            <% @user.user_social_links.each do |link| %>
+                <%= link_to(
+                    image_tag(link.social_link.logo, class: "project_image", alt: link.social_link.i18n_link_title, title: link.social_link.i18n_link_title),
+                    link.generate_link,
+                    target: "_blank",
+                    title: link.social_link.i18n_link_title
+                ) %>
+            <% end %>
         </div>
     </article>
 </section>
+<section id='about'>
+    <h3>
+        <%= t("profile.description") %>
+    </h3>
+    <p>
+        <%= @user.i18n_bio %>
+    </p>
+    <div id='resume_download'>
+        <%= link_to(
+            t("profile.resume"),
+            @resume_main.file,
+            target: "_blank",
+            title: t("profile.resume"),
+            class: "a_button"
+        ) %>
+        <% if @resume_languages.size > 0 %>
+            <details>
+                <summary class='pointer'>
+                    <%= t("profile.resume_lang") %>
+                </summary>
+                <ul>
+                    <% @resume_languages.each do |resume| %>
+                        <li>
+                            <%= link_to(
+                                t("profile.resume_" + resume.language),
+                                resume.file,
+                                target: "_blank",
+                                title: t("profile.resume_" + resume.language)
+                            ) %>
+                        </li>
+                    <% end%>
+                </ul>
+            </details>
+        <% end%>
+    </div>
+</section>

+ 32 - 10
app/views/projects/index.html.erb

@@ -1,10 +1,32 @@
-<h1>Projects#index</h1>
-<p>Find me in app/views/projects/index.html.erb</p>
-<h2>Projects</h2>
-    <ul>
-        <% @projects.each do |project| %>
-            <li>
-                <%= project.title %>
-            </li>
-        <% end %>
-    </ul>
+<% content_for :head do %>
+    <%= stylesheet_link_tag 'projects', media: 'all', 'data-turbolinks-track': 'reload' %>
+<% end %>
+<section>
+    <h3>
+        <%= t("project.title") %>
+    </h3>
+    <% @projects.each do |project| %>
+        <article class='project'>
+            <table>
+                <tr>
+                    <td>
+                        <% if project.logo.attached? %>
+                            <%= link_to(
+                                image_tag(project.logo, class: "project_image"),
+                                project_show_path(permalink: project.permalink)
+                            ) %>
+                        <% end %>
+                    </td>
+                    <td class='project_details'>
+                        <h4 class='project_name'>
+                            <%= link_to(project.i18n_title, project_show_path(permalink: project.permalink)) %>
+                        </h4>
+                        <span>
+                            <%= project.i18n_header %>
+                        </span>
+                    </td>
+                </tr>
+            </table>
+        </article>
+    <% end %>
+</section>

+ 9 - 0
config/application.rb

@@ -27,5 +27,14 @@ module InigoValentin
     .active_storage
     .content_types_to_serve_as_binary
     .delete('image/svg+xml')
+    
+    ActiveStorage::Engine.config
+    .active_storage
+    .content_types_to_serve_as_binary
+    .delete('text/html')
+    
+    ActiveStorage::Engine.config.active_storage.content_types_allowed_inline.append('text/html')
+    print ActiveStorage::Engine.config.active_storage.content_types_to_serve_as_binary
+    print ActiveStorage::Engine.config.active_storage.content_types_allowed_inline
   end
 end

+ 40 - 5
config/locales/en.yml

@@ -31,6 +31,10 @@
 
 en:
     hello: "Hello world"
+    lang:
+        es: "Spanish"
+        en: "English"
+        eu: "Basque"
     time:
         monday: "Monday"
         tuesday: "Tuesday"
@@ -107,24 +111,30 @@ en:
         profile: "Me"
         projects: "Projects"
     footer:
-        copy: "Copyright Iñigo Valentin 2014 - %{year}"
+        copy: "Copyright %{name} 2014 - %{year}"
         help: "Help"
         follow: "Follow me"
+        lang_es: "Mostrar en castellano"
+        lang_en: "Show in english"
+        lang_eu: "Euskaraz ikusi"
     index:
         profile: "Me"
         projects: "Projects"
-        profile_cv: "R&eacute;sum&eacute;"
+        profile_cv: "Résumé"
         profile_more: "More about me"
         projects_all: "See all projects"
     profile:
-        cv: "R&eacute;sum&eacute;"
+        resume: "Résumé"
         title: "Me"
         skills: "Skills"
-        cv_lang: "Other languages"
+        resume_lang: "Other languages"
         description: "About me"
-        cv_printable: "View printable format"
+        resume_printable: "View printable format"
         download_other: "Download in other languages"
         download_current: "Download in english"
+        resume_es: "View in spanish"
+        resume_en: "View in english"
+        resume_eu: "View in basque"
     project:
         info: "Details"
         tags: "Tags"
@@ -169,3 +179,28 @@ en:
         swift: "Swift"
         sqlite: "SQLite"
         android: "Android"
+    help:
+        about_title: "Sobre este sitio"
+        about_text: "TODO"
+        privace_title: "Privacidad"
+        privacy_text: "Let's be honest. Nobody likes being tracked. At least I don't. That's why I don't track you.
+                       <br/><br/>
+                       I try to collect as few personal information about you as posible. There is no advertising, no registration is needed to download anything, no email subscription to see any content on the page, no third party code to track visits...
+                       <br/><br/>
+                       I like to keep a basic track of the visits on the site, it's good for my ego. To do so, I keep IP address of visitors, which I only keep for 72 hours. After that time, they get hashed (meaning I can't ever know the real IP address)
+                       <br/><br/>
+                       And that's pretty much it."
+        cookies_title: "Cookies"
+        cookies_text: "Being consequent with the previous paragraph, I've got bad news.
+                       <br/><br/>No cookies on this site.
+                       <br/><br/>:("
+        license_title: "Licencia"
+        license_text: "Bad news first: There are some icons (application stores, social networks, code repositories...) which, of course, are no work of mine, and are propery of their respective owners.
+                       <br/><br/>
+                       But as for everything else:
+                       <br/><br/>
+                       On most projects and code on this site you'll find it's license, usually a GPL one. For every thing else in this site a <a rel='license' target='_blank' href='http://creativecommons.org/licenses/by-sa/4.0/'>Creative Commons Attribution-ShareAlike 4.0 International License</a> applies.
+                       <br/><br/>
+                       Wich means that you can use, modify, and share this work or its modifications, as long as you give credit to me (for example, by linking to this page) and you keep this license unchanged.
+                       <br/><br/>
+                       So, go on! Start copying and downloading as if there were no tomorrow."

+ 50 - 7
config/locales/es.yml

@@ -31,6 +31,10 @@
 
 es:
     hello: "Hola Mundo!"
+    lang:
+        es: "Castellano"
+        en: "Inglés'"
+        eu: "Euskera"
     time:
         monday: "lunes"
         tuesday: "martes"
@@ -59,11 +63,11 @@ es:
     url_type:
         app_store: "App Store"
         github: "Github"
-        website: "Website"
+        website: "Sitio web"
         google_play: "Google Play"
         live: "Ver"
         app_store_summary: "Ver en App Store"
-        github_summary: "C&ocute;digo fuente en Github"
+        github_summary: "Codigo fuente en Github"
         website_summary: "Ir al sitio"
         google_play_summary: "Ver en Google Play"
         live_summary: "Ejecutar en el navegador"
@@ -107,9 +111,12 @@ es:
         profile: "Yo"
         projects: "Proyectos"
     footer:
-        copy: "Copyright Iñigo Valentin 2014 - %{year}"
+        copy: "Copyright %{name} 2014 - %{year}"
         help: "Ayuda"
         follow: "Sígueme"
+        lang_es: "Mostrar en castellano"
+        lang_en: "Show in english"
+        lang_eu: "Euskaraz ikusi"
     index:
         profile: "Yo"
         projects: "Proyectos"
@@ -117,14 +124,17 @@ es:
         profile_more: "Más sobre mí"
         projects_all: "Ver todos los proyectos"
     profile:
-        cv: "Currículo"
+        resume: "Currículo"
         title: "Yo"
         skills: "Habilidades"
-        cv_lang: "Otros idiomas"
+        resume_lang: "Otros idiomas"
         description: "Sobre mí"
-        cv_printable: "Formato imprimible"
+        resume_printable: "Formato imprimible"
         download_other: "Descargar en otros idiomas"
         download_current: "Descargar"
+        resume_es: "Ver en castellano"
+        resume_en: "Ver en inglés"
+        resume_eu: "Ver en euskera"
     project:
         info: "Detalles"
         tags: "Tags"
@@ -133,7 +143,7 @@ es:
         search: "Buscar"
         license: "Licencia"
         version: "Versión"
-        description: "Descripció"
+        description: "Descripción"
         search_type: "Tipo"
         license_legal: "Texto legal:"
         search_license: "Licencia"
@@ -169,3 +179,36 @@ es:
         swift: "Swift"
         sqlite: "SQLite"
         android: "Android"
+    help:
+        about_title: "Sobre este sitio"
+        about_text: "TODO"
+        privacy_title: "Privacidad"
+        privacy_text: "Vamos a ser sinceros, a nadie le gusta que le rastreen. Al menos a mi no, y por eso no te rastreo a ti.
+                       <br/><br/>
+                       Intento recopilar la menor información posible sobre ti. No hay anuncios, no hay registro para ver o descargar contenido, no hay suscripciones por email, no hay servicios externos para contabilizar visitas...
+                       <br/><br/>
+                       Si que mantengo unas estadísticas basicas sobre las visitas a este sitio, es algo que me resulta muy util. Para eso si que necesito almacenar tu dirección IP, y solo durante 72 horas. Despues, no tengo forma de volver a saberla.
+                       <br/><br/>
+                       Y ya está."
+        cookies_title: "Cookies"
+        cookies_text: "Siendo consecuente con el parrafo anterior....
+                       <br/><br/>... no hay cookies en este sitio.
+                       <br/><br/>:)"
+        license_title: "Licencia"
+        license_text: "Primero lo malo: Hay algunos iconos (tiendas de aplicaciones, redes sociales, sitios web externos...) que, por supuesto, no son creación mía', y son propiedad de sus respectivos propietarios.
+                       <br/><br/>
+                       Pero para todo lo demás:
+                       <br/><br/>
+                       En la mayoría de proyectos encontrarás un apartado sobre la licencia, normalmente una GPL o Creative Commons. Para todo lo demás, se aplica la licencia <a rel='license' target='_blank' href='http://creativecommons.org/licenses/by-sa/4.0/'>Creative Commons Attribution-ShareAlike 4.0 International License</a>.
+                       <br/><br/>
+                       Lo que significa que puedes usar, modificar, y difundir estos contenidos y sus modificaciones, siempre que me menciones como fuente (por ejemplo, con un enlace a esta página) y mantengas la misma licencia."
+                       
+
+
+
+
+
+
+
+
+

+ 214 - 0
config/locales/eu.yml

@@ -0,0 +1,214 @@
+# Files in the config/locales directory are used for internationalization
+# and are automatically loaded by Rails. If you want to use locales other
+# than English, add the necessary files in this directory.
+#
+# To use the locales, use `I18n.t`:
+#
+#     I18n.t 'hello'
+#
+# In views, this is aliased to just `t`:
+#
+#     <%= t('hello') %>
+#
+# To use a different locale, set it with `I18n.locale`:
+#
+#     I18n.locale = :es
+#
+# This would use the information in config/locales/es.yml.
+#
+# The following keys must be escaped otherwise they will not be retrieved by
+# the default I18n backend:
+#
+# true, false, on, off, yes, no
+#
+# Instead, surround them with single quotes.
+#
+# en:
+#   'true': "'foo'"
+#
+# To learn more, please read the Rails Internationalization guide
+# available at https://guides.rubyonrails.org/i18n.html.
+
+eu:
+    hello: "Kaixo Mundua!"
+    lang:
+        es: "Gaztelania"
+        en: "Ingelesa'"
+        eu: "Euskara"
+    time:
+        monday: "astelehena"
+        tuesday: "asteartea"
+        wednesday: "astezkena"
+        thursday: "osteguna"
+        friday: "ostirala"
+        saturday: "larunbata"
+        sunday: "igandea"
+        january: "urtarrila"
+        february: "otsaila"
+        march: "martxoa"
+        april: "apirila"
+        may: "maiatza"
+        june: "ekaina"
+        july: "uztaila"
+        august: "abuztua"
+        september: "iraila"
+        october: "urria"
+        november: "azaroa"
+        december: "abendua"
+    project_type:
+        development: "Software"
+        system: "Sistemak"
+        development_summary: "Software garapena"
+        system_summary: "Sistema muntaia"
+    url_type:
+        app_store: "App Store"
+        github: "Github"
+        website: "Webgune"
+        google_play: "Google Play"
+        live: "Ikusi"
+        app_store_summary: "App Storen ikusi"
+        github_summary: "Iturburu-kodea Github-n ikusi"
+        website_summary: "Webgunera joan"
+        google_play_summary: "Google Play-n ikusi"
+        live_summary: "Nabigatzailen egikaritu"
+    error:
+        code: "CODE"
+        error: "ERROR"
+        title: "Error"
+        try_solution: "Konponbide hauetako bat saiatu:"
+        error_400_title: "Bad request"
+        error_401_title: "Unauthorized"
+        error_403_title: "Forbidden"
+        error_404_title: "Not found"
+        error_500_title: "Server error"
+        error_xxx_title: "Unexpected error"
+        error_400_solution_0: "Aurreko orrialdera joan"
+        error_400_solution_1: "Orrialde nagusirara joan"
+        error_400_solution_2: "Ikusi katuten bideoak Youtuben "
+        error_401_solution_0: "Aurreko orrialdera joan"
+        error_401_solution_1: "Orrialde nagusirara joan"
+        error_401_solution_2: "Ikusi katuten bideoak Youtuben "
+        error_403_solution_0: "Aurreko orrialdera joan"
+        error_403_solution_1: "Orrialde nagusirara joan"
+        error_403_solution_2: "Ikusi katuten bideoak Youtuben "
+        error_404_solution_0: "Aurreko orrialdera joan"
+        error_404_solution_1: "Orrialde nagusirara joan"
+        error_404_solution_2: "Ikusi katuten bideoak Youtuben "
+        error_500_solution_0: "Aurreko orrialdera joan"
+        error_500_solution_1: "Orrialde nagusirara joan"
+        error_500_solution_2: "Ikusi katuten bideoak Youtuben "
+        error_xxx_solution_0: "Aurreko orrialdera joan"
+        error_xxx_solution_1: "Orrialde nagusirara joan"
+        error_xxx_solution_2: "Ikusi katuten bideoak Youtuben "
+        error_400_description: "Zerbitzaria ez du eskaera ulertu..."
+        error_401_description: "Behar ez duzun zerbait ikusten saiatzen ari zara."
+        error_403_description: "Behar ez duzun zerbait ikusten saiatzen ari zara"
+        error_404_description: "Bilatzen ari zaren orrialdea ez da existitzen unibertso honetan. Saiatu alternatibo batean. "
+        error_500_description: "Hau nire errua da, oraintxe saiatzen ari naiz konpontzen. "
+        error_xxx_description: "Zerbait gaizki dago ..."
+    header:
+        home: "Hasiera"
+        profile: "Ni"
+        projects: "Proiektuak"
+    footer:
+        copy: "Copyright %{name} 2014 - %{year}"
+        help: "Laguntza"
+        follow: "Jarrai nazazu!"
+        lang_es: "Mostrar en castellano"
+        lang_en: "Show in english"
+        lang_eu: "Euskaraz ikusi"
+    index:
+        profile: "Ni"
+        projects: "Proiektuak"
+        profile_cv: "Curriculum"
+        profile_more: "Niri buruz gehiago"
+        projects_all: "Proiektu denak ikusi"
+    profile:
+        resume: "Curriculum"
+        title: "Ni"
+        skills: "Trebetasunak"
+        resume_lang: "Otros idiomas"
+        description: "Beste hizkuntzak"
+        resume_printable: "Inprimatzeko formatua "
+        download_other: "Beste hizkuntzetan deskargatu"
+        download_current: "Deskargatu"
+        resume_es: "Gaztelanian ikusi"
+        resume_en: "Ingelesan ikusi"
+        resume_eu: "Euskaraz ikusi"
+    project:
+        info: "Xehetasunak"
+        tags: "Tags"
+        close: "Itxi"
+        title: "Proiektuak"
+        search: "Bilatu"
+        license: "Licentzia"
+        version: "Bertsioa"
+        description: "Deskribapena"
+        search_type: "Mota"
+        license_legal: "Lege-testua:"
+        search_license: "Licentzia"
+        license_summary: "Hitz gutxitan:"
+        search_advanced: "Bilaketa aurreratua"
+    share:
+        google: "Google +"
+        twitter: "Twitter"
+        facebook: "Facebook"
+        linkedin: "LinkedIn"
+        telegram: "Telegram"
+        vkontakte: "VKontakte"
+        google_summary: "Google+ -n banatu"
+        twitter_summary: "Twitter-n banatu"
+        facebook_summary: "Facebook-n banatu"
+        linkedin_summary: "LinkedIn-n banatu"
+        telegram_summary: "Telegram-n banatu"
+        vkontakte_summary: "VKontakte-n banatu"
+    social:
+        rss: "RSS"
+        mail: "eMail"
+        github: "Github"
+        linkedin: "LinkedIn"
+    tag:
+        js: "Javascript"
+        css: "CSS"
+        ios: "iOS"
+        php: "PHP"
+        web: "Web"
+        java: "Java"
+        html5: "HTML5"
+        mysql: "MySQL"
+        swift: "Swift"
+        sqlite: "SQLite"
+        android: "Android"
+    help:
+        about_title: "Webgune buruz"
+        about_text: "TODO"
+        privacy_title: "Priatutasuna"
+        privacy_text: "Egia esan, inori ez zaio gustatzen jarraipena izatea . Niri ez zaizkit gustatzen, horregatik ez zaitut jarraipena egiten .
+                       <br/><br/>
+                       Zuri buruz ahalik eta informazio gutxien biltzen saiatzen naiz. Hemen ez daude iragarkian, izen-emateak, email-harpidetzak, kanpoko zerbitzuak bisitak grabatzeko...
+                       <br/><br/>
+                       Si que mantengo unas estadísticas basicas sobre las visitas a este sitio, es algo que me resulta muy util. Para eso si que necesito almacenar tu dirección IP, y solo durante 72 horas. Despues, no tengo forma de volver a saberla.
+                       <br/><br/>
+                       Y ya está."
+        cookies_title: "Cookies"
+        cookies_text: "Siendo consecuente con el parrafo anterior....
+                       <br/><br/>... no hay cookies en este sitio.
+                       <br/><br/>:)"
+        license_title: "Licentzia"
+        license_text: "Primero lo malo: Hay algunos iconos (tiendas de aplicaciones, redes sociales, sitios web externos...) que, por supuesto, no son creación mía', y son propiedad de sus respectivos propietarios.
+                       <br/><br/>
+                       Pero para todo lo demás:
+                       <br/><br/>
+                       En la mayoría de proyectos encontrarás un apartado sobre la licencia, normalmente una GPL o Creative Commons. Para todo lo demás, se aplica la licencia <a rel='license' target='_blank' href='http://creativecommons.org/licenses/by-sa/4.0/'>Creative Commons Attribution-ShareAlike 4.0 International License</a>.
+                       <br/><br/>
+                       Lo que significa que puedes usar, modificar, y difundir estos contenidos y sus modificaciones, siempre que me menciones como fuente (por ejemplo, con un enlace a esta página) y mantengas la misma licencia."
+                       
+
+
+
+
+
+
+
+
+

+ 5 - 13
config/routes.rb

@@ -1,19 +1,11 @@
 Rails.application.routes.draw do
     scope '(:locale)', locale: /#{I18n.available_locales.join('|')}/ do
-        I18n.locale = :locale
-    end
-
-    if :locale == nil
-        locale = I18n.default_locale
     end
 
     root "main#index"
-    get "/:locale", to: "main#index", as: 'main'
-    get "/profile", to: "profile#index", as: 'profile'
-    get "/:locale/profile", to: "profile#index"
-    get "/projects", to: "projects#index"
-    get "/:locale/projects", to: "projects#index", as: 'project_index'
-    get "/projects/:permalink", to: "projects#show", as: 'project_show'
-    get "/:locale/projects/:permalink", to: "projects#show"
-    get "/help", to: "help#index"
+    get "/:locale", to: "main#index", defaults: { locale: I18n.locale }, as: "main"
+    get "/:locale/profile", to: "profile#index", defaults: { locale: I18n.locale }, as: "profile"
+    get "/:locale/projects", to: "projects#index", defaults: { locale: I18n.locale }, as: "project_index"
+    get "/:locale/projects/:permalink", to: "projects#show", defaults: { locale: I18n.locale }, as: 'project_show'
+    get "/:locale/help", to: "help#index", defaults: { locale: I18n.locale }, as: 'help'
 end

+ 0 - 18
db/migrate/20211212114959_dummy.rb

@@ -1,18 +0,0 @@
-class Dummy < ActiveRecord::Migration[6.1]
-  def change
-    create_table :projects do |t|
-      t.string :permalink
-      t.integer :priority
-      t.integer :nature
-      t.string :title
-      t.string :logo
-      t.string :header
-      t.text :text
-      t.references :license, null: false, foreign_key: true
-      t.references :user, null: false, foreign_key: true
-      t.integer :visibility
-
-      t.timestamps
-    end
-  end
-end

+ 12 - 0
db/migrate/20211213092427_create_social_links.rb

@@ -0,0 +1,12 @@
+class CreateSocialLinks < ActiveRecord::Migration[6.1]
+  def change
+    create_table :social_links do |t|
+      t.string :site_name
+      t.string :pattern
+      t.string :regexp
+      t.string :link_title
+
+      t.timestamps
+    end
+  end
+end

+ 12 - 0
db/migrate/20211213094550_create_user_social_links.rb

@@ -0,0 +1,12 @@
+class CreateUserSocialLinks < ActiveRecord::Migration[6.1]
+  def change
+    create_table :user_social_links do |t|
+      t.references :user, null: false, foreign_key: true
+      t.references :social_link, null: false, foreign_key: true
+      t.integer :priority
+      t.string :link
+
+      t.timestamps
+    end
+  end
+end

+ 13 - 0
db/migrate/20211213105552_create_resumes.rb

@@ -0,0 +1,13 @@
+class CreateResumes < ActiveRecord::Migration[6.1]
+  def change
+    create_table :resumes do |t|
+      t.references :user, null: false, foreign_key: true
+      t.string :language
+      t.integer :priority
+      t.boolean :printable
+      t.string :format
+
+      t.timestamps
+    end
+  end
+end

+ 35 - 1
db/schema.rb

@@ -10,7 +10,7 @@
 #
 # It's strongly recommended that you check this file into your version control system.
 
-ActiveRecord::Schema.define(version: 2021_12_12_114959) do
+ActiveRecord::Schema.define(version: 2021_12_13_105552) do
 
   create_table "active_storage_attachments", charset: "utf8mb4", force: :cascade do |t|
     t.string "name", null: false
@@ -92,6 +92,26 @@ ActiveRecord::Schema.define(version: 2021_12_12_114959) do
     t.index ["technology_id"], name: "index_projects_technologies_on_technology_id"
   end
 
+  create_table "resumes", charset: "utf8mb4", force: :cascade do |t|
+    t.bigint "user_id", null: false
+    t.string "language"
+    t.integer "priority"
+    t.boolean "printable"
+    t.string "format"
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+    t.index ["user_id"], name: "index_resumes_on_user_id"
+  end
+
+  create_table "social_links", charset: "utf8mb4", force: :cascade do |t|
+    t.string "site_name"
+    t.string "pattern"
+    t.string "regexp"
+    t.string "link_title"
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+  end
+
   create_table "tags", charset: "utf8mb4", force: :cascade do |t|
     t.bigint "project_id", null: false
     t.string "tag"
@@ -132,6 +152,17 @@ ActiveRecord::Schema.define(version: 2021_12_12_114959) do
     t.datetime "updated_at", precision: 6, null: false
   end
 
+  create_table "user_social_links", charset: "utf8mb4", force: :cascade do |t|
+    t.bigint "user_id", null: false
+    t.bigint "social_link_id", null: false
+    t.integer "priority"
+    t.string "link"
+    t.datetime "created_at", precision: 6, null: false
+    t.datetime "updated_at", precision: 6, null: false
+    t.index ["social_link_id"], name: "index_user_social_links_on_social_link_id"
+    t.index ["user_id"], name: "index_user_social_links_on_user_id"
+  end
+
   create_table "users", charset: "utf8mb4", force: :cascade do |t|
     t.string "username"
     t.string "full_name"
@@ -154,6 +185,9 @@ ActiveRecord::Schema.define(version: 2021_12_12_114959) do
   add_foreign_key "mail_adresses", "users"
   add_foreign_key "projects", "licenses"
   add_foreign_key "projects", "users"
+  add_foreign_key "resumes", "users"
   add_foreign_key "tags", "projects"
   add_foreign_key "texts", "users"
+  add_foreign_key "user_social_links", "social_links"
+  add_foreign_key "user_social_links", "users"
 end

BIN
public/fonts/Latin-Modern-Mono-Light-Bold.otf


BIN
public/fonts/Nunito-Bold.ttf


BIN
public/fonts/Nunito-Light.ttf


BIN
public/fonts/Nunito-Regular.ttf


+ 93 - 0
public/fonts/OFL.txt

@@ -0,0 +1,93 @@
+Copyright (c) 2011, Vernon Adams (vern@newtypography.co.uk),
+with Reserved Font Name Nunito.
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded, 
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.

+ 7 - 0
test/controllers/help_controller_test.rb

@@ -0,0 +1,7 @@
+require "test_helper"
+
+class HelpControllerTest < ActionDispatch::IntegrationTest
+  # test "the truth" do
+  #   assert true
+  # end
+end

+ 15 - 0
test/fixtures/resumes.yml

@@ -0,0 +1,15 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  user: one
+  language: MyString
+  priority: 1
+  printable: false
+  format: MyString
+
+two:
+  user: two
+  language: MyString
+  priority: 1
+  printable: false
+  format: MyString

+ 13 - 0
test/fixtures/social_links.yml

@@ -0,0 +1,13 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  site_name: MyString
+  pattern: MyString
+  regexp: MyString
+  link_title: MyString
+
+two:
+  site_name: MyString
+  pattern: MyString
+  regexp: MyString
+  link_title: MyString

+ 13 - 0
test/fixtures/user_social_links.yml

@@ -0,0 +1,13 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+  user: one
+  social_link: one
+  priority: 1
+  link: MyString
+
+two:
+  user: two
+  social_link: two
+  priority: 1
+  link: MyString

+ 7 - 0
test/models/resume_test.rb

@@ -0,0 +1,7 @@
+require "test_helper"
+
+class ResumeTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end

+ 7 - 0
test/models/social_link_test.rb

@@ -0,0 +1,7 @@
+require "test_helper"
+
+class SocialLinkTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end

+ 7 - 0
test/models/user_social_link_test.rb

@@ -0,0 +1,7 @@
+require "test_helper"
+
+class UserSocialLinkTest < ActiveSupport::TestCase
+  # test "the truth" do
+  #   assert true
+  # end
+end