@@ -3,31 +3,149 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
3
3
4
4
alias Atomic.Accounts
5
5
alias Atomic.Socials
6
+ alias AtomicWeb.Components.ImageUploader
6
7
7
8
@ extensions_whitelist ~w( .jpg .jpeg .gif .png)
8
9
10
+ @ impl true
11
+ def render ( assigns ) do
12
+ ~H"""
13
+ < div class = "px-4 pt-4 " >
14
+ < . form :let = { f } for = { @ changeset } id = "profile-form " phx-target = { @ myself } phx-change = "validate " phx-submit = "save " >
15
+ <!-- Upload de Foto -->
16
+ < div class = "flex flex-wrap justify-between " >
17
+ <!-- Secção para a imagem de capa -->
18
+ < div class = "flex-1 max-w-[70%] pr-4 " >
19
+ <%= label ( f , :cover_image , "Cover Image" , class: "mt-3 mb-1 text-sm font-medium text-gray-700" ) %>
20
+ </ div >
21
+ <!-- Secção para a imagem de perfil -->
22
+ < div class = "flex flex-shrink-0 flex-col items-center " >
23
+ <%= label ( f , :name , "Profile Picture" , class: "mt-3 mb-1 text-sm font-medium text-gray-700" ) %>
24
+ < . live_component module = { ImageUploader } id = "uploader-profile-picture " uploads = { @ uploads } target = { @ myself } />
25
+ </ div >
26
+ </ div >
27
+ <!-- Linha de separação -->
28
+ < hr class = "mb-6 h-full w-full border-gray-200 " />
29
+ <!-- Campos do formulário em duas colunas -->
30
+ < div class = "grid grid-cols-1 gap-6 sm:grid-cols-2 " >
31
+ < div >
32
+ <%= label ( f , :name , "Full name" , class: "mb-1 text-sm font-medium text-gray-700" ) %>
33
+ <%= text_input ( f , :name ,
34
+ required: true ,
35
+ placeholder: gettext ( "John Doe" ) ,
36
+ class: "w-full appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:outline-none focus:ring-orange-400 sm:text-sm"
37
+ ) %>
38
+ < div class = "text-sm text-red-600 " > <%= error_tag ( f , :name ) %> </ div >
39
+ </ div >
40
+
41
+ < div >
42
+ <%= label ( f , :email , "Email" , class: "mb-1 text-sm font-medium text-gray-700" ) %>
43
+ <%= text_input ( f , :email ,
44
+ required: true ,
45
+ placeholder: gettext ( "john_doe@mail.com" ) ,
46
+ class: "w-full appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:outline-none focus:ring-orange-400 sm:text-sm"
47
+ ) %>
48
+ < div class = "text-sm text-red-600 " > <%= error_tag ( f , :email ) %> </ div >
49
+ </ div >
50
+
51
+ < div >
52
+ <%= label ( f , :username , "Username" , class: "mb-1 text-sm font-medium text-gray-700" ) %>
53
+ < div class = "relative flex w-full appearance-none rounded border border-zinc-300 px-3 text-zinc-900 placeholder-zinc-500 focus-within:z-10 focus-within:border-orange-400 focus-within:outline-none focus-within:ring-orange-400 sm:text-sm " >
54
+ < span class = "select-none self-center " > @</ span >
55
+ <%= text_input ( f , :slug ,
56
+ required: true ,
57
+ spellcheck: false ,
58
+ placeholder: gettext ( "john_doe" ) ,
59
+ class: "w-full appearance-none border-none pl-0 text-zinc-900 placeholder-zinc-500 focus:outline-none focus:ring-transparent sm:text-sm"
60
+ ) %>
61
+ </ div >
62
+ < div class = "text-sm text-red-600 " > <%= error_tag ( f , :slug ) %> </ div >
63
+ </ div >
64
+
65
+ < div >
66
+ <%= label ( f , :phone_number , "Phone number" , class: "mb-1 text-sm font-medium text-gray-700" ) %>
67
+ <%= text_input ( f , :phone_number ,
68
+ required: true ,
69
+ placeholder: gettext ( "912345678" ) ,
70
+ class: "w-full appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:outline-none focus:ring-orange-400 sm:text-sm"
71
+ ) %>
72
+ < div class = "text-sm text-red-600 " > <%= error_tag ( f , :phone_number ) %> </ div >
73
+ </ div >
74
+
75
+ < div >
76
+ <%= label ( f , :bio , "Bio" , class: "mb-1 text-sm font-medium text-gray-700" ) %>
77
+ <%= textarea ( f , :bio ,
78
+ placeholder: "Tell us about yourself" ,
79
+ class: "w-full appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:outline-none focus:ring-orange-400 sm:text-sm"
80
+ ) %>
81
+ < div class = "text-sm text-red-600 " > <%= error_tag ( f , :bio ) %> </ div >
82
+ </ div >
83
+
84
+ < div >
85
+ <%= label ( f , :instagram , "Instagram Username" , class: "mb-1 text-sm font-medium text-gray-700" ) %>
86
+ <%= text_input ( f , :instagram ,
87
+ placeholder: "your_username" ,
88
+ class: "w-full appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:outline-none focus:ring-orange-400 sm:text-sm"
89
+ ) %>
90
+ < div class = "text-sm text-red-600 " > <%= error_tag ( f , :instagram ) %> </ div >
91
+ </ div >
92
+
93
+ < div >
94
+ <%= label ( f , :facebook , "Facebook Username" , class: "mb-1 text-sm font-medium text-gray-700" ) %>
95
+ <%= text_input ( f , :facebook ,
96
+ placeholder: "your_username" ,
97
+ class: "w-full appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:outline-none focus:ring-orange-400 sm:text-sm"
98
+ ) %>
99
+ < div class = "text-sm text-red-600 " > <%= error_tag ( f , :facebook ) %> </ div >
100
+ </ div >
101
+
102
+ < div >
103
+ <%= label ( f , :twitter , "X Username" , class: "mb-1 text-sm font-medium text-gray-700" ) %>
104
+ <%= text_input ( f , :twitter ,
105
+ placeholder: "your_username" ,
106
+ class: "w-full appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:outline-none focus:ring-orange-400 sm:text-sm"
107
+ ) %>
108
+ < div class = "text-sm text-red-600 " > <%= error_tag ( f , :twitter ) %> </ div >
109
+ </ div >
110
+
111
+ < div >
112
+ <%= label ( f , :tiktok , "TikTok Username" , class: "mb-1 text-sm font-medium text-gray-700" ) %>
113
+ <%= text_input ( f , :tiktok ,
114
+ placeholder: "your_username" ,
115
+ class: "w-full appearance-none rounded border border-zinc-300 px-3 py-2 text-zinc-900 placeholder-zinc-500 focus:z-10 focus:border-orange-400 focus:outline-none focus:ring-orange-400 sm:text-sm"
116
+ ) %>
117
+ < div class = "text-sm text-red-600 " > <%= error_tag ( f , :tiktok ) %> </ div >
118
+ </ div >
119
+ </ div >
120
+ <!-- Botões -->
121
+ < div class = "mt-8 flex w-full justify-end " >
122
+ < button type = "submit " class = "inline-flex rounded-md border-2 border-orange-500 bg-white px-6 py-2 text-sm font-medium text-orange-500 shadow-sm hover:bg-orange-600 hover:text-white " >
123
+ Save
124
+ </ button >
125
+ </ div >
126
+ </ . form >
127
+ </ div >
128
+ """
129
+ end
130
+
9
131
@ impl true
10
132
def mount ( socket ) do
11
133
{ :ok ,
12
134
socket
13
- |> allow_upload ( :picture , accept: @ extensions_whitelist , max_entries: 1 )
14
- |> allow_upload ( :cover_image , accept: @ extensions_whitelist , max_entries: 1 ) }
135
+ |> allow_upload ( :image ,
136
+ accept: Uploaders.ProfilePicture . extension_whitelist ( ) ,
137
+ max_entries: 1
138
+ ) }
15
139
end
16
140
17
141
@ impl true
18
142
def update ( % { user: user } = assigns , socket ) do
19
- user_changeset = Accounts . change_user ( user )
20
- socials_changeset = Socials . changeset ( % Socials { } , % { } )
21
-
22
- combined_changeset = % {
23
- user_changeset
24
- | changes: Map . merge ( user_changeset . changes , socials_changeset . changes )
25
- }
143
+ changeset = Accounts . change_user ( user )
26
144
27
145
{ :ok ,
28
146
socket
29
147
|> assign ( assigns )
30
- |> assign ( :changeset , combined_changeset ) }
148
+ |> assign ( :changeset , changeset ) }
31
149
end
32
150
33
151
@ impl true
@@ -41,41 +159,31 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
41
159
end
42
160
43
161
@ impl true
44
- def handle_event ( "save" , % { "user" => user_params , "socials" => socials_params } , socket ) do
162
+ def handle_event ( "save" , % { "user" => user_params } , socket ) do
45
163
user = socket . assigns . user
46
164
47
- socials_changeset = Socials . changeset ( % Socials { } , socials_params )
48
-
49
- case socials_changeset . valid? do
50
- true ->
51
- :ok
52
-
53
- false ->
54
- { :noreply , assign ( socket , :changeset , socials_changeset ) }
55
- end
165
+ flash_text =
166
+ if user_params [ "email" ] != user . email do
167
+ case Accounts . apply_user_email ( user , % { email: user_params [ "email" ] } ) do
168
+ { :ok , applied_user } ->
169
+ Accounts . deliver_update_email_instructions (
170
+ applied_user ,
171
+ user . email ,
172
+ & Routes . profile_edit_url ( socket , :confirm_email , & 1 )
173
+ )
174
+
175
+ "Profile updated successfully, please check your email to confirm the new address."
176
+ end
177
+ else
178
+ "Profile updated successfully."
179
+ end
56
180
57
181
case Accounts . update_user (
58
182
user ,
59
183
Map . put ( user_params , "email" , user . email ) ,
60
184
& consume_image_data ( socket , & 1 )
61
185
) do
62
186
{ :ok , _user } ->
63
- flash_text =
64
- if user_params [ "email" ] != user . email do
65
- case Accounts . apply_user_email ( user , % { email: user_params [ "email" ] } ) do
66
- { :ok , applied_user } ->
67
- Accounts . deliver_update_email_instructions (
68
- applied_user ,
69
- user . email ,
70
- & Routes . profile_edit_url ( socket , :confirm_email , & 1 )
71
- )
72
-
73
- "Profile updated successfully, please check your email to confirm the new address."
74
- end
75
- else
76
- "Profile updated successfully."
77
- end
78
-
79
187
{ :noreply ,
80
188
socket
81
189
|> put_flash ( :success , flash_text )
@@ -87,26 +195,12 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
87
195
end
88
196
89
197
defp consume_image_data ( socket , user ) do
90
- consume_uploaded_entries ( socket , :picture , fn % { path: path } , entry ->
91
- resized_path = resize_image ( path , 200 , 200 )
92
-
93
- Accounts . update_user ( user , % {
94
- "picture" => % Plug.Upload {
198
+ consume_uploaded_entries ( socket , :image , fn % { path: path } , entry ->
199
+ Accounts . update_user_picture ( user , % {
200
+ "profile_picture" => % Plug.Upload {
95
201
content_type: entry . client_type ,
96
202
filename: entry . client_name ,
97
- path: resized_path
98
- }
99
- } )
100
- end )
101
-
102
- consume_uploaded_entries ( socket , :cover_image , fn % { path: path } , entry ->
103
- resized_path = resize_image ( path , 800 , 250 )
104
-
105
- Accounts . update_user ( user , % {
106
- "cover_image" => % Plug.Upload {
107
- content_type: entry . client_type ,
108
- filename: entry . client_name ,
109
- path: resized_path
203
+ path: path
110
204
}
111
205
} )
112
206
end )
@@ -118,17 +212,4 @@ defmodule AtomicWeb.ProfileLive.FormComponent do
118
212
{ :ok , user }
119
213
end
120
214
end
121
-
122
- defp resize_image ( path , width , height ) do
123
- command = "convert"
124
- args = [ "-resize" , "#{ width } x#{ height } " , path , path ]
125
-
126
- case System . cmd ( command , args ) do
127
- { _ , 0 } ->
128
- { :ok , path }
129
-
130
- { error_msg , _ } ->
131
- { :error , error_msg }
132
- end
133
- end
134
215
end
0 commit comments