diff --git a/src/pages/auth/register-page.ts b/src/pages/auth/register-page.ts index fd5e97b..0b6313b 100644 --- a/src/pages/auth/register-page.ts +++ b/src/pages/auth/register-page.ts @@ -1,13 +1,265 @@ -import { LitElement, html, css } from 'lit'; -import { customElement, state } from 'lit/decorators.js'; -import '../../components/auth-card.ts'; -import '../../components/form-input.ts'; -import '../../components/ui-button'; -import '../../components/notify-bar.ts'; -import '../../components/horizontal-divider'; -import '../../components/ui-link'; +import { LitElement, html, css } from "lit"; +import { customElement, state } from "lit/decorators.js"; +import "../../components/auth-card.ts"; +import "../../components/form-input.ts"; +import "../../components/ui-button"; +import "../../components/notify-bar.ts"; +import "../../components/horizontal-divider"; +import "../../components/ui-link"; -@customElement('register-page') +const COUNTRIES = [ + { code: "AD", label: "Andorra" }, + { code: "AE", label: "United Arab Emirates" }, + { code: "AF", label: "Afghanistan" }, + { code: "AG", label: "Antigua and Barbuda" }, + { code: "AI", label: "Anguilla" }, + { code: "AL", label: "Albania" }, + { code: "AM", label: "Armenia" }, + { code: "AO", label: "Angola" }, + { code: "AQ", label: "Antarctica" }, + { code: "AR", label: "Argentina" }, + { code: "AS", label: "American Samoa" }, + { code: "AT", label: "Austria" }, + { code: "AU", label: "Australia" }, + { code: "AW", label: "Aruba" }, + { code: "AX", label: "Åland Islands" }, + { code: "AZ", label: "Azerbaijan" }, + { code: "BA", label: "Bosnia and Herzegovina" }, + { code: "BB", label: "Barbados" }, + { code: "BD", label: "Bangladesh" }, + { code: "BE", label: "Belgium" }, + { code: "BF", label: "Burkina Faso" }, + { code: "BG", label: "Bulgaria" }, + { code: "BH", label: "Bahrain" }, + { code: "BI", label: "Burundi" }, + { code: "BJ", label: "Benin" }, + { code: "BL", label: "Saint Barthélemy" }, + { code: "BM", label: "Bermuda" }, + { code: "BN", label: "Brunei" }, + { code: "BO", label: "Bolivia" }, + { code: "BQ", label: "Bonaire, Sint Eustatius and Saba" }, + { code: "BR", label: "Brazil" }, + { code: "BS", label: "Bahamas" }, + { code: "BT", label: "Bhutan" }, + { code: "BV", label: "Bouvet Island" }, + { code: "BW", label: "Botswana" }, + { code: "BY", label: "Belarus" }, + { code: "BZ", label: "Belize" }, + { code: "CA", label: "Canada" }, + { code: "CC", label: "Cocos (Keeling) Islands" }, + { code: "CD", label: "Congo, Democratic Republic of the" }, + { code: "CF", label: "Central African Republic" }, + { code: "CG", label: "Congo" }, + { code: "CH", label: "Switzerland" }, + { code: "CI", label: "Côte d’Ivoire" }, + { code: "CK", label: "Cook Islands" }, + { code: "CL", label: "Chile" }, + { code: "CM", label: "Cameroon" }, + { code: "CN", label: "China" }, + { code: "CO", label: "Colombia" }, + { code: "CR", label: "Costa Rica" }, + { code: "CU", label: "Cuba" }, + { code: "CV", label: "Cabo Verde" }, + { code: "CW", label: "Curaçao" }, + { code: "CX", label: "Christmas Island" }, + { code: "CY", label: "Cyprus" }, + { code: "CZ", label: "Czechia" }, + { code: "DE", label: "Germany" }, + { code: "DJ", label: "Djibouti" }, + { code: "DK", label: "Denmark" }, + { code: "DM", label: "Dominica" }, + { code: "DO", label: "Dominican Republic" }, + { code: "DZ", label: "Algeria" }, + { code: "EC", label: "Ecuador" }, + { code: "EE", label: "Estonia" }, + { code: "EG", label: "Egypt" }, + { code: "EH", label: "Western Sahara" }, + { code: "ER", label: "Eritrea" }, + { code: "ES", label: "Spain" }, + { code: "ET", label: "Ethiopia" }, + { code: "FI", label: "Finland" }, + { code: "FJ", label: "Fiji" }, + { code: "FK", label: "Falkland Islands (Malvinas)" }, + { code: "FM", label: "Micronesia (Federated States of)" }, + { code: "FO", label: "Faroe Islands" }, + { code: "FR", label: "France" }, + { code: "GA", label: "Gabon" }, + { code: "GB", label: "United Kingdom" }, + { code: "GD", label: "Grenada" }, + { code: "GE", label: "Georgia" }, + { code: "GF", label: "French Guiana" }, + { code: "GG", label: "Guernsey" }, + { code: "GH", label: "Ghana" }, + { code: "GI", label: "Gibraltar" }, + { code: "GL", label: "Greenland" }, + { code: "GM", label: "Gambia" }, + { code: "GN", label: "Guinea" }, + { code: "GP", label: "Guadeloupe" }, + { code: "GQ", label: "Equatorial Guinea" }, + { code: "GR", label: "Greece" }, + { code: "GS", label: "South Georgia and the South Sandwich Islands" }, + { code: "GT", label: "Guatemala" }, + { code: "GU", label: "Guam" }, + { code: "GW", label: "Guinea-Bissau" }, + { code: "GY", label: "Guyana" }, + { code: "HK", label: "Hong Kong" }, + { code: "HM", label: "Heard Island and McDonald Islands" }, + { code: "HN", label: "Honduras" }, + { code: "HR", label: "Croatia" }, + { code: "HT", label: "Haiti" }, + { code: "HU", label: "Hungary" }, + { code: "ID", label: "Indonesia" }, + { code: "IE", label: "Ireland" }, + { code: "IL", label: "Israel" }, + { code: "IM", label: "Isle of Man" }, + { code: "IN", label: "India" }, + { code: "IO", label: "British Indian Ocean Territory" }, + { code: "IQ", label: "Iraq" }, + { code: "IR", label: "Iran" }, + { code: "IS", label: "Iceland" }, + { code: "IT", label: "Italy" }, + { code: "JE", label: "Jersey" }, + { code: "JM", label: "Jamaica" }, + { code: "JO", label: "Jordan" }, + { code: "JP", label: "Japan" }, + { code: "KE", label: "Kenya" }, + { code: "KG", label: "Kyrgyzstan" }, + { code: "KH", label: "Cambodia" }, + { code: "KI", label: "Kiribati" }, + { code: "KM", label: "Comoros" }, + { code: "KN", label: "Saint Kitts and Nevis" }, + { code: "KP", label: "North Korea" }, + { code: "KR", label: "South Korea" }, + { code: "KW", label: "Kuwait" }, + { code: "KY", label: "Cayman Islands" }, + { code: "KZ", label: "Kazakhstan" }, + { code: "LA", label: "Laos" }, + { code: "LB", label: "Lebanon" }, + { code: "LC", label: "Saint Lucia" }, + { code: "LI", label: "Liechtenstein" }, + { code: "LK", label: "Sri Lanka" }, + { code: "LR", label: "Liberia" }, + { code: "LS", label: "Lesotho" }, + { code: "LT", label: "Lithuania" }, + { code: "LU", label: "Luxembourg" }, + { code: "LV", label: "Latvia" }, + { code: "LY", label: "Libya" }, + { code: "MA", label: "Morocco" }, + { code: "MC", label: "Monaco" }, + { code: "MD", label: "Moldova" }, + { code: "ME", label: "Montenegro" }, + { code: "MF", label: "Saint Martin (French part)" }, + { code: "MG", label: "Madagascar" }, + { code: "MH", label: "Marshall Islands" }, + { code: "MK", label: "North Macedonia" }, + { code: "ML", label: "Mali" }, + { code: "MM", label: "Myanmar" }, + { code: "MN", label: "Mongolia" }, + { code: "MO", label: "Macao" }, + { code: "MP", label: "Northern Mariana Islands" }, + { code: "MQ", label: "Martinique" }, + { code: "MR", label: "Mauritania" }, + { code: "MS", label: "Montserrat" }, + { code: "MT", label: "Malta" }, + { code: "MU", label: "Mauritius" }, + { code: "MV", label: "Maldives" }, + { code: "MW", label: "Malawi" }, + { code: "MX", label: "Mexico" }, + { code: "MY", label: "Malaysia" }, + { code: "MZ", label: "Mozambique" }, + { code: "NA", label: "Namibia" }, + { code: "NC", label: "New Caledonia" }, + { code: "NE", label: "Niger" }, + { code: "NF", label: "Norfolk Island" }, + { code: "NG", label: "Nigeria" }, + { code: "NI", label: "Nicaragua" }, + { code: "NL", label: "Netherlands" }, + { code: "NO", label: "Norway" }, + { code: "NP", label: "Nepal" }, + { code: "NR", label: "Nauru" }, + { code: "NU", label: "Niue" }, + { code: "NZ", label: "New Zealand" }, + { code: "OM", label: "Oman" }, + { code: "PA", label: "Panama" }, + { code: "PE", label: "Peru" }, + { code: "PF", label: "French Polynesia" }, + { code: "PG", label: "Papua New Guinea" }, + { code: "PH", label: "Philippines" }, + { code: "PK", label: "Pakistan" }, + { code: "PL", label: "Poland" }, + { code: "PM", label: "Saint Pierre and Miquelon" }, + { code: "PN", label: "Pitcairn" }, + { code: "PR", label: "Puerto Rico" }, + { code: "PS", label: "Palestine" }, + { code: "PT", label: "Portugal" }, + { code: "PW", label: "Palau" }, + { code: "PY", label: "Paraguay" }, + { code: "QA", label: "Qatar" }, + { code: "RE", label: "Réunion" }, + { code: "RO", label: "Romania" }, + { code: "RS", label: "Serbia" }, + { code: "RU", label: "Russia" }, + { code: "RW", label: "Rwanda" }, + { code: "SA", label: "Saudi Arabia" }, + { code: "SB", label: "Solomon Islands" }, + { code: "SC", label: "Seychelles" }, + { code: "SD", label: "Sudan" }, + { code: "SE", label: "Sweden" }, + { code: "SG", label: "Singapore" }, + { code: "SH", label: "Saint Helena, Ascension and Tristan da Cunha" }, + { code: "SI", label: "Slovenia" }, + { code: "SJ", label: "Svalbard and Jan Mayen" }, + { code: "SK", label: "Slovakia" }, + { code: "SL", label: "Sierra Leone" }, + { code: "SM", label: "San Marino" }, + { code: "SN", label: "Senegal" }, + { code: "SO", label: "Somalia" }, + { code: "SR", label: "Suriname" }, + { code: "SS", label: "South Sudan" }, + { code: "ST", label: "São Tomé and Príncipe" }, + { code: "SV", label: "El Salvador" }, + { code: "SX", label: "Sint Maarten (Dutch part)" }, + { code: "SY", label: "Syria" }, + { code: "SZ", label: "Eswatini" }, + { code: "TC", label: "Turks and Caicos Islands" }, + { code: "TD", label: "Chad" }, + { code: "TF", label: "French Southern Territories" }, + { code: "TG", label: "Togo" }, + { code: "TH", label: "Thailand" }, + { code: "TJ", label: "Tajikistan" }, + { code: "TK", label: "Tokelau" }, + { code: "TL", label: "Timor-Leste" }, + { code: "TM", label: "Turkmenistan" }, + { code: "TN", label: "Tunisia" }, + { code: "TO", label: "Tonga" }, + { code: "TR", label: "Turkey" }, + { code: "TT", label: "Trinidad and Tobago" }, + { code: "TV", label: "Tuvalu" }, + { code: "TW", label: "Taiwan" }, + { code: "TZ", label: "Tanzania" }, + { code: "UA", label: "Ukraine" }, + { code: "UG", label: "Uganda" }, + { code: "UM", label: "United States Minor Outlying Islands" }, + { code: "US", label: "United States" }, + { code: "UY", label: "Uruguay" }, + { code: "UZ", label: "Uzbekistan" }, + { code: "VA", label: "Vatican City" }, + { code: "VC", label: "Saint Vincent and the Grenadines" }, + { code: "VE", label: "Venezuela" }, + { code: "VG", label: "Virgin Islands (British)" }, + { code: "VI", label: "Virgin Islands (U.S.)" }, + { code: "VN", label: "Vietnam" }, + { code: "VU", label: "Vanuatu" }, + { code: "WF", label: "Wallis and Futuna" }, + { code: "WS", label: "Samoa" }, + { code: "YE", label: "Yemen" }, + { code: "YT", label: "Mayotte" }, + { code: "ZA", label: "South Africa" }, + { code: "ZM", label: "Zambia" }, + { code: "ZW", label: "Zimbabwe" }, +]; + +@customElement("register-page") export class RegisterPage extends LitElement { static styles = css` :host { @@ -21,59 +273,288 @@ export class RegisterPage extends LitElement { color: color-mix(in srgb, var(--color-text) 60%, transparent); margin: 0; } + + .dropdown-search { + width: 100%; + box-sizing: border-box; + padding: 8px 12px; + border: none; + border-bottom: 1px solid + color-mix(in srgb, var(--color-text) 12%, transparent); + background: transparent; + color: var(--color-text); + font-size: 0.9375rem; + outline: none; + } + + .dropdown-search::placeholder { + color: color-mix(in srgb, var(--color-text) 35%, transparent); + } + + .dropdown-wrapper { + display: flex; + flex-direction: column; + gap: 6px; + position: relative; + } + + .dropdown-label { + font-size: 0.75rem; + font-weight: 600; + letter-spacing: 0.05em; + text-transform: uppercase; + color: color-mix(in srgb, var(--color-text) 70%, transparent); + } + + .dropdown-trigger { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 14px; + border-radius: 8px; + border: 1px solid color-mix(in srgb, var(--color-text) 15%, transparent); + background: color-mix(in srgb, var(--color-text) 5%, transparent); + color: var(--color-text); + font-size: 0.9375rem; + cursor: pointer; + user-select: none; + transition: border-color 0.2s; + } + + .dropdown-trigger:hover, + .dropdown-trigger.open { + border-color: color-mix(in srgb, var(--color-text) 35%, transparent); + } + + .dropdown-trigger .placeholder { + color: color-mix(in srgb, var(--color-text) 35%, transparent); + } + + .chevron { + width: 16px; + height: 16px; + flex-shrink: 0; + color: color-mix(in srgb, var(--color-text) 50%, transparent); + transition: transform 0.2s; + } + + .chevron.open { + transform: rotate(180deg); + } + + .dropdown-list { + position: absolute; + top: calc(100% + 4px); + left: 0; + right: 0; + z-index: 100; + background: var(--color-surface-elevated, #2a2a2a); + border: 1px solid color-mix(in srgb, var(--color-text) 15%, transparent); + border-radius: 8px; + overflow: hidden; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35); + } + + .dropdown-scroll { + max-height: 220px; + overflow-y: auto; + scrollbar-width: thin; + scrollbar-color: color-mix(in srgb, var(--color-text) 20%, transparent) + transparent; + } + + .dropdown-item { + padding: 10px 14px; + font-size: 0.9375rem; + color: var(--color-text); + cursor: pointer; + transition: background 0.15s; + } + + .dropdown-item:hover { + background: color-mix(in srgb, var(--color-text) 8%, transparent); + } + + .dropdown-item.selected { + background: color-mix(in srgb, var(--color-text) 15%, transparent); + font-weight: 500; + } `; - @state() name = ''; - @state() email = ''; - @state() password = ''; + @state() dropdownSearch = ""; + + @state() firstname = ""; + @state() lastname = ""; + @state() email = ""; + @state() phonenumber = ""; + @state() country = ""; + @state() password = ""; @state() error: string | null = null; @state() loading = false; + @state() dropdownOpen = false; + + private toggleDropdown() { + this.dropdownOpen = !this.dropdownOpen; + if (!this.dropdownOpen) this.dropdownSearch = ""; + } + private selectCountry(code: string) { + this.country = code; + this.dropdownOpen = false; + this.dropdownSearch = ""; + } + + private handleOutsideClick = (e: MouseEvent) => { + const path = e.composedPath(); + if (!path.includes(this)) { + this.dropdownOpen = false; + } + }; + + connectedCallback() { + super.connectedCallback(); + document.addEventListener("click", this.handleOutsideClick); + } + + disconnectedCallback() { + super.disconnectedCallback(); + document.removeEventListener("click", this.handleOutsideClick); + } async handleRegister() { this.error = null; this.loading = true; try { - //const response = await fetch('/api/auth/register', { - const response = await fetch('http://127.0.0.1:8080/auth/register', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, + const response = await fetch("http://127.0.0.1:8080/auth/register", { + method: "POST", + headers: { "Content-Type": "application/json" }, body: JSON.stringify({ - name: this.name, + firstName: this.firstname, + lastName: this.lastname, email: this.email, + phoneNumber: this.phonenumber, + country: this.country, password: this.password, }), }); if (!response.ok) { const err = await response.json().catch(() => null); - this.error = err?.message ?? 'Registration failed'; + this.error = err?.message ?? "Registration failed"; return; } - window.dispatchEvent(new CustomEvent('nav', { - detail: { path: '/login' }, - bubbles: true, - composed: true, - })); + window.dispatchEvent( + new CustomEvent("nav", { + detail: { path: "/login" }, + bubbles: true, + composed: true, + }), + ); } catch { - this.error = 'Netzwerkfehler. Bitte erneut versuchen.'; + this.error = "Netzwerkfehler. Bitte erneut versuchen."; } finally { this.loading = false; } } + private renderDropdown() { + const selected = COUNTRIES.find((c) => c.code === this.country); + const filtered = COUNTRIES.filter((c) => + c.label.toLowerCase().includes(this.dropdownSearch.toLowerCase()), + ); + + return html` + + `; + } + render() { return html` - (this.name = e.detail.value)} - > +
+ + (this.firstname = e.detail.value)} + style="flex: 1; min-width: 0;" + > + + + (this.lastname = e.detail.value)} + style="flex: 1; min-width: 0;" + > +
(this.email = e.detail.value)} > + + (this.phonenumber = e.detail.value)} + > + + ${this.renderDropdown()} + - ${this.loading ? 'Creating account...' : 'Create account'} + ${this.loading ? "Creating account..." : "Create account"} @@ -106,4 +598,4 @@ export class RegisterPage extends LitElement {
`; } -} \ No newline at end of file +}