kitchen-site icon indicating copy to clipboard operation
kitchen-site copied to clipboard

Image in user profile

Open xauxatz opened this issue 7 years ago • 6 comments

I have been struggling several hours now to insert a picture into a standard user profile. I just can't figure it out! I have been studying the File Upload example in detail - but cannot get it to work within my extremely simple app. I simple want to extend the normal user profile with an extra field to hold an image for the user. Can't this be done without adding extra stuff to Meteorkitchen?

xauxatz avatar Nov 25 '18 18:11 xauxatz

@xauxatz Which part / where you stuck?

perak avatar Nov 25 '18 20:11 perak

I have attached the source code of the app here, I guess that is the easiest. I am able to upload a photo which is then also shown on the screen - but it does not seem to be stored in the correct field in the collection.


{
	"application": {
		"title": "Young Helpers",
		"roles": [
			"admin",
			"user"
		],
		"default_role": "user",
		"collections": [
			{
				"name": "users",
				"type": "collection",
				"fields": [
					{
						"name": "type_of_user",
						"title": "Type Of User",
						"type": "array",
						"default": "1",
						"required": true,
						"input": "radio",
						"input_items": [
							{
								"value": "helper",
								"title": "Hjælper"
							},
							{
								"value": "client",
								"title": "Køber"
							}
						]
					},
					{
						"name": "street",
						"title": "Street",
						"type": "string",
						"required": true
					},
					{
						"name": "post_code",
						"title": "Post Code",
						"type": "integer",
						"required": true
					},
					{
						"name": "city",
						"title": "City",
						"type": "string",
						"required": true
					},
					{
						"name": "desc",
						"title": "Text Desc",
						"type": "string",
						"required": true
					},
					{
						"name": "services",
						"title": "Services",
						"type": "array",
						"input": "select-multiple",
						"input_items": [
							{
								"value": "kids",
								"title": "Børnepasning"
							},
							{
								"value": "pet_walk",
								"title": "Gå tur med hund"
							},
							{
								"value": "pet_sitting",
								"title": "Passe hund/kat/kanin"
							},
							{
								"value": "cleaning",
								"title": "Gøre rent"
							},
							{
								"value": "delivery",
								"title": "Hente/bringe"
							},
							{
								"value": "shopping",
								"title": "Købe ind"
							}
						]
					},
					{
						"name": "picture",
						"title": "Billede",
						"type": "string",
						"input": "file",
						"file_collection": "files",
						"file_container": "file"
					}
				]
			},
			{
				"name": "files",
				"type": "file_collection",
				"storage_adapter_options": {
					"gridfs": {}
				}
			}
		],
		"queries": [
			{
				"name": "admin_users",
				"collection": "users",
				"filter": "{}",
				"options": "{}"
			},
			{
				"name": "admin_user",
				"collection": "users",
				"find_one": true,
				"filter": "{ \"_id\": \":userId\" }",
				"options": "{}"
			},
			{
				"name": "users_null",
				"collection": "users",
				"find_one": true,
				"filter": "{ \"_id\": null }",
				"options": "{}"
			},
			{
				"name": "current_user_data",
				"collection": "users",
				"find_one": true,
				"filter": "{ \"_id\": \"Meteor.userId()\" }",
				"options": "{}"
			}
		],
		"free_zone": {
			"type": "zone",
			"pages": [
				{
					"name": "home_public",
					"type": "page",
					"components": [
						{
							"name": "home_jumbotron",
							"type": "jumbotron",
							"title": "Young Helpers",
							"button_title": "Continue »",
							"button_route": "login",
							"object_type": "jumbotron"
						}
					]
				}
			]
		},
		"public_zone": {
			"type": "zone",
			"components": [
				{
					"name": "left_menu",
					"type": "menu",
					"items": [
						{
							"title": "Home",
							"route": "home_public"
						}
					],
					"object_type": "menu"
				},
				{
					"name": "right_menu",
					"type": "menu",
					"items": [
						{
							"title": "Register",
							"route": "register"
						},
						{
							"title": "Login",
							"route": "login"
						}
					],
					"object_type": "menu"
				}
			],
			"pages": [
				{
					"name": "login",
					"type": "page",
					"template": "login"
				},
				{
					"name": "register",
					"type": "page",
					"template": "register"
				},
				{
					"name": "verify_email",
					"type": "page",
					"template": "verify_email",
					"route_params": [
						"verifyEmailToken"
					]
				},
				{
					"name": "forgot_password",
					"type": "page",
					"template": "forgot_password"
				},
				{
					"name": "reset_password",
					"type": "page",
					"template": "reset_password",
					"route_params": [
						"resetPasswordToken"
					]
				}
			],
			"default_route": "home_public"
		},
		"private_zone": {
			"type": "zone",
			"components": [
				{
					"name": "left_menu",
					"type": "menu",
					"items": [
						{
							"title": "Home",
							"route": "home_private",
							"icon_class": "fa fa-home"
						}
					],
					"object_type": "menu"
				},
				{
					"name": "right_menu",
					"type": "menu",
					"items": [
						{
							"title": "Admin",
							"route": "admin",
							"icon_class": "fa fa-wrench"
						},
						{
							"title": "{{userEmail}}",
							"icon_class": "fa fa-cog",
							"items": [
								{
									"title": "Settings",
									"route": "user_settings"
								},
								{
									"title": "Logout",
									"route": "logout"
								}
							]
						}
					],
					"object_type": "menu"
				}
			],
			"pages": [
				{
					"name": "home_private",
					"type": "page",
					"title": "Welcome {{userFullName}}!"
				},
				{
					"name": "admin",
					"type": "page",
					"components": [
						{
							"name": "side_menu",
							"type": "menu",
							"class": "nav nav-stacked nav-pills",
							"items": [
								{
									"title": "Users",
									"route": "admin.users"
								}
							],
							"object_type": "menu"
						}
					],
					"roles": [
						"admin"
					],
					"pages": [
						{
							"name": "users",
							"type": "page",
							"components": [
								{
									"name": "view",
									"type": "data_view",
									"title": "Users",
									"query_name": "admin_users",
									"text_if_empty": "No users yet",
									"insert_route": "admin.users.insert",
									"details_route": "admin.users.details",
									"edit_route": "admin.users.edit",
									"details_route_params": [
										{
											"name": "userId",
											"value": "this._id"
										}
									],
									"edit_route_params": [
										{
											"name": "userId",
											"value": "this._id"
										}
									],
									"fields": [
										{
											"name": "profile.name",
											"title": "Name",
											"type": "string"
										},
										{
											"name": "roles",
											"title": "Role",
											"type": "string"
										}
									],
									"object_type": "data_view"
								}
							],
							"pages": [
								{
									"name": "details",
									"type": "page",
									"components": [
										{
											"name": "details_form",
											"type": "form",
											"title": "User details",
											"query_name": "admin_user",
											"mode": "read_only",
											"close_route": "admin.users",
											"back_route": "admin.users",
											"fields": [
												{
													"name": "profile.name",
													"title": "Name",
													"type": "string"
												},
												{
													"name": "roles",
													"title": "Role",
													"type": "string"
												}
											],
											"object_type": "form"
										}
									],
									"route_params": [
										"userId"
									]
								},
								{
									"name": "insert",
									"type": "page",
									"components": [
										{
											"name": "insert_form",
											"type": "form",
											"title": "Add new user",
											"query_name": "users_null",
											"mode": "insert",
											"submit_route": "admin.users",
											"cancel_route": "admin.users",
											"fields": [
												{
													"name": "profile.name",
													"title": "Name",
													"type": "string",
													"required": true
												},
												{
													"name": "email",
													"title": "E-mail",
													"type": "email",
													"required": true
												},
												{
													"name": "password",
													"title": "Password",
													"type": "string",
													"required": true,
													"input": "password"
												}
											],
											"object_type": "form"
										}
									]
								},
								{
									"name": "edit",
									"type": "page",
									"components": [
										{
											"name": "edit_form",
											"type": "form",
											"title": "Edit user",
											"query_name": "admin_user",
											"mode": "update",
											"submit_route": "admin.users",
											"cancel_route": "admin.users",
											"fields": [
												{
													"name": "profile.name",
													"title": "Name",
													"type": "string",
													"required": true
												},
												{
													"name": "roles",
													"title": "Role",
													"type": "array",
													"input": "radio",
													"input_items": [
														{
															"value": "user",
															"title": "User"
														},
														{
															"value": "admin",
															"title": "Admin"
														},
														{
															"value": "blocked",
															"title": "Blocked"
														}
													]
												}
											],
											"object_type": "form"
										}
									],
									"route_params": [
										"userId"
									]
								}
							]
						}
					]
				},
				{
					"name": "user_settings",
					"type": "page",
					"components": [
						{
							"name": "side_menu",
							"type": "menu",
							"class": "nav nav-stacked nav-pills",
							"items": [
								{
									"title": "Profile",
									"route": "user_settings.profile"
								},
								{
									"title": "Change password",
									"route": "user_settings.change_pass"
								}
							],
							"object_type": "menu"
						}
					],
					"roles": [
						"user",
						"admin"
					],
					"pages": [
						{
							"name": "profile",
							"type": "page",
							"components": [
								{
									"name": "edit_form",
									"type": "form",
									"title": "Ret din profil",
									"query_name": "current_user_data",
									"mode": "update",
									"submit_route": "user_settings.profile",
									"fields": [
										{
											"name": "profile.name",
											"title": "Navn",
											"type": "string",
											"required": true
										},
										{
											"name": "profile.type_of_user",
											"title": "Type af bruger",
											"type": "array",
											"required": true,
											"input": "radio",
											"input_items": [
												{
													"value": "helper",
													"title": "Hjælper"
												},
												{
													"value": "client",
													"title": "Kunde"
												}
											]
										},
										{
											"name": "profile.street",
											"title": "Vej og nummer",
											"type": "string",
											"required": true
										},
										{
											"name": "profile.post_code",
											"title": "Postkode",
											"type": "string",
											"required": true
										},
										{
											"name": "profile.city",
											"title": "By",
											"type": "string",
											"required": true
										},
										{
											"name": "profile.desc",
											"title": "Beskrivelse af dig selv",
											"type": "string",
											"input": "textarea"
										},
										{
											"name": "profile.services",
											"title": "Hvad kan du hjælpe med? (hold shift eller ctrl nede for at vælge flere)",
											"type": "array",
											"input": "select-multiple",
											"input_items": [
												{
													"value": "kids",
													"title": "Børnepasning"
												},
												{
													"value": "pet_walk",
													"title": "Gå tur med hunden"
												},
												{
													"value": "pet_sitting",
													"title": "Passe hund/kat/kanin"
												},
												{
													"value": "cleaning",
													"title": "Gøre rent"
												},
												{
													"value": "delivery",
													"title": "Hente/bringe"
												},
												{
													"value": "shopping",
													"title": "Købe ind"
												}
											]
										},
										{
											"name": "profile.picture",
											"title": "Billede",
											"type": "string",
											"input": "file",
											"file_collection": "files",
											"file_container": "file"
										}
									],
									"object_type": "form"
								}
							]
						},
						{
							"name": "change_pass",
							"type": "page",
							"template": "change_pass"
						}
					]
				},
				{
					"name": "logout",
					"type": "page",
					"template": "logout"
				}
			]
		}
	}
}

