Skip to content

Commit

Permalink
profile photo first stable
Browse files Browse the repository at this point in the history
  • Loading branch information
Resul Avan authored and Resul Avan committed May 28, 2020
1 parent a494272 commit cc36c79
Show file tree
Hide file tree
Showing 21 changed files with 164 additions and 99 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ See the [Features](#features) for more functionalities
- [x] the url same as hosting
- [x] dynamic sitemap
- [x] firebase-storage
- [x] profile picture
- [x] profile photo
- [x] cover photo
- [x] firestore
- [x] user collection
- [x] firebase-auth
- [x] firebase-auth password
- [x] register
Expand Down
24 changes: 11 additions & 13 deletions functions/src/api/authApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import express, { Request, Response, Router } from 'express';
import { addDecodedIdToken } from '../service/firebase-admin-utils';
import { DefaultUserPhoto, StoredUser } from '../types'
import { User, UserDTO } from '../types'
import admin from '../service/firebase-admin-init';
import { FirebaseError } from "firebase-admin";
import { RuntimeOptions, runWith } from "firebase-functions";
Expand Down Expand Up @@ -30,26 +30,24 @@ router.post(service, async (req: Request, res: Response) => {
}

return await addDecodedIdToken(req.body.token)
.then((decodedIdToken: admin.auth.DecodedIdToken) => {
const alt = decodedIdToken.name as string || decodedIdToken.email as string;
.then(async (decodedIdToken: admin.auth.DecodedIdToken) => {
const user = await admin.firestore().doc(decodedIdToken.sub).get().then((document) => {
return document.data() as User
})
if (!user) {
throw new Error('User not found by id: ' + decodedIdToken.sub)
}

const profilePhoto = decodedIdToken.picture ?
{
src: decodedIdToken.picture,
alt: 'Picture of ' + alt
}
: DefaultUserPhoto

const user: StoredUser = {
const storedUser: UserDTO = {
name: decodedIdToken.name,
verified: decodedIdToken.email_verified as boolean,
email: decodedIdToken.email as string,
profilePhoto,
profilePhoto: user.profilePhoto,
userId: decodedIdToken.sub,
providers: [{ providerType: decodedIdToken.firebase.sign_in_provider }]
};

return res.status(200).json(user);
return res.status(200).json(storedUser);
})
.catch((error) => handleFirebaseError(res, error, '/api' + service));
});
Expand Down
17 changes: 11 additions & 6 deletions functions/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import { BaseCollection } from "../../src/types";

export interface Image {
src: string;
alt: string;
name?: string;
default?: boolean
}

export const DefaultUserPhoto: Image = {
src: '/img/default-profile.svg',
alt: ' user default picture'
}

export interface ProviderData {
providerType: string
}

export interface StoredUser {
export interface UserDTO {
name: string
email: string
profilePhoto: Image
userId: string,
verified: boolean
providers: ProviderData[]
}

export interface User extends BaseCollection {
id: string
name: string
surname: string
profilePhoto: Image
coverPhoto: Image
}
2 changes: 1 addition & 1 deletion src/components/image/upload/SingleFileUpload.vue
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@
name: this.fileName,
src: downloadURL,
alt: this.getAltValue(this.file?.name || ''),
default: false
}
this.uploadCompleted(image)
});
});
Expand Down
8 changes: 4 additions & 4 deletions src/components/navbar/ProfileNavigator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</b-field>
</template>

<b-navbar-item tag="router-link" :to="accountRoute" active>
<b-navbar-item tag="router-link" :to="profileRoute" active>
<b-icon pack="fas" icon="user"/>
<span>{{$t('topNavbar.profile')}}</span>
</b-navbar-item>
Expand All @@ -26,20 +26,20 @@

