diff --git a/functions/src/Integrations/user-stats.ts b/functions/src/Integrations/user-stats.ts
new file mode 100644
index 0000000000..31ef8fb817
--- /dev/null
+++ b/functions/src/Integrations/user-stats.ts
@@ -0,0 +1,81 @@
+import * as functions from 'firebase-functions'
+import { db } from '../Firebase/firestoreDB'
+
+
+export const countHowTos = functions.firestore
+ .document('v3_howtos/{id}')
+ .onWrite(async (change, context) => {
+
+ updateStats(change, 'v3_howtos', 'howToCount')
+
+ })
+
+export const countEvents = functions.firestore
+ .document('v3_events/{id}')
+ .onWrite(async (change, context) => {
+
+ updateStats(change, 'v3_events', 'eventCount')
+
+ })
+
+function updateStats(change, collection, target){
+
+ const info = change.after.exists ? change.after.data() : null
+ const prevInfo = change.before.exists ? change.before.data() : null
+ const userStatsRef = db.collection('v3_users/');
+
+ let delta = 0
+
+ if (info !== null && info.moderation === 'accepted' && prevInfo !== null && prevInfo.Moderation !== 'accepted') { // Increment if now accepted and previously different
+ delta = 1
+ } else if (prevInfo !== null && prevInfo.moderation === 'accepted' && (info === null || info.moderation !== 'accepted')) { // Decrement if previously accepted and now erased or moderation changed
+ delta = -1
+ } else {
+ return null
+ }
+
+ console.log('Update ', collection, ' delta: ', delta )
+
+ return userStatsRef.doc(info._createdBy).update({'_stats':{
+ [target]: admin.firestore.FieldValue.increment(delta)
+ }}).catch(e => {
+ console.log(e);
+ // In case stats for user are inexistent we compute from all his records, Only triggers if no user exist (new Collection)
+ // computeUserStats(info._createdBy)
+ })
+}
+
+// Compute one user stats
+function computeUserStats(owner){
+
+ const userStatsRef = db.collection('v3_users/')
+
+ db.collection('v3_howtos').where("_createdBy", "==", owner).where("moderation", "==", "accepted")
+ .get()
+ .then(querySnapshot => {
+ let count = 0;
+ querySnapshot.forEach(doc => {
+ count++;
+ });
+ console.log('Accepted howtos for', owner ,',count: ', count);
+ userStatsRef.doc(owner).set({'_stats':{
+ howToCount: count
+ }}, {merge: true});
+ return null
+ }).catch(() => null);
+
+ db.collection('v3_events').where("_createdBy", "==", owner).where("moderation", "==", "accepted")
+ .get()
+ .then(querySnapshot => {
+ let count = 0;
+ querySnapshot.forEach(doc => {
+ count++;
+ });
+ console.log('Accepted events for', owner ,',count: ', count);
+ userStatsRef.doc(owner).set({'_stats':{
+ eventCount: count
+ }}, {merge: true});
+ return null
+ }).catch(() => null);
+}
+
diff --git a/functions/src/index.ts b/functions/src/index.ts
index fa9c8b086e..44ae4dd0ad 100644
--- a/functions/src/index.ts
+++ b/functions/src/index.ts
@@ -5,6 +5,7 @@ import * as IntegrationsSlack from './Integrations/firebase-slack'
import * as IntegrationsDiscord from './Integrations/firebase-discord'
import { FirebaseUserBackup } from './Integrations/firebase-userBackup'
import * as IntegrationsEmail from './Integrations/firebase-email'
+import * as UserStats from './Integrations/user-stats'
import * as Admin from './admin'
// the following endpoints are exposed for use by various triggers
@@ -23,6 +24,8 @@ exports.notifyHowToAccepted = IntegrationsDiscord.notifyHowToAccepted
exports.notifyEventAccepted = IntegrationsDiscord.notifyEventAccepted
exports.firebaseUserBackup = FirebaseUserBackup
exports.emailNotificationDemo = IntegrationsEmail.notifyEmailDemo
+exports.countEvents = UserStats.countEvents
+exports.countHowTos = UserStats.countHowTos
// CC Note, 2020-04-40
// folder-based naming conventions should be encourage from now on
exports.adminGetUserEmail = Admin.getUserEmail
diff --git a/src/models/user.models.tsx b/src/models/user.models.tsx
index 446487ddf5..836cb556b7 100644
--- a/src/models/user.models.tsx
+++ b/src/models/user.models.tsx
@@ -36,6 +36,7 @@ export interface IUser {
country?: string | null
location?: ILocation | null
year?: ISODateString
+ _stats?: IUserStats
}
interface IExternalLink {
@@ -51,6 +52,11 @@ interface IExternalLink {
| 'instagram'
}
+interface IUserStats {
+ howToCount: number
+ eventCount: number
+}
+
export type IUserDB = IUser & DBDoc
export type UserRole = 'super-admin' | 'subscriber' | 'admin'
diff --git a/src/pages/User/content/UserPage/UserPage.tsx b/src/pages/User/content/UserPage/UserPage.tsx
index e3a5d92877..83d2823214 100644
--- a/src/pages/User/content/UserPage/UserPage.tsx
+++ b/src/pages/User/content/UserPage/UserPage.tsx
@@ -228,7 +228,9 @@ export class UserPage extends React.Component<
}
// Comment on 6.05.20 by BG : renderCommitmentBox commented for now, will be reused with #974
public renderUserStatsBox(user: IUserPP) {
- console.log('user.location', user.location)
+ if (!user._stats) {
+ user._stats = { howToCount: 0, eventCount: 0 }
+ }
return (
@@ -239,12 +241,14 @@ export class UserPage extends React.Component<
)} */}
-
-
-
- {user.location?.country}
-
-
+ {user.location && (
+
+
+
+ {user.location?.country}
+
+
+ )}
{/* {isV4Member && (
@@ -252,12 +256,20 @@ export class UserPage extends React.Component<
)} */}
-
- 0
-
-
- 0
-
+ {user._stats.eventCount > 0 && (
+
+
+ {user._stats.eventCount}
+
+
+ )}
+ {user._stats.howToCount > 0 && (
+
+
+ {user._stats.howToCount}
+
+
+ )}
)
}
@@ -384,7 +396,12 @@ export class UserPage extends React.Component<
)
}
// TODO check if user exist and have created how-to or events
- const shouldRenderUserStatsBox = user && user.location ? true : false
+ const shouldRenderUserStatsBox =
+ user &&
+ (user.location ||
+ (user._stats && (user._stats.howToCount || user._stats.eventCount)))
+ ? true
+ : false
return (