xauxatz avatar Nov 26 '18 06:11 xauxatz

@xauxatz oops, that is a bug. I'll give you workaround in few minutes, so you can fix at your side before I deploy new version.

perak avatar Nov 26 '18 08:11 perak

@xauxatz

  • First, in your /server/server.js change updateUserAccount method to:
	"updateUserAccount": function(userId, data) {
		if(!data || !Object.keys(data).length) {
			return;
		}

		// Only admin or owner
		if(!(Users.isAdmin(this.userId) || userId == this.userId)) {
			throw new Meteor.Error(403, "Access denied.");
		}

		// deepen: convert { "x.y": "val" } into { x: { y: "val" }}
		var userData = objectUtils.deepen(data);

		// non-admin user can change only .profile, .private and .public
		if(!Users.isAdmin(this.userId)) {
			let allowedKeys = ["profile", "private", "public"];
			for(var key in userData) {
				if(allowedKeys.indexOf(key) < 0) {
					throw new Meteor.Error(403, "You are not allowed to modify \"" + key + "\".");
				}
			}
		}

		// flatten: convert { x: { y: "val" }} into { "x.y": "val" }
		userData = objectUtils.flatten(userData);

		// update
		Users.update(userId, { $set: userData });
	},

OR you can change kitchen's template:

Find directory where meteor kitchen is installed, on Linux and Mac it is ~/.meteor-kitchen/ by default, and there you will find /templates/blaze/code/server_accounts.js and change method here.

That will allow writing profile data and image ID will be saved in user's document

  • But you will have hard time to display image (because you have only ID, so you'll need to query "images" collection to find image URL (and that's full image, not thumbnail...). This requires change form template ("image" field). I'll try to find time later today/tonight and give you code.

perak avatar Nov 26 '18 10:11 perak

Thanks a lot, Perak - I look forward to the last bit of code change! As always great support! My reason for choosing Meteorkitchen over any other framework

xauxatz avatar Nov 27 '18 14:11 xauxatz

Hi Petar - do you have time to make the last code suggested by you, in order to display the image?

Best regards / Venlig hilsen Claus Skaaning Mobil +45 20690771

Den 26. nov. 2018 kl. 11.34 skrev Petar Korponaić [email protected]:

@xauxatz

First, in your /server/server.js change updateUserAccount method to: "updateUserAccount": function(userId, data) { if(!data || !Object.keys(data).length) { return; }

  // Only admin or owner
  if(!(Users.isAdmin(this.userId) || userId == this.userId)) {
  	throw new Meteor.Error(403, "Access denied.");
  }

  // deepen: convert { "x.y": "val" } into { x: { y: "val" }}
  var userData = objectUtils.deepen(data);

  // non-admin user can change only .profile, .private and .public
  if(!Users.isAdmin(this.userId)) {
  	let allowedKeys = ["profile", "private", "public"];
  	for(var key in userData) {
  		if(allowedKeys.indexOf(key) < 0) {
  			throw new Meteor.Error(403, "You are not allowed to modify \"" + key + "\".");
  		}
  	}
  }

  // flatten: convert { x: { y: "val" }} into { "x.y": "val" }
  userData = objectUtils.flatten(userData);

  // update
  Users.update(userId, { $set: userData });

}, OR you can change kitchen's template:

Find directory where meteor kitchen is installed, on Linux and Mac it is ~/.meteor-kitchen/ by default, and there you will find /templates/blaze/code/server_accounts.js and change method here.

That will allow writing profile data and image ID will be saved in user's document

But you will have hard time to display image (because you have only ID, so you'll need to query "images" collection to find image URL (and that's full image, not thumbnail...). This requires change form template ("image" field). I'll try to find time later today/tonight and give you code. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

xauxatz avatar Dec 19 '18 19:12 xauxatz