<script lang="ts">
import { Component, Prop, Vue } from 'nuxt-property-decorator';
import { DefaultUserPhoto, Image, ProfilePhotoPlaceholder, RouteType, StoredUser } from "~/types";
import { DefaultProfilePhoto, Image, ProfilePhotoPlaceholder, RouteType, StoredUser } from "~/types";
@Component({
components: {}
})
export default class ProfileNavigator extends Vue {
accountRoute = RouteType.ACCOUNT;
profileRoute = RouteType.PROFILE;
@Prop({ required: true }) storedUser !: StoredUser;
@Prop({ type: Function, required: true }) logout !: () => void;
get profilePhoto(): Image {
return this.storedUser.profilePhoto || DefaultUserPhoto
return this.storedUser.profilePhoto || DefaultProfilePhoto
}
imageLoadError(event: any) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<template>
<div class="card-image">
<figure class="image cropped-h512">
<img v-lazy="coverPhoto.src"
<img v-lazy="computedCoverPhoto.src"
:src="placeholder"
:alt="coverPhoto.alt"
:alt="computedCoverPhoto.alt"
@error="imageLoadError">
</figure>
<div class="is-overlay is-pulled-right has-margin-5">
Expand All @@ -16,16 +16,26 @@

<script lang="ts">
import { Component, Prop, Vue } from 'nuxt-property-decorator';
import { CoverPhotoPlaceholder, CoverPhotoStorageRef, Image, StoredUser } from "~/types";
import {
CoverPhotoPlaceholder,
CoverPhotoStorageRef,
DefaultCoverPhoto,
Image,
StateNamespace,
StoredUser
} from "~/types";
import SingleFileUpload from '~/components/image/upload/SingleFileUpload.vue';
@Component({
components: { SingleFileUpload }
})
export default class ProfileCover extends Vue {
@Prop({ required: true }) storedUser !: StoredUser
@Prop({ required: true }) coverPhoto !: Image
@StateNamespace.auth.Action updateCoverPhoto !: (coverPhoto: Image) => void;
get parentFolderRef() {
return CoverPhotoStorageRef.folderRef
.replace(CoverPhotoStorageRef.parameters.userId, this.storedUser.userId)
Expand All @@ -35,16 +45,16 @@
return CoverPhotoPlaceholder
}
updateCoverPhoto(image: Image) {
console.log('new Cover: ', image)
get computedCoverPhoto() {
return this.coverPhoto || DefaultCoverPhoto
}
imageLoadError(event: any) {
event.target.src = CoverPhotoPlaceholder
}
getCoverImageAltName(fileName: string) {
return 'Cover photo of ' + this.storedUser.name
return `Cover photo of ${this.storedUser.name} as ${fileName}`
}
}
</script>
10 changes: 4 additions & 6 deletions src/components/profile/Profile.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<div>
<div>
<ProfileCover :cover-photo="coverPhoto" :stored-user="storedUser"/>
<CoverPhoto :stored-user="storedUser" :cover-photo="coverPhoto"/>
<div class="has-margin-top-10 has-margin-bottom-10">
<article class="media has-margin-left-5">
<div class="media-left">
Expand Down Expand Up @@ -51,7 +51,6 @@
<script lang="ts">
import { Component, Prop, Vue } from 'nuxt-property-decorator';
import {
DefaultCoverPhoto,
Image,
ProfilePhotoStorageRef,
ProviderConfig,
Expand All @@ -62,17 +61,16 @@
} from "~/types";
import ProfileInfo from "~/components/profile/ProfileInfo.vue";
import ProfilePhoto from "~/components/profile/ProfilePhoto.vue";
import ProfileCover from "~/components/profile/ProfileCover.vue";
import CoverPhoto from "~/components/profile/CoverPhoto.vue";
import ProviderList from "~/components/profile/ProviderList.vue";
@Component({
components: { ProfileCover, ProviderList, ProfilePhoto, ProfileInfo },
components: { CoverPhoto, ProfilePhoto, ProviderList, ProfileInfo },
})
export default class Profile extends Vue {
coverPhoto: Image = DefaultCoverPhoto
@Prop({ required: true }) storedUser !: StoredUser;
@Prop({ required: true }) coverPhoto !: Image;
@StateNamespace.auth.Action updateProfilePhoto !: (profilePhotoUrl: string) => void;
Expand Down
12 changes: 6 additions & 6 deletions src/components/profile/ProfilePhoto.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
<script lang="ts">
import { Component, Prop, Vue } from 'nuxt-property-decorator';
import {
DefaultUserPhoto,
DefaultProfilePhoto,
Image,
ProfilePhotoPlaceholder,
ProfilePhotoStorageRef,
StateNamespace,
Expand All @@ -30,16 +31,15 @@
export default class ProfilePhoto extends Vue {
@Prop({ required: true }) storedUser !: StoredUser
@StateNamespace.auth.Action updateProfilePhoto !: (profilePhotoUrl: string) => void;
@StateNamespace.auth.Action updateProfilePhoto !: (profilePhoto: Image) => void;
get parentFolderRef() {
return ProfilePhotoStorageRef.folderRef
.replace(ProfilePhotoStorageRef.parameters.userId, this.storedUser.userId)
}
get profilePhoto(){
return this.storedUser.profilePhoto || this.storedUser.profilePicture || DefaultUserPhoto
get profilePhoto() {
return this.storedUser.profilePhoto || DefaultProfilePhoto
}
get placeholder() {
Expand All @@ -51,7 +51,7 @@
}
getProfilePhotoAltValue(fileName: string) {
return fileName;
return `Profile photo of ${this.storedUser.name} as ${fileName}`
}
}
</script>
2 changes: 1 addition & 1 deletion src/middleware/router-auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const routerAuthMiddleware: Middleware = ({ store, redirect, route }) => {
console.log('routerAuthMiddleware', route.fullPath, route.query, store.state.auth.storedUser)
if (store.state.auth.storedUser) {
if (authenticatedNotAllowed(route)) {
redirect(RouteType.ACCOUNT)
redirect(RouteType.PROFILE)
}
} else {
if (authenticatedAllowed(route)) {
Expand Down
18 changes: 0 additions & 18 deletions src/pages/account/index.vue

This file was deleted.

2 changes: 1 addition & 1 deletion src/pages/auth/reset-password.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator';
import { Context } from "@nuxt/types";
import SetPasswordForm from "~/components/form/SetPasswordForm.vue";
import { NotificationMessage, RouteParameters, StateNamespace } from "~/types";
import { Context } from "@nuxt/types";
import { getWarningNotificationMessage } from "~/service/notification-service";
@Component({
Expand Down
38 changes: 38 additions & 0 deletions src/pages/profile/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<template>
<Profile v-if="storedUser" :stored-user="storedUser" :cover-photo="coverPhoto"/>
</template>

<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator';
import Profile from "~/components/profile/Profile.vue";
import { Image, StateNamespace, StoredUser, User } from "~/types";
import { getUser } from "~/service/firebase/firestore-service";
@Component({
components: { Profile },
})
export default class Account extends Vue {
coverPhoto: Image | null = null;
@StateNamespace.auth.Getter storedUser !: StoredUser;
async created() {
await getUser(this.storedUser.userId)
.then((user: User) => {
console.log('created ', user)
this.coverPhoto = user.coverPhoto as Image
})
}
// async asyncData({}: Context) {
// getUser(this.storedUser.userId)
// .then((user: User) => {
// return {
// coverPhoto: user.coverPhoto
// }
// })
// }
}
</script>


2 changes: 1 addition & 1 deletion src/plugins/firebase-auth-listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const getNextRoute = (route: Route): Location => {
}

if (authenticatedNotAllowed(route) || route.path == RouteType.ACTION.path) {
return RouteType.ACCOUNT
return RouteType.PROFILE
}

return { path: route.fullPath }
Expand Down
Loading

0 comments on commit cc36c79

Please sign in to comment.