diff --git a/api/app/controllers/clubs_controller.rb b/api/app/controllers/clubs_controller.rb
index f9d5305..dd7828c 100644
--- a/api/app/controllers/clubs_controller.rb
+++ b/api/app/controllers/clubs_controller.rb
@@ -28,7 +28,7 @@ def set_club
end
def club_params
- params.permit(:name, :address, :schedule, :image)
+ params.permit(:name, :address, :schedule, :image, :district, :latitude, :longitude)
end
end
diff --git a/api/app/serializers/club_serializer.rb b/api/app/serializers/club_serializer.rb
index 27591cd..6355f8b 100644
--- a/api/app/serializers/club_serializer.rb
+++ b/api/app/serializers/club_serializer.rb
@@ -1,7 +1,7 @@
class ClubSerializer < ActiveModel::Serializer
include Rails.application.routes.url_helpers
- attributes :id, :name, :address, :image, :schedule, :favorited, :favorited_count
+ attributes :id, :name, :address, :image, :schedule, :favorited, :favorited_count, :district, :latitude, :longitude
def image
# rails_blob_path(object.image, only_path: true) if object.image.attached?
diff --git a/api/db/migrate/20190715215722_add_district_to_clubs.rb b/api/db/migrate/20190715215722_add_district_to_clubs.rb
new file mode 100644
index 0000000..5c232a5
--- /dev/null
+++ b/api/db/migrate/20190715215722_add_district_to_clubs.rb
@@ -0,0 +1,7 @@
+class AddDistrictToClubs < ActiveRecord::Migration[5.2]
+ def change
+ add_column :clubs, :district, :string
+ add_column :clubs, :latitude, :string
+ add_column :clubs, :longitude, :string
+ end
+end
diff --git a/api/db/schema.rb b/api/db/schema.rb
index 34e40c0..f52b1ec 100644
--- a/api/db/schema.rb
+++ b/api/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: 2019_07_15_153026) do
+ActiveRecord::Schema.define(version: 2019_07_15_215722) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -42,6 +42,9 @@
t.json "schedule"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.string "district"
+ t.string "latitude"
+ t.string "longitude"
end
create_table "favorites", force: :cascade do |t|
diff --git a/api/db/seeds.rb b/api/db/seeds.rb
index 35c8a46..4ecbab7 100644
--- a/api/db/seeds.rb
+++ b/api/db/seeds.rb
@@ -3,7 +3,7 @@
regular_user = User.create(name: 'Lian Nivin', email: 'liam@kampu.pe', role: "regular", password: '123456')
owner_user = User.create(name: 'Cristian Berly', email: 'berli@kampu.pe', role: "owner", password: '123456')
-Club.create([{name: "Club #1", address: 'Jr cayumba 440',
+clubs = Club.create([{name: "Club #1", address: 'Jr cayumba 440', district: "Lince", latitude: -12.1199378, longitude: -77.0373161,
schedule: {
'monday-friday': {
start: '8',
@@ -17,7 +17,7 @@
start: '8',
end: '22'
},
-}}, {name: "Club #2", address: 'Jr cayumba 440',
+}}, {name: "Club #2", address: 'Av. Jorge Chavez 184', district: "Miraflores", latitude: -13.1199378, longitude: -77.0353161,
schedule: {
'monday-friday': {
start: '8',
@@ -31,7 +31,7 @@
start: '8',
end: '22'
},
-}}, {name: "Club #3", address: 'Jr cayumba 440',
+}}, {name: "Club #3", address: 'Jr General Artigas 440', district: "Pueblo Libre", latitude: -14.1199378, longitude: -77.0373261,
schedule: {
'monday-friday': {
start: '8',
@@ -53,7 +53,7 @@
Club.create(
name: 'Club golden',
- address: 'Jr cayumba 440',
+ address: 'Jr Something 123', district: "Cercado de Lima", latitude: -12.0641388, longitude: -77.0358862,
schedule: {
'monday-friday': {
start: '8',
diff --git a/client/.env.example b/client/.env.example
index 45a40a2..8a456c0 100644
--- a/client/.env.example
+++ b/client/.env.example
@@ -1,3 +1,4 @@
REACT_APP_VERSION=$npm_package_version
REACT_APP_API_URL=http://localhost:4000/api
REACT_APP_API_URL_PRODUCTION=
+REACT_APP_OPEN_CAGE_DATA_KEY=
diff --git a/client/package.json b/client/package.json
index 30d020a..8567028 100644
--- a/client/package.json
+++ b/client/package.json
@@ -6,6 +6,7 @@
"@emotion/core": "^10.0.10",
"@reach/router": "^1.2.1",
"@testing-library/react": "^8.0.1",
+ "geolib": "^3.0.4",
"jest-emotion": "^10.0.11",
"jest-fetch-mock": "^2.1.2",
"leaflet": "^1.5.1",
diff --git a/client/src/components/club-card.js b/client/src/components/club-card.js
new file mode 100644
index 0000000..e877c86
--- /dev/null
+++ b/client/src/components/club-card.js
@@ -0,0 +1,22 @@
+/** @jsx jsx */
+import React from "react";
+import { jsx } from "@emotion/core";
+import { Card, Title } from "../components/ui";
+
+function ClubCard({ club }) {
+ const styleCard = {
+ maxWidth: "100%",
+ marginBottom: "1.5em"
+ };
+
+ return (
+
+ {club.name}
+ {JSON.stringify(club)}
+ {club.position}
+ {club.distance !== 0 ? `${club.distance / 1000.0}km` : null}
+
+ );
+}
+
+export default ClubCard;
diff --git a/client/src/components/club.js b/client/src/components/club.js
index c7fc41b..5bff71a 100644
--- a/client/src/components/club.js
+++ b/client/src/components/club.js
@@ -2,7 +2,7 @@
import React from "react";
import { jsx } from "@emotion/core";
import { Card } from "./ui";
-import { Heart } from "./icons";
+import { Heart, MapPin } from "./icons";
import { favorite, unfavorite } from "../services/club";
import { useSetFavorite, useSetUnfavorite } from "../actions/action-hooks";
@@ -16,6 +16,12 @@ function Club({ club }) {
color: "tomato"
};
+ const styleMapPin = {
+ cursor: "pointer",
+ color: "#414141",
+ marginLeft: "auto"
+ };
+
async function handleClick() {
if (club.favorited) {
setFavorite(await unfavorite(club.id));
@@ -69,6 +75,10 @@ function Club({ club }) {
>
{club.favorited_count > 0 && club.favorited_count}
+
+
+ {club.distance !== 0 ? `${club.distance / 1000.0}km` : null}
+
diff --git a/client/src/components/icons.js b/client/src/components/icons.js
index 8693830..4858d21 100644
--- a/client/src/components/icons.js
+++ b/client/src/components/icons.js
@@ -19,4 +19,24 @@ function Heart(props) {
);
}
-export { Heart };
+function MapPin(props) {
+ return (
+
+ );
+}
+
+export { Heart, MapPin };
diff --git a/client/src/services/geocode.js b/client/src/services/geocode.js
new file mode 100644
index 0000000..94fdd13
--- /dev/null
+++ b/client/src/services/geocode.js
@@ -0,0 +1,21 @@
+async function getCoords(place) {
+ let apikey = process.env.REACT_APP_OPEN_CAGE_DATA_KEY;
+ let api_url = "https://api.opencagedata.com/geocode/v1/json";
+ let request_url =
+ api_url +
+ "?" +
+ "q=" +
+ encodeURIComponent(place) +
+ "&key=" +
+ apikey +
+ "&language=es" +
+ "&pretty=1" +
+ "&countrycode=pe" +
+ "&no_annotations=1";
+ const response = await fetch(request_url);
+
+ if (!response.ok) throw new Error(response.statusText);
+ return response.json();
+}
+
+export { getCoords };
diff --git a/client/src/views/create-club.js b/client/src/views/create-club.js
index 95dd474..4991c88 100644
--- a/client/src/views/create-club.js
+++ b/client/src/views/create-club.js
@@ -4,11 +4,13 @@ import { jsx } from "@emotion/core";
import { navigate } from "@reach/router";
import { Input, Label, Card, Button } from "../components/ui";
import { postClub } from "../services/club";
+import { getCoords } from "../services/geocode";
function CreateClub() {
const [fields, setFields] = React.useState({
name: "",
address: "",
+ district: "",
image: null,
schedule: JSON.stringify({
"monday-friday": {
@@ -41,10 +43,15 @@ function CreateClub() {
Object.keys(fields).forEach(key => {
formData.append(key, fields[key]);
});
+ const { results } = await getCoords(
+ `${fields.address}, ${fields.district}`
+ );
+ formData.append("latitude", results[0].geometry.lat);
+ formData.append("longitude", results[0].geometry.lng);
+
try {
- const club = await postClub(formData);
+ await postClub(formData);
navigate("/owner");
- console.log(club);
} catch (error) {
console.log(error.message);
}
@@ -86,6 +93,20 @@ function CreateClub() {
onChange={handleChange}
/>
+
+
+
+
{
- setLoading(true);
getClubs().then(clubs => {
setClubs(clubs);
- setLoading(false);
});
- }, []);
+ }, [setClubs]);
+
+ function setDistance(clubPosition, position) {
+ return getDistance(
+ { latitude: position[0], longitude: position[1] },
+ {
+ latitude: parseFloat(clubPosition.latitude),
+ longitude: parseFloat(clubPosition.longitude)
+ }
+ );
+ }
+
+ React.useEffect(() => {
+ const watchID = navigator.geolocation.watchPosition(pos => {
+ setPosition([pos.coords.latitude, pos.coords.longitude]);
+ });
+ return () => {
+ navigator.geolocation.clearWatch(watchID);
+ };
+ }, [setPosition]);
+
+ function handleChangeLocation(e) {
+ console.log(e.target.value);
+ setSelectedLocation(e.target.value);
+ }
+
+ function handleChangeSortType(e) {
+ console.log(e.target.value);
+ setSortType(e.target.value);
+ }
+
+ function sortBy(a, b) {
+ switch (sortType) {
+ case "location":
+ return a.distance - b.distance;
+
+ case "favorites":
+ return b.favorited_count - a.favorited_count;
+
+ case "name":
+ return a.name - b.name;
+
+ default:
+ break;
+ }
+ }
+
+ const styleSelectsContainer = {
+ display: "flex",
+ justifyContent: "space-between",
+ marginBottom: "1em"
+ };
return (
-
Filters
- {loading &&
Loading
}
- {clubs.map(club => (
-
- ))}
+
+
+
+
+
+ {clubs ? (
+ clubs
+ .map(club => {
+ let distance = 0;
+ if (club.latitude == null || club.longitude == null) {
+ distance = 0;
+ } else if (position[0] !== 0) {
+ distance = setDistance(club, position);
+ }
+ club.distance = distance;
+ console.log(club);
+ return club;
+ })
+ .sort(sortBy)
+ .map(club => {
+ return
;
+ })
+ ) : (
+
Loading...
+ )}
);
}
diff --git a/client/yarn.lock b/client/yarn.lock
index 0294157..bea4608 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -4374,6 +4374,11 @@ gauge@~2.7.3:
strip-ansi "^3.0.1"
wide-align "^1.1.0"
+geolib@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/geolib/-/geolib-3.0.4.tgz#63fd82cf4311f08cadc142aaa73a0941844266d1"
+ integrity sha512-IpbpPdfuVdjj2T909H0Kj0Crp0he+xfFYX6e1Wlvo5L2OVkfnfvpTLp9k0VYuu5ObbWhQ/TI2VKNsrAokss5vA==
+
get-caller-file@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"