mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-05-26 09:50:08 -04:00
Compare commits
2 Commits
dev
...
feature/se
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7bb632c3c1 | ||
|
|
80e724fefe |
@@ -30,3 +30,44 @@ if (document.getElementById("membermap") !== null) {
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
$(document).on('click', '#find-me', function(e) {
|
||||
e.preventDefault();
|
||||
if (navigator.geolocation) {
|
||||
navigator.geolocation.getCurrentPosition(function(position) {
|
||||
$('#member_latitude').val(position.coords.latitude);
|
||||
$('#member_longitude').val(position.coords.longitude);
|
||||
updateMap(position.coords.latitude, position.coords.longitude);
|
||||
});
|
||||
} else {
|
||||
alert("Geolocation is not supported by this browser.");
|
||||
}
|
||||
});
|
||||
|
||||
if (document.getElementById("map") !== null) {
|
||||
var map = L.map('map').setView([0, 0], 2);
|
||||
var marker;
|
||||
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
|
||||
maxZoom: 18
|
||||
}).addTo(map);
|
||||
|
||||
map.on('click', function(e) {
|
||||
updateMarker(e.latlng);
|
||||
$('#member_latitude').val(e.latlng.lat);
|
||||
$('#member_longitude').val(e.latlng.lng);
|
||||
});
|
||||
|
||||
function updateMarker(latlng) {
|
||||
if (marker) {
|
||||
map.removeLayer(marker);
|
||||
}
|
||||
marker = L.marker(latlng).addTo(map);
|
||||
}
|
||||
|
||||
function updateMap(lat, lng) {
|
||||
map.setView([lat, lng], 13);
|
||||
updateMarker(L.latLng(lat, lng));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class MembersController < ApplicationController
|
||||
load_and_authorize_resource except: %i(finish_signup unsubscribe view_follows view_followers show)
|
||||
load_and_authorize_resource except: %i(finish_signup unsubscribe view_follows view_followers show set_location update_location)
|
||||
skip_authorize_resource only: %i(nearby unsubscribe finish_signup)
|
||||
respond_to :html, :json, :rss
|
||||
|
||||
@@ -86,6 +86,36 @@ class MembersController < ApplicationController
|
||||
end
|
||||
end
|
||||
|
||||
def set_location
|
||||
@member = Member.find_by_slug!(params[:id])
|
||||
authorize! :update, @member
|
||||
end
|
||||
|
||||
def update_location
|
||||
@member = Member.find_by_slug!(params[:id])
|
||||
authorize! :update, @member
|
||||
|
||||
if params[:member][:latitude].present? && params[:member][:longitude].present?
|
||||
lat = params[:member][:latitude].to_f.round(2)
|
||||
lng = params[:member][:longitude].to_f.round(2)
|
||||
params[:member][:latitude] = lat
|
||||
params[:member][:longitude] = lng
|
||||
|
||||
results = Geocoder.search([lat, lng])
|
||||
if results.first
|
||||
params[:member][:location] = results.first.city || results.first.town || results.first.village || results.first.hamlet
|
||||
else
|
||||
params[:member][:location] = "Location near #{lat}, #{lng}"
|
||||
end
|
||||
end
|
||||
|
||||
if @member.update(member_params)
|
||||
redirect_to member_path(@member), notice: 'Location updated.'
|
||||
else
|
||||
render :set_location
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
EMAIL_TYPE_STRING = {
|
||||
@@ -95,7 +125,7 @@ class MembersController < ApplicationController
|
||||
}.freeze
|
||||
|
||||
def member_params
|
||||
params.require(:member).permit(:login_name, :tos_agreement, :email, :newsletter, :send_harvest_reminder)
|
||||
params.require(:member).permit(:login_name, :tos_agreement, :email, :newsletter, :location, :latitude, :longitude, :send_harvest_reminder)
|
||||
end
|
||||
|
||||
def member_json_fields
|
||||
|
||||
23
app/views/members/set_location.html.haml
Normal file
23
app/views/members/set_location.html.haml
Normal file
@@ -0,0 +1,23 @@
|
||||
- content_for :title, "Set your location"
|
||||
|
||||
%h1 Set your location
|
||||
|
||||
= form_for @member, url: update_location_member_path(@member), method: :put do |f|
|
||||
.form-group
|
||||
= f.label :location
|
||||
= f.text_field :location, class: 'form-control'
|
||||
|
||||
.form-group
|
||||
= f.label :latitude
|
||||
= f.text_field :latitude, class: 'form-control', readonly: true
|
||||
|
||||
.form-group
|
||||
= f.label :longitude
|
||||
= f.text_field :longitude, class: 'form-control', readonly: true
|
||||
|
||||
#map.set-location-map
|
||||
|
||||
.form-group
|
||||
%button#find-me.btn.btn-default Find my location
|
||||
|
||||
= f.submit 'Update location', class: 'btn btn-primary'
|
||||
@@ -65,6 +65,9 @@
|
||||
= link_to edit_member_registration_path, class: 'btn btn-block' do
|
||||
= member_icon
|
||||
= t('members.edit_profile')
|
||||
= link_to set_location_member_path(@member), class: 'btn btn-block' do
|
||||
= icon('fas', 'map-marker')
|
||||
Set location
|
||||
|
||||
- if can?(:create, Notification) && current_member != @member
|
||||
= link_to new_message_path(recipient_id: @member.id), class: 'btn btn-block' do
|
||||
|
||||
@@ -113,6 +113,10 @@ Rails.application.routes.draw do
|
||||
resources :timeline
|
||||
|
||||
resources :members, param: :slug do
|
||||
member do
|
||||
get :set_location
|
||||
put :update_location
|
||||
end
|
||||
resources :gardens
|
||||
resources :seeds
|
||||
resources :plantings
|
||||
|
||||
83
spec/features/members/set_location_spec.rb
Normal file
83
spec/features/members/set_location_spec.rb
Normal file
@@ -0,0 +1,83 @@
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.feature 'Set location', type: :feature do
|
||||
let(:member) { FactoryBot.create(:member) }
|
||||
|
||||
before do
|
||||
login_as(member, scope: :member)
|
||||
end
|
||||
|
||||
scenario 'member sets their location by clicking on the map', js: true do
|
||||
visit set_location_member_path(member)
|
||||
|
||||
# Test clicking on the map
|
||||
page.execute_script("map.fire('click', { latlng: L.latLng(40.7128, -74.0060) })")
|
||||
expect(find('#member_latitude').value).to eq('40.7128')
|
||||
expect(find('#member_longitude').value).to eq('-74.006')
|
||||
|
||||
# Mock geocoding
|
||||
geocoder_result = instance_double('Geocoder::Result::Nominatim',
|
||||
city: 'New York',
|
||||
town: nil,
|
||||
village: nil,
|
||||
hamlet: nil)
|
||||
allow(Geocoder).to receive(:search).with([40.71, -74.01]).and_return([geocoder_result])
|
||||
|
||||
click_button 'Update location'
|
||||
|
||||
expect(page).to have_content('Location updated.')
|
||||
member.reload
|
||||
expect(member.location).to eq('New York')
|
||||
expect(member.latitude).to eq(40.71)
|
||||
expect(member.longitude).to eq(-74.01)
|
||||
end
|
||||
|
||||
scenario 'member uses "Find my location"', js: true do
|
||||
visit set_location_member_path(member)
|
||||
|
||||
# Mock browser's geolocation
|
||||
page.execute_script("
|
||||
navigator.geolocation.getCurrentPosition = function(success) {
|
||||
var position = { coords: { latitude: 34.0522, longitude: -118.2437 } };
|
||||
success(position);
|
||||
}
|
||||
")
|
||||
|
||||
click_button 'Find my location'
|
||||
|
||||
expect(find('#member_latitude').value).to eq('34.0522')
|
||||
expect(find('#member_longitude').value).to eq('-118.2437')
|
||||
|
||||
# Mock geocoding
|
||||
geocoder_result = instance_double('Geocoder::Result::Nominatim',
|
||||
city: 'Los Angeles',
|
||||
town: nil,
|
||||
village: nil,
|
||||
hamlet: nil)
|
||||
allow(Geocoder).to receive(:search).with([34.05, -118.24]).and_return([geocoder_result])
|
||||
|
||||
click_button 'Update location'
|
||||
|
||||
expect(page).to have_content('Location updated.')
|
||||
member.reload
|
||||
expect(member.location).to eq('Los Angeles')
|
||||
expect(member.latitude).to eq(34.05)
|
||||
expect(member.longitude).to eq(-118.24)
|
||||
end
|
||||
|
||||
scenario 'geocoding fails', js: true do
|
||||
visit set_location_member_path(member)
|
||||
|
||||
page.execute_script("map.fire('click', { latlng: L.latLng(1.2345, 6.7890) })")
|
||||
|
||||
allow(Geocoder).to receive(:search).with([1.23, 6.79]).and_return([])
|
||||
|
||||
click_button 'Update location'
|
||||
|
||||
expect(page).to have_content('Location updated.')
|
||||
member.reload
|
||||
expect(member.location).to eq('Location near 1.23, 6.79')
|
||||
expect(member.latitude).to eq(1.23)
|
||||
expect(member.longitude).to eq(6.79)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user