-
%
-
-
-
{{ photoPercent }}
-
{{ $t('profile.dashboard.all-photos') }}
-
+
+
+
{{ photoPercent }}%
+
{{ $t('profile.dashboard.all-photos') }}
+
-
-
%
-
-
-
{{ tagPercent }}
-
{{ $t('profile.dashboard.all-tags') }}
-
+
+
+
{{ tagPercent }}%
+
{{ $t('profile.dashboard.all-tags') }}
@@ -46,53 +40,29 @@
diff --git a/resources/js/components/Profile/top/ProfileWelcome.vue b/resources/js/components/Profile/top/ProfileWelcome.vue
deleted file mode 100644
index a5c494d1f..000000000
--- a/resources/js/components/Profile/top/ProfileWelcome.vue
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
{{ $t('profile.dashboard.welcome') }}, {{ name }}
-
-
{{ $t('profile.dashboard.out-of', {total: totalUsers} ) }}
-
{{ $t('profile.dashboard.rank', { rank: usersPosition } ) }}
-
-
-
-
-
-
diff --git a/resources/js/components/ProfileChart.vue b/resources/js/components/ProfileChart.vue
deleted file mode 100644
index 50c278d9e..000000000
--- a/resources/js/components/ProfileChart.vue
+++ /dev/null
@@ -1,73 +0,0 @@
-
diff --git a/resources/js/langs/de/settings/common.json b/resources/js/langs/de/settings/common.json
index 772ffe02a..a5183c0f8 100644
--- a/resources/js/langs/de/settings/common.json
+++ b/resources/js/langs/de/settings/common.json
@@ -9,5 +9,7 @@
"presence": "Presence",
"emails": "Emails",
"show-flag": "Show Flag",
- "teams": "Teams"
+ "teams": "Teams",
+ "public-profile": "Public Profile",
+ "social-media": "Social Media"
}
diff --git a/resources/js/langs/en/settings/common.json b/resources/js/langs/en/settings/common.json
index 772ffe02a..a5183c0f8 100644
--- a/resources/js/langs/en/settings/common.json
+++ b/resources/js/langs/en/settings/common.json
@@ -9,5 +9,7 @@
"presence": "Presence",
"emails": "Emails",
"show-flag": "Show Flag",
- "teams": "Teams"
+ "teams": "Teams",
+ "public-profile": "Public Profile",
+ "social-media": "Social Media"
}
diff --git a/resources/js/langs/es/settings/common.json b/resources/js/langs/es/settings/common.json
index 3632d740e..ff09258f4 100644
--- a/resources/js/langs/es/settings/common.json
+++ b/resources/js/langs/es/settings/common.json
@@ -9,5 +9,7 @@
"presence": "Presencia",
"emails": "Corres electrónicos",
"show-flag": "Mostrar bandera",
- "teams": "Equipos"
+ "teams": "Equipos",
+ "public-profile": "Public Profile",
+ "social-media": "Social Media"
}
diff --git a/resources/js/langs/nl/settings/common.json b/resources/js/langs/nl/settings/common.json
index 73f3d4bf9..932451515 100644
--- a/resources/js/langs/nl/settings/common.json
+++ b/resources/js/langs/nl/settings/common.json
@@ -9,5 +9,7 @@
"presence": "Aanwezigheid",
"emails": "Emails",
"show-flag": "Toon vlag",
- "teams": "Teams"
-}
\ No newline at end of file
+ "teams": "Teams",
+ "public-profile": "Public Profile",
+ "social-media": "Social Media"
+}
diff --git a/resources/js/langs/pl/settings/common.json b/resources/js/langs/pl/settings/common.json
index 3838a83c9..478e2cffc 100644
--- a/resources/js/langs/pl/settings/common.json
+++ b/resources/js/langs/pl/settings/common.json
@@ -9,5 +9,7 @@
"presence": "Obecność",
"emails": "E-maile",
"show-flag": "Pokaż flage",
- "teams": "Drużyny"
+ "teams": "Drużyny",
+ "public-profile": "Public Profile",
+ "social-media": "Social Media"
}
diff --git a/resources/js/routes.js b/resources/js/routes.js
index 2c4fa778f..73ef719f3 100644
--- a/resources/js/routes.js
+++ b/resources/js/routes.js
@@ -9,10 +9,8 @@ import can_verify_boxes from './middleware/can_verify_boxes'
import middlewarePipeline from './middleware/middlewarePipeline'
-// The earlier a route is defined, the higher its priority.
const router = new VueRouter({
mode: 'history',
- // base: process.env.BASE_URL, // not sure if we need this?
linkActiveClass: 'is-active',
routes: [
// GUEST ROUTES
@@ -113,13 +111,6 @@ const router = new VueRouter({
middleware: [ auth ]
}
},
- {
- path: '/submit', // old route
- component: require('./views/general/Upload').default,
- meta: {
- middleware: [ auth ]
- }
- },
{
path: '/tag',
component: require('./views/general/Tag').default,
@@ -154,40 +145,44 @@ const router = new VueRouter({
},
{
path: 'details',
- component: require('./views/settings/Details').default,
+ component: require('./views/Settings/Details').default,
},
{
path: 'account',
- component: require('./views/settings/Account').default,
+ component: require('./views/Settings/Account').default,
},
{
path: 'payments',
- component: require('./views/settings/Payments').default,
+ component: require('./views/Settings/Payments').default,
},
{
path: 'privacy',
- component: require('./views/settings/Privacy').default,
+ component: require('./views/Settings/Privacy').default,
},
{
path: 'littercoin',
- component: require('./views/settings/Littercoin').default,
+ component: require('./views/Settings/Littercoin').default,
},
{
path: 'presence',
- component: require('./views/settings/Presence').default,
+ component: require('./views/Settings/Presence').default,
},
{
path: 'emails',
- component: require('./views/settings/Emails').default,
+ component: require('./views/Settings/Emails').default,
},
{
path: 'show-flag',
- component: require('./views/settings/GlobalFlag').default,
+ component: require('./views/Settings/GlobalFlag').default,
},
- // {
- // path: 'phone',
- // component: require('./views/Phone').default
- // }
+ {
+ path: 'public-profile',
+ component: require('./views/Settings/PublicProfile').default
+ },
+ {
+ path: 'social-media',
+ component: require('./views/Settings/SocialMediaIntegration').default
+ }
]
},
{
@@ -203,6 +198,11 @@ const router = new VueRouter({
meta: {
middleware: [ auth, can_verify_boxes ]
}
+ },
+ // Public Profile by Username
+ {
+ path: '/:username?',
+ component: require('./views/general/Profile').default,
}
]
});
@@ -212,7 +212,7 @@ const router = new VueRouter({
*/
router.beforeEach((to, from, next) => {
- if (! to.meta.middleware) return next();
+ if (!to.meta.middleware) return next();
// testing --- this allows store to init before router finishes and returns with auth false
// await store.dispatch('CHECK_AUTH');
diff --git a/resources/js/store/modules/user/actions.js b/resources/js/store/modules/user/actions.js
index ffb0f8792..aa6a8066c 100644
--- a/resources/js/store/modules/user/actions.js
+++ b/resources/js/store/modules/user/actions.js
@@ -165,15 +165,15 @@ export const actions = {
async GET_CURRENT_USER (context)
{
await axios.get('/current-user')
- .then(response => {
- console.log('get_current_user', response);
+ .then(response => {
+ console.log('get_current_user', response);
- context.commit('initUser', response.data);
- context.commit('set_default_litter_presence', response.data.items_remaining);
- })
- .catch(error => {
- console.log('error.get_current_user', error);
- });
+ context.commit('initUser', response.data);
+ context.commit('set_default_litter_presence', response.data.items_remaining);
+ })
+ .catch(error => {
+ console.log('error.get_current_user', error);
+ });
},
/**
@@ -199,33 +199,62 @@ export const actions = {
*/
async GET_USERS_PROFILE_DATA (context)
{
- await axios.get('/user/profile/index')
- .then(response => {
- console.log('get_users_position', response);
+ const username = context.state.public_profile.publicProfile.username;
- context.commit('usersPosition', response.data);
- })
- .catch(error => {
- console.error('get_users_position', error);
- });
+ await axios.get('/user/profile/index', {
+ params: {
+ username
+ }
+ })
+ .then(response => {
+ console.log('get_users_position', response);
+
+ context.commit('usersPosition', response.data);
+ })
+ .catch(error => {
+ console.error('get_users_position', error);
+ });
},
/**
* Get the geojson data for the users Profile/ProfileMap
+ *
+ * This can be for the currently authenticated user, or a public profile
*/
async GET_USERS_PROFILE_MAP_DATA (context, payload)
{
- await axios.get('/user/profile/map', {
+ const url = (context.state.public_profile.publicProfile)
+ ? '/user/public-profile/map'
+ : '/user/profile/map';
+
+ const username = context.state.public_profile.publicProfile.hasOwnProperty('username')
+ ? context.state.public_profile.publicProfile.username
+ : null;
+
+ const title = i18n.t('notifications.success');
+ const body = "Map data updated";
+
+ await axios.get(url, {
params: {
period: payload.period,
start: payload.start + ' 00:00:00',
- end: payload.end + ' 23:59:59'
+ end: payload.end + ' 23:59:59',
+ username
}
})
.then(response => {
console.log('get_users_profile_map_data', response);
- context.commit('usersGeojson', response.data.geojson);
+ if (response.data.success)
+ {
+ Vue.$vToastify.success({
+ title,
+ body,
+ position: 'top-right'
+ });
+
+ context.commit('usersGeojson', response.data.geojson);
+ }
})
.catch(error => {
console.error('get_users_profile_map_data', error);
@@ -354,8 +383,8 @@ export const actions = {
*/
async TOGGLE_LITTER_PICKED_UP_SETTING (context)
{
- let title = i18n.t('notifications.success');
- let body = i18n.t('notifications.litter-toggled');
+ const title = i18n.t('notifications.success');
+ const body = i18n.t('notifications.litter-toggled');
await axios.post('/settings/toggle')
.then(response => {
@@ -378,13 +407,44 @@ export const actions = {
});
},
+ /**
+ * Toggle the privacy status of the users dashboard
+ */
+ async TOGGLE_PUBLIC_PROFILE (context)
+ {
+ const title = i18n.t('notifications.success');
+
+ const nowPublic = "Your Profile is now public";
+ const nowPrivate = "Your Profile is now private";
+
+ await axios.post('/settings/public-profile/toggle')
+ .then(response => {
+ console.log('toggle_public_profile', response);
+
+ if (response.data.success)
+ {
+ context.commit('updateUserSettings', response.data.settings);
+
+ Vue.$vToastify.success({
+ title,
+ body: (response.data.settings.show_public_profile)
+ ? nowPublic
+ : nowPrivate,
+ position: 'top-right'
+ });
+ }
+ })
+ .catch(error => {
+ console.error('toggle_public_profile', error);
+ });
+ },
+
/**
* The user wants to update name, email, username
*/
async UPDATE_DETAILS (context)
{
const title = i18n.t('notifications.success');
- // todo - translate this
const body = 'Your information has been updated'
await axios.post('/settings/details', {
@@ -395,7 +455,6 @@ export const actions = {
.then(response => {
console.log('update_details', response);
- /* improve this */
Vue.$vToastify.success({
title,
body,
@@ -403,7 +462,7 @@ export const actions = {
});
})
.catch(error => {
- console.log('error.update_details', error);
+ console.error('update_details', error);
// update errors. user.js
context.commit('errors', error.response.data.errors);
@@ -415,16 +474,15 @@ export const actions = {
*/
async UPDATE_GLOBAL_FLAG (context, payload)
{
- let title = i18n.t('notifications.success');
- let body = i18n.t('notifications.settings.flag-updated');
+ const title = i18n.t('notifications.success');
+ const body = i18n.t('notifications.settings.flag-updated');
await axios.post('/settings/save-flag', {
country: payload
})
.then(response => {
- console.log(response);
+ console.log('update_global_flag', response);
- /* improve this */
Vue.$vToastify.success({
title,
body,
@@ -432,7 +490,65 @@ export const actions = {
});
})
.catch(error => {
- console.log(error);
+ console.log('update_global_flag', error);
+ });
+ },
+
+ /**
+ * Update the settings of the users public profile
+ */
+ async UPDATE_PUBLIC_PROFILE_SETTINGS (context)
+ {
+ const title = i18n.t('notifications.success');
+ const body = "Your settings have been updated";
+
+ await axios.post('/settings/public-profile/update', {
+ map: context.state.user.settings.map,
+ download: context.state.user.settings.download,
+ })
+ .then(response => {
+ console.log('update_public_profile_settings', response);
+
+ if (response.data.success)
+ {
+ Vue.$vToastify.success({
+ title,
+ body,
+ position: 'top-right'
+ });
+ }
+ })
+ .catch(error => {
+ console.error('update_public_profile_settings', error);
+ });
+ },
+
+ /**
+ * Update the users links to twitter and instagram
+ */
+ async UPDATE_SOCIAL_MEDIA_LINKS (context)
+ {
+ const title = i18n.t('notifications.success');
+ const body = "Your settings have been updated";
+
+ await axios.post('/settings/social-media/update', {
+ twitter: context.state.user.settings.twitter,
+ instagram: context.state.user.settings.instagram,
+ })
+ .then(response => {
+ console.log('update_public_profile_settings', response);
+
+ if (response.data.success)
+ {
+ Vue.$vToastify.success({
+ title,
+ body,
+ position: 'top-right'
+ });
+ }
+ })
+ .catch(error => {
+ console.error('update_public_profile_settings', error);
});
}
};
diff --git a/resources/js/store/modules/user/index.js b/resources/js/store/modules/user/index.js
index 9e07f8e6d..2df1a564a 100644
--- a/resources/js/store/modules/user/index.js
+++ b/resources/js/store/modules/user/index.js
@@ -5,9 +5,14 @@ import { mutations } from './mutations';
const state = Object.assign({}, init);
+import { public_profile } from './public_profile';
+
export const user = {
state,
actions,
getters,
- mutations
+ mutations,
+ modules: {
+ public_profile
+ }
};
diff --git a/resources/js/store/modules/user/init.js b/resources/js/store/modules/user/init.js
index 948b2bac4..42d0aefc3 100644
--- a/resources/js/store/modules/user/init.js
+++ b/resources/js/store/modules/user/init.js
@@ -11,6 +11,7 @@ export const init = {
position: 0,
photoPercent: 0,
requiredXp: 0,
+ settings: null,
tagPercent: 0,
totalPhotos: 0,
totalTags: 0,
diff --git a/resources/js/store/modules/user/mutations.js b/resources/js/store/modules/user/mutations.js
index 2ef2b4fb9..fcbce514b 100644
--- a/resources/js/store/modules/user/mutations.js
+++ b/resources/js/store/modules/user/mutations.js
@@ -118,6 +118,18 @@ export const mutations = {
state.user.active_team = payload;
},
+ /**
+ * Update a value for one of the available settings params
+ */
+ publicProfileSetting (state, payload)
+ {
+ const settings = Object.assign({}, state.user.settings);
+
+ settings[payload.key] = payload.v;
+
+ state.user.settings = settings;
+ },
+
/**
* Updates the user's team data
*/
@@ -150,6 +162,22 @@ export const mutations = {
state.user.items_remaining = payload;
},
+ // /**
+ // * After successful response
+ // */
+ // toggleUserDashboardPrivacyStatus (state, payload)
+ // {
+ // state.user.show_public_profile = ! state.user.show_public_profile;
+ // },
+
+ /**
+ * Initialise settings after updating pubic profile
+ */
+ updateUserSettings (state, payload)
+ {
+ state.user.settings = payload;
+ },
+
/**
* Users map data for the given time-period
*/
diff --git a/resources/js/store/modules/user/public_profile/index.js b/resources/js/store/modules/user/public_profile/index.js
new file mode 100644
index 000000000..5ea87443c
--- /dev/null
+++ b/resources/js/store/modules/user/public_profile/index.js
@@ -0,0 +1,11 @@
+import { mutations } from './mutations';
+
+const state = {
+ publicProfile: null,
+ userData: null
+};
+
+export const public_profile = {
+ state,
+ mutations
+};
diff --git a/resources/js/store/modules/user/public_profile/mutations.js b/resources/js/store/modules/user/public_profile/mutations.js
new file mode 100644
index 000000000..fb16ad018
--- /dev/null
+++ b/resources/js/store/modules/user/public_profile/mutations.js
@@ -0,0 +1,10 @@
+export const mutations = {
+ /**
+ * Initialise the public profile and related data of a user when viewing /username
+ */
+ userByUsername (state, payload)
+ {
+ state.publicProfile = payload.publicProfile;
+ state.userData = payload.userData;
+ }
+}
diff --git a/resources/js/views/RootContainer.vue b/resources/js/views/RootContainer.vue
index 79ebb4441..e07eb2c31 100644
--- a/resources/js/views/RootContainer.vue
+++ b/resources/js/views/RootContainer.vue
@@ -19,7 +19,17 @@ import Unsubscribed from '../components/Notifications/Unsubscribed'
export default {
name: 'RootContainer',
- props: ['auth', 'user', 'verified', 'unsub'],
+ props: [
+ 'auth',
+ 'user',
+ 'verified',
+ 'unsub',
+
+ // These exist when we are visiting olm.com/username = public profile
+ 'username',
+ 'publicProfile',
+ 'userData'
+ ],
components: {
Nav,
Modal,
@@ -31,15 +41,17 @@ export default {
return {
showEmailConfirmed: false,
showUnsubscribed: false
- }
+ };
},
created ()
{
+ // Initialise language
if (this.$localStorage.get('lang'))
{
this.$i18n.locale = this.$localStorage.get('lang');
}
+ // Check if the user is authenticated
if (this.auth)
{
this.$store.commit('login');
@@ -47,22 +59,41 @@ export default {
// user object is passed when the page is refreshed
if (this.user)
{
- const u = JSON.parse(this.user);
- this.$store.commit('initUser', u);
- this.$store.commit('set_default_litter_presence', u.items_remaining);
+ const user = JSON.parse(this.user);
+ console.log('RootContainer.user', user);
+
+ this.$store.commit('initUser', user);
+ this.$store.commit('set_default_litter_presence', user.items_remaining);
}
}
-
// This is needed to invalidate user.auth = true
// which is persisted and not updated if the authenticated user forgets to manually log out
- else this.$store.commit('resetState');
+ else
+ {
+ console.log('guest');
+ this.$store.commit('resetState');
+ }
// If Account Verified
if (this.verified) this.showEmailConfirmed = true;
if (this.unsub) this.showUnsubscribed = true;
+
+ // If the user is visiting a username with public settings turned on
+ if (this.username)
+ {
+ const publicProfile = JSON.parse(this.publicProfile);
+ console.log({ publicProfile });
+
+ const userData = JSON.parse(this.userData);
+ console.log({ userData });
+
+ this.$store.commit('userByUsername', {
+ publicProfile,
+ userData
+ });
+ }
},
computed: {
-
/**
* Boolean to show or hide the modal
*/
diff --git a/resources/js/views/Settings.vue b/resources/js/views/Settings.vue
index f4df3232f..c6c1cbb0c 100644
--- a/resources/js/views/Settings.vue
+++ b/resources/js/views/Settings.vue
@@ -7,7 +7,7 @@
{{ $t('settings.common.general') }}