A website for the ATmosphereConf
at init 3.1 kB view raw
1--- 2interface Props { 3 displayName?: string 4 description?: string 5 avatar?: string 6 banner?: string 7 submitLabel?: string 8 action?: string 9} 10 11const { 12 displayName = '', 13 description = '', 14 avatar = '', 15 banner = '', 16 submitLabel = 'Create Profile', 17 action = '/api/profile/create' 18} = Astro.props 19--- 20 21<form 22 method="POST" 23 action={action} 24 enctype="multipart/form-data" 25 class="space-y-4" 26> 27 <div class="form-control"> 28 <label class="label"> 29 <span class="label-text">Display Name</span> 30 <span class="label-text-alt">Max 64 characters</span> 31 </label> 32 <input 33 type="text" 34 name="displayName" 35 placeholder="Enter your display name" 36 class="input input-bordered w-full" 37 value={displayName} 38 maxlength="64" 39 required 40 /> 41 </div> 42 43 <div class="form-control"> 44 <label class="label"> 45 <span class="label-text">Description</span> 46 <span class="label-text-alt">Max 256 characters</span> 47 </label> 48 <textarea 49 name="description" 50 placeholder="Tell us about yourself" 51 class="textarea textarea-bordered h-24" 52 maxlength="256" 53 >{description}</textarea> 54 </div> 55 56 <div class="form-control"> 57 <label class="label"> 58 <span class="label-text">Avatar</span> 59 <span class="label-text-alt">PNG or JPEG, max 1MB</span> 60 </label> 61 {avatar && ( 62 <div class="avatar mb-2"> 63 <div class="w-24 rounded-full"> 64 <img src={avatar} alt="Current avatar" /> 65 </div> 66 </div> 67 )} 68 <input 69 type="file" 70 name="avatar" 71 accept="image/png,image/jpeg" 72 class="file-input file-input-bordered w-full" 73 /> 74 </div> 75 76 <div class="form-control"> 77 <label class="label"> 78 <span class="label-text">Banner</span> 79 <span class="label-text-alt">PNG or JPEG, max 1MB</span> 80 </label> 81 {banner && ( 82 <div class="mb-2"> 83 <img src={banner} alt="Current banner" class="w-full h-32 object-cover rounded-lg" /> 84 </div> 85 )} 86 <input 87 type="file" 88 name="banner" 89 accept="image/png,image/jpeg" 90 class="file-input file-input-bordered w-full" 91 /> 92 </div> 93 94 <div class="form-control mt-6"> 95 <button type="submit" class="btn btn-primary w-full"> 96 {submitLabel} 97 </button> 98 </div> 99</form> 100 101<script> 102 // Client-side validation for file sizes 103 const form = document.querySelector('form') 104 if (form) { 105 form.addEventListener('submit', (e) => { 106 const avatarInput = form.querySelector('input[name="avatar"]') as HTMLInputElement 107 const bannerInput = form.querySelector('input[name="banner"]') as HTMLInputElement 108 109 const maxSize = 1000000 // 1MB 110 111 if (avatarInput?.files?.[0] && avatarInput.files[0].size > maxSize) { 112 e.preventDefault() 113 alert('Avatar file size must be less than 1MB') 114 return 115 } 116 117 if (bannerInput?.files?.[0] && bannerInput.files[0].size > maxSize) { 118 e.preventDefault() 119 alert('Banner file size must be less than 1MB') 120 return 121 } 122 }) 123 } 124</script>