* feat: add Form to UserSettingProfile * feat: submit user information * feat: submit new password to backendtags/v0.1.0
| @@ -15,3 +15,424 @@ export const UserSettingRouteMap = { | |||
| [UserSettingRouteKey.Team]: 'Team', | |||
| [UserSettingRouteKey.Logout]: 'Log out', | |||
| }; | |||
| export const TimezoneList = [ | |||
| 'UTC-11\tPacific/Midway', | |||
| 'UTC-11\tPacific/Niue', | |||
| 'UTC-11\tPacific/Pago_Pago', | |||
| 'UTC-10\tAmerica/Adak', | |||
| 'UTC-10\tPacific/Honolulu', | |||
| 'UTC-10\tPacific/Rarotonga', | |||
| 'UTC-10\tPacific/Tahiti', | |||
| 'UTC-9:30\tPacific/Marquesas', | |||
| 'UTC-9\tAmerica/Anchorage', | |||
| 'UTC-9\tAmerica/Juneau', | |||
| 'UTC-9\tAmerica/Metlakatla', | |||
| 'UTC-9\tAmerica/Nome', | |||
| 'UTC-9\tAmerica/Sitka', | |||
| 'UTC-9\tAmerica/Yakutat', | |||
| 'UTC-9\tPacific/Gambier', | |||
| 'UTC-8\tAmerica/Los_Angeles', | |||
| 'UTC-8\tAmerica/Tijuana', | |||
| 'UTC-8\tAmerica/Vancouver', | |||
| 'UTC-8\tPacific/Pitcairn', | |||
| 'UTC-7\tAmerica/Boise', | |||
| 'UTC-7\tAmerica/Cambridge_Bay', | |||
| 'UTC-7\tAmerica/Ciudad_Juarez', | |||
| 'UTC-7\tAmerica/Creston', | |||
| 'UTC-7\tAmerica/Dawson', | |||
| 'UTC-7\tAmerica/Dawson_Creek', | |||
| 'UTC-7\tAmerica/Denver', | |||
| 'UTC-7\tAmerica/Edmonton', | |||
| 'UTC-7\tAmerica/Fort_Nelson', | |||
| 'UTC-7\tAmerica/Hermosillo', | |||
| 'UTC-7\tAmerica/Inuvik', | |||
| 'UTC-7\tAmerica/Mazatlan', | |||
| 'UTC-7\tAmerica/Phoenix', | |||
| 'UTC-7\tAmerica/Whitehorse', | |||
| 'UTC-7\tAmerica/Yellowknife', | |||
| 'UTC-6\tAmerica/Bahia_Banderas', | |||
| 'UTC-6\tAmerica/Belize', | |||
| 'UTC-6\tAmerica/Chicago', | |||
| 'UTC-6\tAmerica/Chihuahua', | |||
| 'UTC-6\tAmerica/Costa_Rica', | |||
| 'UTC-6\tAmerica/El_Salvador', | |||
| 'UTC-6\tAmerica/Guatemala', | |||
| 'UTC-6\tAmerica/Indiana/Knox', | |||
| 'UTC-6\tAmerica/Indiana/Tell_City', | |||
| 'UTC-6\tAmerica/Managua', | |||
| 'UTC-6\tAmerica/Matamoros', | |||
| 'UTC-6\tAmerica/Menominee', | |||
| 'UTC-6\tAmerica/Merida', | |||
| 'UTC-6\tAmerica/Mexico_City', | |||
| 'UTC-6\tAmerica/Monterrey', | |||
| 'UTC-6\tAmerica/North_Dakota/Beulah', | |||
| 'UTC-6\tAmerica/North_Dakota/Center', | |||
| 'UTC-6\tAmerica/North_Dakota/New_Salem', | |||
| 'UTC-6\tAmerica/Ojinaga', | |||
| 'UTC-6\tAmerica/Rankin_Inlet', | |||
| 'UTC-6\tAmerica/Regina', | |||
| 'UTC-6\tAmerica/Resolute', | |||
| 'UTC-6\tAmerica/Swift_Current', | |||
| 'UTC-6\tAmerica/Tegucigalpa', | |||
| 'UTC-6\tAmerica/Winnipeg', | |||
| 'UTC-6\tPacific/Easter', | |||
| 'UTC-6\tPacific/Galapagos', | |||
| 'UTC-5\tAmerica/Atikokan', | |||
| 'UTC-5\tAmerica/Bogota', | |||
| 'UTC-5\tAmerica/Cancun', | |||
| 'UTC-5\tAmerica/Cayman', | |||
| 'UTC-5\tAmerica/Detroit', | |||
| 'UTC-5\tAmerica/Eirunepe', | |||
| 'UTC-5\tAmerica/Grand_Turk', | |||
| 'UTC-5\tAmerica/Guayaquil', | |||
| 'UTC-5\tAmerica/Havana', | |||
| 'UTC-5\tAmerica/Indiana/Indianapolis', | |||
| 'UTC-5\tAmerica/Indiana/Marengo', | |||
| 'UTC-5\tAmerica/Indiana/Petersburg', | |||
| 'UTC-5\tAmerica/Indiana/Vevay', | |||
| 'UTC-5\tAmerica/Indiana/Vincennes', | |||
| 'UTC-5\tAmerica/Indiana/Winamac', | |||
| 'UTC-5\tAmerica/Iqaluit', | |||
| 'UTC-5\tAmerica/Jamaica', | |||
| 'UTC-5\tAmerica/Kentucky/Louisville', | |||
| 'UTC-5\tAmerica/Kentucky/Monticello', | |||
| 'UTC-5\tAmerica/Lima', | |||
| 'UTC-5\tAmerica/Nassau', | |||
| 'UTC-5\tAmerica/New_York', | |||
| 'UTC-5\tAmerica/Panama', | |||
| 'UTC-5\tAmerica/Port-au-Prince', | |||
| 'UTC-5\tAmerica/Rio_Branco', | |||
| 'UTC-5\tAmerica/Toronto', | |||
| 'UTC-4\tAmerica/Anguilla', | |||
| 'UTC-4\tAmerica/Antigua', | |||
| 'UTC-4\tAmerica/Aruba', | |||
| 'UTC-4\tAmerica/Asuncion', | |||
| 'UTC-4\tAmerica/Barbados', | |||
| 'UTC-4\tAmerica/Blanc-Sablon', | |||
| 'UTC-4\tAmerica/Boa_Vista', | |||
| 'UTC-4\tAmerica/Campo_Grande', | |||
| 'UTC-4\tAmerica/Caracas', | |||
| 'UTC-4\tAmerica/Cuiaba', | |||
| 'UTC-4\tAmerica/Curacao', | |||
| 'UTC-4\tAmerica/Dominica', | |||
| 'UTC-4\tAmerica/Glace_Bay', | |||
| 'UTC-4\tAmerica/Goose_Bay', | |||
| 'UTC-4\tAmerica/Grenada', | |||
| 'UTC-4\tAmerica/Guadeloupe', | |||
| 'UTC-4\tAmerica/Guyana', | |||
| 'UTC-4\tAmerica/Halifax', | |||
| 'UTC-4\tAmerica/Kralendijk', | |||
| 'UTC-4\tAmerica/La_Paz', | |||
| 'UTC-4\tAmerica/Lower_Princes', | |||
| 'UTC-4\tAmerica/Manaus', | |||
| 'UTC-4\tAmerica/Marigot', | |||
| 'UTC-4\tAmerica/Martinique', | |||
| 'UTC-4\tAmerica/Moncton', | |||
| 'UTC-4\tAmerica/Montserrat', | |||
| 'UTC-4\tAmerica/Porto_Velho', | |||
| 'UTC-4\tAmerica/Port_of_Spain', | |||
| 'UTC-4\tAmerica/Puerto_Rico', | |||
| 'UTC-4\tAmerica/Santiago', | |||
| 'UTC-4\tAmerica/Santo_Domingo', | |||
| 'UTC-4\tAmerica/St_Barthelemy', | |||
| 'UTC-4\tAmerica/St_Kitts', | |||
| 'UTC-4\tAmerica/St_Lucia', | |||
| 'UTC-4\tAmerica/St_Thomas', | |||
| 'UTC-4\tAmerica/St_Vincent', | |||
| 'UTC-4\tAmerica/Thule', | |||
| 'UTC-4\tAmerica/Tortola', | |||
| 'UTC-4\tAtlantic/Bermuda', | |||
| 'UTC-3:30\tAmerica/St_Johns', | |||
| 'UTC-3\tAmerica/Araguaina', | |||
| 'UTC-3\tAmerica/Argentina/Buenos_Aires', | |||
| 'UTC-3\tAmerica/Argentina/Catamarca', | |||
| 'UTC-3\tAmerica/Argentina/Cordoba', | |||
| 'UTC-3\tAmerica/Argentina/Jujuy', | |||
| 'UTC-3\tAmerica/Argentina/La_Rioja', | |||
| 'UTC-3\tAmerica/Argentina/Mendoza', | |||
| 'UTC-3\tAmerica/Argentina/Rio_Gallegos', | |||
| 'UTC-3\tAmerica/Argentina/Salta', | |||
| 'UTC-3\tAmerica/Argentina/San_Juan', | |||
| 'UTC-3\tAmerica/Argentina/San_Luis', | |||
| 'UTC-3\tAmerica/Argentina/Tucuman', | |||
| 'UTC-3\tAmerica/Argentina/Ushuaia', | |||
| 'UTC-3\tAmerica/Bahia', | |||
| 'UTC-3\tAmerica/Belem', | |||
| 'UTC-3\tAmerica/Cayenne', | |||
| 'UTC-3\tAmerica/Fortaleza', | |||
| 'UTC-3\tAmerica/Maceio', | |||
| 'UTC-3\tAmerica/Miquelon', | |||
| 'UTC-3\tAmerica/Montevideo', | |||
| 'UTC-3\tAmerica/Paramaribo', | |||
| 'UTC-3\tAmerica/Punta_Arenas', | |||
| 'UTC-3\tAmerica/Recife', | |||
| 'UTC-3\tAmerica/Santarem', | |||
| 'UTC-3\tAmerica/Sao_Paulo', | |||
| 'UTC-3\tAntarctica/Palmer', | |||
| 'UTC-3\tAntarctica/Rothera', | |||
| 'UTC-3\tAtlantic/Stanley', | |||
| 'UTC-2\tAmerica/Noronha', | |||
| 'UTC-2\tAmerica/Nuuk', | |||
| 'UTC-2\tAtlantic/South_Georgia', | |||
| 'UTC-1\tAmerica/Scoresbysund', | |||
| 'UTC-1\tAtlantic/Azores', | |||
| 'UTC-1\tAtlantic/Cape_Verde', | |||
| 'UTC+0\tAfrica/Abidjan', | |||
| 'UTC+0\tAfrica/Accra', | |||
| 'UTC+0\tAfrica/Bamako', | |||
| 'UTC+0\tAfrica/Banjul', | |||
| 'UTC+0\tAfrica/Bissau', | |||
| 'UTC+0\tAfrica/Casablanca', | |||
| 'UTC+0\tAfrica/Conakry', | |||
| 'UTC+0\tAfrica/Dakar', | |||
| 'UTC+0\tAfrica/El_Aaiun', | |||
| 'UTC+0\tAfrica/Freetown', | |||
| 'UTC+0\tAfrica/Lome', | |||
| 'UTC+0\tAfrica/Monrovia', | |||
| 'UTC+0\tAfrica/Nouakchott', | |||
| 'UTC+0\tAfrica/Ouagadougou', | |||
| 'UTC+0\tAfrica/Sao_Tome', | |||
| 'UTC+0\tAmerica/Danmarkshavn', | |||
| 'UTC+0\tAntarctica/Troll', | |||
| 'UTC+0\tAtlantic/Canary', | |||
| 'UTC+0\tAtlantic/Faroe', | |||
| 'UTC+0\tAtlantic/Madeira', | |||
| 'UTC+0\tAtlantic/Reykjavik', | |||
| 'UTC+0\tAtlantic/St_Helena', | |||
| 'UTC+0\tEurope/Dublin', | |||
| 'UTC+0\tEurope/Guernsey', | |||
| 'UTC+0\tEurope/Isle_of_Man', | |||
| 'UTC+0\tEurope/Jersey', | |||
| 'UTC+0\tEurope/Lisbon', | |||
| 'UTC+0\tEurope/London', | |||
| 'UTC+1\tAfrica/Algiers', | |||
| 'UTC+1\tAfrica/Bangui', | |||
| 'UTC+1\tAfrica/Brazzaville', | |||
| 'UTC+1\tAfrica/Ceuta', | |||
| 'UTC+1\tAfrica/Douala', | |||
| 'UTC+1\tAfrica/Kinshasa', | |||
| 'UTC+1\tAfrica/Lagos', | |||
| 'UTC+1\tAfrica/Libreville', | |||
| 'UTC+1\tAfrica/Luanda', | |||
| 'UTC+1\tAfrica/Malabo', | |||
| 'UTC+1\tAfrica/Ndjamena', | |||
| 'UTC+1\tAfrica/Niamey', | |||
| 'UTC+1\tAfrica/Porto-Novo', | |||
| 'UTC+1\tAfrica/Tunis', | |||
| 'UTC+1\tAfrica/Windhoek', | |||
| 'UTC+1\tArctic/Longyearbyen', | |||
| 'UTC+1\tEurope/Amsterdam', | |||
| 'UTC+1\tEurope/Andorra', | |||
| 'UTC+1\tEurope/Belgrade', | |||
| 'UTC+1\tEurope/Berlin', | |||
| 'UTC+1\tEurope/Bratislava', | |||
| 'UTC+1\tEurope/Brussels', | |||
| 'UTC+1\tEurope/Budapest', | |||
| 'UTC+1\tEurope/Copenhagen', | |||
| 'UTC+1\tEurope/Gibraltar', | |||
| 'UTC+1\tEurope/Ljubljana', | |||
| 'UTC+1\tEurope/Luxembourg', | |||
| 'UTC+1\tEurope/Madrid', | |||
| 'UTC+1\tEurope/Malta', | |||
| 'UTC+1\tEurope/Monaco', | |||
| 'UTC+1\tEurope/Oslo', | |||
| 'UTC+1\tEurope/Paris', | |||
| 'UTC+1\tEurope/Podgorica', | |||
| 'UTC+1\tEurope/Prague', | |||
| 'UTC+1\tEurope/Rome', | |||
| 'UTC+1\tEurope/San_Marino', | |||
| 'UTC+1\tEurope/Sarajevo', | |||
| 'UTC+1\tEurope/Skopje', | |||
| 'UTC+1\tEurope/Stockholm', | |||
| 'UTC+1\tEurope/Tirane', | |||
| 'UTC+1\tEurope/Vaduz', | |||
| 'UTC+1\tEurope/Vatican', | |||
| 'UTC+1\tEurope/Vienna', | |||
| 'UTC+1\tEurope/Warsaw', | |||
| 'UTC+1\tEurope/Zagreb', | |||
| 'UTC+1\tEurope/Zurich', | |||
| 'UTC+2\tAfrica/Blantyre', | |||
| 'UTC+2\tAfrica/Bujumbura', | |||
| 'UTC+2\tAfrica/Cairo', | |||
| 'UTC+2\tAfrica/Gaborone', | |||
| 'UTC+2\tAfrica/Harare', | |||
| 'UTC+2\tAfrica/Johannesburg', | |||
| 'UTC+2\tAfrica/Juba', | |||
| 'UTC+2\tAfrica/Khartoum', | |||
| 'UTC+2\tAfrica/Kigali', | |||
| 'UTC+2\tAfrica/Lubumbashi', | |||
| 'UTC+2\tAfrica/Lusaka', | |||
| 'UTC+2\tAfrica/Maputo', | |||
| 'UTC+2\tAfrica/Maseru', | |||
| 'UTC+2\tAfrica/Mbabane', | |||
| 'UTC+2\tAfrica/Tripoli', | |||
| 'UTC+2\tAsia/Beirut', | |||
| 'UTC+2\tAsia/Famagusta', | |||
| 'UTC+2\tAsia/Gaza', | |||
| 'UTC+2\tAsia/Hebron', | |||
| 'UTC+2\tAsia/Jerusalem', | |||
| 'UTC+2\tAsia/Nicosia', | |||
| 'UTC+2\tEurope/Athens', | |||
| 'UTC+2\tEurope/Bucharest', | |||
| 'UTC+2\tEurope/Chisinau', | |||
| 'UTC+2\tEurope/Helsinki', | |||
| 'UTC+2\tEurope/Kaliningrad', | |||
| 'UTC+2\tEurope/Kyiv', | |||
| 'UTC+2\tEurope/Mariehamn', | |||
| 'UTC+2\tEurope/Riga', | |||
| 'UTC+2\tEurope/Sofia', | |||
| 'UTC+2\tEurope/Tallinn', | |||
| 'UTC+2\tEurope/Vilnius', | |||
| 'UTC+3\tAfrica/Addis_Ababa', | |||
| 'UTC+3\tAfrica/Asmara', | |||
| 'UTC+3\tAfrica/Dar_es_Salaam', | |||
| 'UTC+3\tAfrica/Djibouti', | |||
| 'UTC+3\tAfrica/Kampala', | |||
| 'UTC+3\tAfrica/Mogadishu', | |||
| 'UTC+3\tAfrica/Nairobi', | |||
| 'UTC+3\tAntarctica/Syowa', | |||
| 'UTC+3\tAsia/Aden', | |||
| 'UTC+3\tAsia/Amman', | |||
| 'UTC+3\tAsia/Baghdad', | |||
| 'UTC+3\tAsia/Bahrain', | |||
| 'UTC+3\tAsia/Damascus', | |||
| 'UTC+3\tAsia/Kuwait', | |||
| 'UTC+3\tAsia/Qatar', | |||
| 'UTC+3\tAsia/Riyadh', | |||
| 'UTC+3\tEurope/Istanbul', | |||
| 'UTC+3\tEurope/Kirov', | |||
| 'UTC+3\tEurope/Minsk', | |||
| 'UTC+3\tEurope/Moscow', | |||
| 'UTC+3\tEurope/Simferopol', | |||
| 'UTC+3\tEurope/Volgograd', | |||
| 'UTC+3\tIndian/Antananarivo', | |||
| 'UTC+3\tIndian/Comoro', | |||
| 'UTC+3\tIndian/Mayotte', | |||
| 'UTC+3:30\tAsia/Tehran', | |||
| 'UTC+4\tAsia/Baku', | |||
| 'UTC+4\tAsia/Dubai', | |||
| 'UTC+4\tAsia/Muscat', | |||
| 'UTC+4\tAsia/Tbilisi', | |||
| 'UTC+4\tAsia/Yerevan', | |||
| 'UTC+4\tEurope/Astrakhan', | |||
| 'UTC+4\tEurope/Samara', | |||
| 'UTC+4\tEurope/Saratov', | |||
| 'UTC+4\tEurope/Ulyanovsk', | |||
| 'UTC+4\tIndian/Mahe', | |||
| 'UTC+4\tIndian/Mauritius', | |||
| 'UTC+4\tIndian/Reunion', | |||
| 'UTC+4:30\tAsia/Kabul', | |||
| 'UTC+5\tAntarctica/Mawson', | |||
| 'UTC+5\tAsia/Aqtau', | |||
| 'UTC+5\tAsia/Aqtobe', | |||
| 'UTC+5\tAsia/Ashgabat', | |||
| 'UTC+5\tAsia/Atyrau', | |||
| 'UTC+5\tAsia/Dushanbe', | |||
| 'UTC+5\tAsia/Karachi', | |||
| 'UTC+5\tAsia/Oral', | |||
| 'UTC+5\tAsia/Qyzylorda', | |||
| 'UTC+5\tAsia/Samarkand', | |||
| 'UTC+5\tAsia/Tashkent', | |||
| 'UTC+5\tAsia/Yekaterinburg', | |||
| 'UTC+5\tIndian/Kerguelen', | |||
| 'UTC+5\tIndian/Maldives', | |||
| 'UTC+5:30\tAsia/Colombo', | |||
| 'UTC+5:30\tAsia/Kolkata', | |||
| 'UTC+5:45\tAsia/Kathmandu', | |||
| 'UTC+6\tAntarctica/Vostok', | |||
| 'UTC+6\tAsia/Almaty', | |||
| 'UTC+6\tAsia/Bishkek', | |||
| 'UTC+6\tAsia/Dhaka', | |||
| 'UTC+6\tAsia/Omsk', | |||
| 'UTC+6\tAsia/Qostanay', | |||
| 'UTC+6\tAsia/Thimphu', | |||
| 'UTC+6\tAsia/Urumqi', | |||
| 'UTC+6\tIndian/Chagos', | |||
| 'UTC+6:30\tAsia/Yangon', | |||
| 'UTC+6:30\tIndian/Cocos', | |||
| 'UTC+7\tAntarctica/Davis', | |||
| 'UTC+7\tAsia/Bangkok', | |||
| 'UTC+7\tAsia/Barnaul', | |||
| 'UTC+7\tAsia/Hovd', | |||
| 'UTC+7\tAsia/Ho_Chi_Minh', | |||
| 'UTC+7\tAsia/Jakarta', | |||
| 'UTC+7\tAsia/Krasnoyarsk', | |||
| 'UTC+7\tAsia/Novokuznetsk', | |||
| 'UTC+7\tAsia/Novosibirsk', | |||
| 'UTC+7\tAsia/Phnom_Penh', | |||
| 'UTC+7\tAsia/Pontianak', | |||
| 'UTC+7\tAsia/Tomsk', | |||
| 'UTC+7\tAsia/Vientiane', | |||
| 'UTC+7\tIndian/Christmas', | |||
| 'UTC+8\tAsia/Brunei', | |||
| 'UTC+8\tAsia/Choibalsan', | |||
| 'UTC+8\tAsia/Hong_Kong', | |||
| 'UTC+8\tAsia/Irkutsk', | |||
| 'UTC+8\tAsia/Kuala_Lumpur', | |||
| 'UTC+8\tAsia/Kuching', | |||
| 'UTC+8\tAsia/Macau', | |||
| 'UTC+8\tAsia/Makassar', | |||
| 'UTC+8\tAsia/Manila', | |||
| 'UTC+8\tAsia/Shanghai', | |||
| 'UTC+8\tAsia/Singapore', | |||
| 'UTC+8\tAsia/Taipei', | |||
| 'UTC+8\tAsia/Ulaanbaatar', | |||
| 'UTC+8\tAustralia/Perth', | |||
| 'UTC+8:45\tAustralia/Eucla', | |||
| 'UTC+9\tAsia/Chita', | |||
| 'UTC+9\tAsia/Dili', | |||
| 'UTC+9\tAsia/Jayapura', | |||
| 'UTC+9\tAsia/Khandyga', | |||
| 'UTC+9\tAsia/Pyongyang', | |||
| 'UTC+9\tAsia/Seoul', | |||
| 'UTC+9\tAsia/Tokyo', | |||
| 'UTC+9\tAsia/Yakutsk', | |||
| 'UTC+9\tPacific/Palau', | |||
| 'UTC+9:30\tAustralia/Adelaide', | |||
| 'UTC+9:30\tAustralia/Broken_Hill', | |||
| 'UTC+9:30\tAustralia/Darwin', | |||
| 'UTC+10\tAntarctica/DumontDUrville', | |||
| 'UTC+10\tAntarctica/Macquarie', | |||
| 'UTC+10\tAsia/Ust-Nera', | |||
| 'UTC+10\tAsia/Vladivostok', | |||
| 'UTC+10\tAustralia/Brisbane', | |||
| 'UTC+10\tAustralia/Hobart', | |||
| 'UTC+10\tAustralia/Lindeman', | |||
| 'UTC+10\tAustralia/Melbourne', | |||
| 'UTC+10\tAustralia/Sydney', | |||
| 'UTC+10\tPacific/Chuuk', | |||
| 'UTC+10\tPacific/Guam', | |||
| 'UTC+10\tPacific/Port_Moresby', | |||
| 'UTC+10\tPacific/Saipan', | |||
| 'UTC+10:30\tAustralia/Lord_Howe', | |||
| 'UTC+11\tAntarctica/Casey', | |||
| 'UTC+11\tAsia/Magadan', | |||
| 'UTC+11\tAsia/Sakhalin', | |||
| 'UTC+11\tAsia/Srednekolymsk', | |||
| 'UTC+11\tPacific/Bougainville', | |||
| 'UTC+11\tPacific/Efate', | |||
| 'UTC+11\tPacific/Guadalcanal', | |||
| 'UTC+11\tPacific/Kosrae', | |||
| 'UTC+11\tPacific/Norfolk', | |||
| 'UTC+11\tPacific/Noumea', | |||
| 'UTC+11\tPacific/Pohnpei', | |||
| 'UTC+12\tAntarctica/McMurdo', | |||
| 'UTC+12\tAsia/Anadyr', | |||
| 'UTC+12\tAsia/Kamchatka', | |||
| 'UTC+12\tPacific/Auckland', | |||
| 'UTC+12\tPacific/Fiji', | |||
| 'UTC+12\tPacific/Funafuti', | |||
| 'UTC+12\tPacific/Kwajalein', | |||
| 'UTC+12\tPacific/Majuro', | |||
| 'UTC+12\tPacific/Nauru', | |||
| 'UTC+12\tPacific/Tarawa', | |||
| 'UTC+12\tPacific/Wake', | |||
| 'UTC+12\tPacific/Wallis', | |||
| 'UTC+12:45\tPacific/Chatham', | |||
| 'UTC+13\tPacific/Apia', | |||
| 'UTC+13\tPacific/Fakaofo', | |||
| 'UTC+13\tPacific/Kanton', | |||
| 'UTC+13\tPacific/Tongatapu', | |||
| 'UTC+14\tPacific/Kiritimati', | |||
| ]; | |||
| @@ -74,3 +74,16 @@ export const useLogout = () => { | |||
| return logout; | |||
| }; | |||
| export const useSaveSetting = () => { | |||
| const dispatch = useDispatch(); | |||
| const saveSetting = useCallback( | |||
| (userInfo: { new_password: string } | IUserInfo): number => { | |||
| return dispatch<any>({ type: 'settingModel/setting', payload: userInfo }); | |||
| }, | |||
| [dispatch], | |||
| ); | |||
| return saveSetting; | |||
| }; | |||
| @@ -26,6 +26,11 @@ import { useDispatch, useSelector } from 'umi'; | |||
| import { useFetchLlmList, useSelectLlmOptions } from '@/hooks/llmHooks'; | |||
| import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; | |||
| import { IKnowledge } from '@/interfaces/database/knowledge'; | |||
| import { | |||
| getBase64FromUploadFileList, | |||
| getUploadFileListFromBase64, | |||
| normFile, | |||
| } from '@/utils/fileUtil'; | |||
| import { PlusOutlined } from '@ant-design/icons'; | |||
| import { LlmModelType } from '../../constant'; | |||
| import styles from './index.less'; | |||
| @@ -43,26 +48,12 @@ const Configuration = () => { | |||
| (state: any) => state.kSModel.knowledgeDetails, | |||
| ); | |||
| const normFile = (e: any) => { | |||
| if (Array.isArray(e)) { | |||
| return e; | |||
| } | |||
| return e?.fileList; | |||
| }; | |||
| const parserList = useSelectParserList(); | |||
| const embeddingModelOptions = useSelectLlmOptions(); | |||
| const onFinish = async (values: any) => { | |||
| console.info(values); | |||
| const fileList = values.avatar; | |||
| let avatar; | |||
| if (Array.isArray(fileList) && fileList.length > 0) { | |||
| avatar = fileList[0].thumbUrl; | |||
| } | |||
| const avatar = getBase64FromUploadFileList(values.avatar); | |||
| dispatch({ | |||
| type: 'kSModel/updateKb', | |||
| payload: { | |||
| @@ -78,12 +69,10 @@ const Configuration = () => { | |||
| }; | |||
| useEffect(() => { | |||
| const avatar = knowledgeDetails.avatar; | |||
| let fileList: UploadFile[] = []; | |||
| const fileList: UploadFile[] = getUploadFileListFromBase64( | |||
| knowledgeDetails.avatar, | |||
| ); | |||
| if (avatar) { | |||
| fileList = [{ uid: '1', name: 'file', thumbUrl: avatar, status: 'done' }]; | |||
| } | |||
| form.setFieldsValue({ | |||
| ...pick(knowledgeDetails, [ | |||
| 'description', | |||
| @@ -52,7 +52,7 @@ const model: DvaModel<SettingModelState> = { | |||
| const { data } = yield call(userService.setting, payload); | |||
| const { retcode } = data; | |||
| if (retcode === 0) { | |||
| message.success('密码修改成功!'); | |||
| message.success('Modified!'); | |||
| yield put({ | |||
| type: 'updateState', | |||
| payload: { | |||
| @@ -61,7 +61,6 @@ const model: DvaModel<SettingModelState> = { | |||
| }); | |||
| yield put({ | |||
| type: 'getUserInfo', | |||
| payload: {}, | |||
| }); | |||
| } | |||
| }, | |||
| @@ -0,0 +1,19 @@ | |||
| import { Typography } from 'antd'; | |||
| const { Title, Paragraph } = Typography; | |||
| interface IProps { | |||
| title: string; | |||
| description: string; | |||
| } | |||
| const SettingTitle = ({ title, description }: IProps) => { | |||
| return ( | |||
| <div> | |||
| <Title level={5}>{title}</Title> | |||
| <Paragraph>{description}</Paragraph> | |||
| </div> | |||
| ); | |||
| }; | |||
| export default SettingTitle; | |||
| @@ -0,0 +1,23 @@ | |||
| import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; | |||
| import { Form } from 'antd'; | |||
| import { useEffect, useState } from 'react'; | |||
| export const useValidateSubmittable = () => { | |||
| const [form] = Form.useForm(); | |||
| const [submittable, setSubmittable] = useState<boolean>(false); | |||
| // Watch all values | |||
| const values = Form.useWatch([], form); | |||
| useEffect(() => { | |||
| form | |||
| .validateFields({ validateOnly: true }) | |||
| .then(() => setSubmittable(true)) | |||
| .catch(() => setSubmittable(false)); | |||
| }, [form, values]); | |||
| return { submittable, form }; | |||
| }; | |||
| export const useGetUserInfoLoading = () => | |||
| useOneNamespaceEffectsLoading('settingModel', ['setting']); | |||
| @@ -0,0 +1,12 @@ | |||
| .settingWrapper { | |||
| width: 100%; | |||
| .outletWrapper { | |||
| padding: 32px 32px 0; | |||
| } | |||
| .itemDescription { | |||
| padding: 10px 0; | |||
| margin: 0; | |||
| } | |||
| } | |||
| @@ -2,11 +2,15 @@ import { Flex } from 'antd'; | |||
| import { Outlet } from 'umi'; | |||
| import SideBar from './sidebar'; | |||
| import styles from './index.less'; | |||
| const UserSetting = () => { | |||
| return ( | |||
| <Flex> | |||
| <Flex className={styles.settingWrapper}> | |||
| <SideBar></SideBar> | |||
| <Outlet></Outlet> | |||
| <Flex flex={1} className={styles.outletWrapper}> | |||
| <Outlet></Outlet> | |||
| </Flex> | |||
| </Flex> | |||
| ); | |||
| }; | |||
| @@ -0,0 +1,3 @@ | |||
| .passwordWrapper { | |||
| width: 100%; | |||
| } | |||
| @@ -1,5 +1,139 @@ | |||
| import { useOneNamespaceEffectsLoading } from '@/hooks/storeHooks'; | |||
| import { useSaveSetting } from '@/hooks/userSettingHook'; | |||
| import { rsaPsw } from '@/utils'; | |||
| import { Button, Divider, Form, Input, Space } from 'antd'; | |||
| import SettingTitle from '../components/setting-title'; | |||
| import { useValidateSubmittable } from '../hooks'; | |||
| import parentStyles from '../index.less'; | |||
| import styles from './index.less'; | |||
| type FieldType = { | |||
| password?: string; | |||
| new_password?: string; | |||
| confirm_password?: string; | |||
| }; | |||
| const tailLayout = { | |||
| wrapperCol: { offset: 20, span: 4 }, | |||
| }; | |||
| const UserSettingPassword = () => { | |||
| return <div>UserSettingPassword</div>; | |||
| const loading = useOneNamespaceEffectsLoading('settingModel', ['setting']); | |||
| const { form, submittable } = useValidateSubmittable(); | |||
| const saveSetting = useSaveSetting(); | |||
| const onFinish = (values: any) => { | |||
| const password = rsaPsw(values.password) as string; | |||
| const new_password = rsaPsw(values.new_password) as string; | |||
| saveSetting({ password, new_password }); | |||
| }; | |||
| const onFinishFailed = (errorInfo: any) => { | |||
| console.log('Failed:', errorInfo); | |||
| }; | |||
| return ( | |||
| <section className={styles.passwordWrapper}> | |||
| <SettingTitle | |||
| title="Password" | |||
| description="Please enter your current password to change your password." | |||
| ></SettingTitle> | |||
| <Divider /> | |||
| <Form | |||
| colon={false} | |||
| name="basic" | |||
| labelAlign={'left'} | |||
| labelCol={{ span: 8 }} | |||
| wrapperCol={{ span: 16 }} | |||
| style={{ width: '100%' }} | |||
| initialValues={{ remember: true }} | |||
| onFinish={onFinish} | |||
| onFinishFailed={onFinishFailed} | |||
| form={form} | |||
| autoComplete="off" | |||
| // requiredMark={'optional'} | |||
| > | |||
| <Form.Item<FieldType> | |||
| label="Current password" | |||
| name="password" | |||
| rules={[ | |||
| { | |||
| required: true, | |||
| message: 'Please input your password!', | |||
| whitespace: true, | |||
| }, | |||
| ]} | |||
| > | |||
| <Input.Password /> | |||
| </Form.Item> | |||
| <Divider /> | |||
| <Form.Item label="New password" required> | |||
| <Form.Item<FieldType> | |||
| noStyle | |||
| name="new_password" | |||
| rules={[ | |||
| { | |||
| required: true, | |||
| message: 'Please input your password!', | |||
| whitespace: true, | |||
| }, | |||
| ]} | |||
| > | |||
| <Input.Password /> | |||
| </Form.Item> | |||
| <p className={parentStyles.itemDescription}> | |||
| Your new password must be more than 8 characters. | |||
| </p> | |||
| </Form.Item> | |||
| <Divider /> | |||
| <Form.Item<FieldType> | |||
| label="Confirm new password" | |||
| name="confirm_password" | |||
| dependencies={['new_password']} | |||
| rules={[ | |||
| { | |||
| required: true, | |||
| message: 'Please confirm your password!', | |||
| whitespace: true, | |||
| }, | |||
| ({ getFieldValue }) => ({ | |||
| validator(_, value) { | |||
| if (!value || getFieldValue('new_password') === value) { | |||
| return Promise.resolve(); | |||
| } | |||
| return Promise.reject( | |||
| new Error('The new password that you entered do not match!'), | |||
| ); | |||
| }, | |||
| }), | |||
| ]} | |||
| > | |||
| <Input.Password /> | |||
| </Form.Item> | |||
| <Divider /> | |||
| <Form.Item | |||
| {...tailLayout} | |||
| shouldUpdate={(prevValues, curValues) => | |||
| prevValues.additional !== curValues.additional | |||
| } | |||
| > | |||
| <Space> | |||
| <Button htmlType="button">Cancel</Button> | |||
| <Button | |||
| type="primary" | |||
| htmlType="submit" | |||
| disabled={!submittable} | |||
| loading={loading} | |||
| > | |||
| Save | |||
| </Button> | |||
| </Space> | |||
| </Form.Item> | |||
| </Form> | |||
| </section> | |||
| ); | |||
| }; | |||
| export default UserSettingPassword; | |||
| @@ -0,0 +1,7 @@ | |||
| .profileWrapper { | |||
| width: 100%; | |||
| .emailDescription { | |||
| padding: 10px 0; | |||
| margin: 0; | |||
| } | |||
| } | |||
| @@ -1,5 +1,194 @@ | |||
| import { useSaveSetting, useSelectUserInfo } from '@/hooks/userSettingHook'; | |||
| import { | |||
| getBase64FromUploadFileList, | |||
| getUploadFileListFromBase64, | |||
| normFile, | |||
| } from '@/utils/fileUtil'; | |||
| import { PlusOutlined, QuestionCircleOutlined } from '@ant-design/icons'; | |||
| import { | |||
| Button, | |||
| Divider, | |||
| Form, | |||
| Input, | |||
| Select, | |||
| Space, | |||
| Tooltip, | |||
| Upload, | |||
| UploadFile, | |||
| } from 'antd'; | |||
| import { useEffect } from 'react'; | |||
| import SettingTitle from '../components/setting-title'; | |||
| import { TimezoneList } from '../constants'; | |||
| import { useGetUserInfoLoading, useValidateSubmittable } from '../hooks'; | |||
| import parentStyles from '../index.less'; | |||
| import styles from './index.less'; | |||
| const { Option } = Select; | |||
| type FieldType = { | |||
| nickname?: string; | |||
| language?: string; | |||
| email?: string; | |||
| color_schema?: string; | |||
| timezone?: string; | |||
| avatar?: string; | |||
| }; | |||
| const tailLayout = { | |||
| wrapperCol: { offset: 20, span: 4 }, | |||
| }; | |||
| const UserSettingProfile = () => { | |||
| return <div>UserSettingProfile</div>; | |||
| const userInfo = useSelectUserInfo(); | |||
| const saveSetting = useSaveSetting(); | |||
| const loading = useGetUserInfoLoading(); | |||
| const { form, submittable } = useValidateSubmittable(); | |||
| const onFinish = (values: any) => { | |||
| const avatar = getBase64FromUploadFileList(values.avatar); | |||
| saveSetting({ ...values, avatar }); | |||
| }; | |||
| const onFinishFailed = (errorInfo: any) => { | |||
| console.log('Failed:', errorInfo); | |||
| }; | |||
| useEffect(() => { | |||
| const fileList: UploadFile[] = getUploadFileListFromBase64(userInfo.avatar); | |||
| form.setFieldsValue({ ...userInfo, avatar: fileList }); | |||
| }, [form, userInfo]); | |||
| return ( | |||
| <section className={styles.profileWrapper}> | |||
| <SettingTitle | |||
| title="Profile" | |||
| description="Update your photo and personal details here." | |||
| ></SettingTitle> | |||
| <Divider /> | |||
| <Form | |||
| colon={false} | |||
| name="basic" | |||
| labelAlign={'left'} | |||
| labelCol={{ span: 8 }} | |||
| wrapperCol={{ span: 16 }} | |||
| style={{ width: '100%' }} | |||
| initialValues={{ remember: true }} | |||
| onFinish={onFinish} | |||
| onFinishFailed={onFinishFailed} | |||
| form={form} | |||
| autoComplete="off" | |||
| > | |||
| <Form.Item<FieldType> | |||
| label="Username" | |||
| name="nickname" | |||
| rules={[ | |||
| { | |||
| required: true, | |||
| message: 'Please input your username!', | |||
| whitespace: true, | |||
| }, | |||
| ]} | |||
| > | |||
| <Input /> | |||
| </Form.Item> | |||
| <Divider /> | |||
| <Form.Item<FieldType> | |||
| label={ | |||
| <div> | |||
| <Space> | |||
| Your photo | |||
| <Tooltip title="prompt text"> | |||
| <QuestionCircleOutlined /> | |||
| </Tooltip> | |||
| </Space> | |||
| <div>This will be displayed on your profile.</div> | |||
| </div> | |||
| } | |||
| name="avatar" | |||
| valuePropName="fileList" | |||
| getValueFromEvent={normFile} | |||
| > | |||
| <Upload | |||
| listType="picture-card" | |||
| maxCount={1} | |||
| showUploadList={{ showPreviewIcon: false, showRemoveIcon: false }} | |||
| > | |||
| <button style={{ border: 0, background: 'none' }} type="button"> | |||
| <PlusOutlined /> | |||
| <div style={{ marginTop: 8 }}>Upload</div> | |||
| </button> | |||
| </Upload> | |||
| </Form.Item> | |||
| <Divider /> | |||
| <Form.Item<FieldType> | |||
| label="Color schema" | |||
| name="color_schema" | |||
| rules={[ | |||
| { required: true, message: 'Please select your color schema!' }, | |||
| ]} | |||
| > | |||
| <Select placeholder="select your color schema"> | |||
| <Option value="Bright">Bright</Option> | |||
| <Option value="Dark">Dark</Option> | |||
| </Select> | |||
| </Form.Item> | |||
| <Divider /> | |||
| <Form.Item<FieldType> | |||
| label="Language" | |||
| name="language" | |||
| rules={[{ required: true, message: 'Please input your language!' }]} | |||
| > | |||
| <Select placeholder="select your language"> | |||
| <Option value="English">English</Option> | |||
| <Option value="Chinese">Chinese</Option> | |||
| </Select> | |||
| </Form.Item> | |||
| <Divider /> | |||
| <Form.Item<FieldType> | |||
| label="Timezone" | |||
| name="timezone" | |||
| rules={[{ required: true, message: 'Please input your timezone!' }]} | |||
| > | |||
| <Select placeholder="select your timezone" showSearch> | |||
| {TimezoneList.map((x) => ( | |||
| <Option value={x} key={x}> | |||
| {x} | |||
| </Option> | |||
| ))} | |||
| </Select> | |||
| </Form.Item> | |||
| <Divider /> | |||
| <Form.Item label="Email address"> | |||
| <Form.Item<FieldType> name="email" noStyle> | |||
| <Input disabled /> | |||
| </Form.Item> | |||
| <p className={parentStyles.itemDescription}> | |||
| Once registered, an account cannot be changed and can only be | |||
| cancelled. | |||
| </p> | |||
| </Form.Item> | |||
| <Form.Item | |||
| {...tailLayout} | |||
| shouldUpdate={(prevValues, curValues) => | |||
| prevValues.additional !== curValues.additional | |||
| } | |||
| > | |||
| <Space> | |||
| <Button htmlType="button">Cancel</Button> | |||
| <Button | |||
| type="primary" | |||
| htmlType="submit" | |||
| disabled={!submittable} | |||
| loading={loading} | |||
| > | |||
| Save | |||
| </Button> | |||
| </Space> | |||
| </Form.Item> | |||
| </Form> | |||
| </section> | |||
| ); | |||
| }; | |||
| export default UserSettingProfile; | |||
| @@ -0,0 +1,3 @@ | |||
| .sideBarWrapper { | |||
| padding-top: 32px; | |||
| } | |||
| @@ -10,6 +10,8 @@ import { | |||
| UserSettingRouteMap, | |||
| } from '../constants'; | |||
| import styles from './index.less'; | |||
| type MenuItem = Required<MenuProps>['items'][number]; | |||
| function getItem( | |||
| @@ -45,12 +47,15 @@ const SideBar = () => { | |||
| }, [pathName]); | |||
| return ( | |||
| <Menu | |||
| selectedKeys={selectedKeys} | |||
| mode="inline" | |||
| items={items} | |||
| onClick={handleMenuClick} | |||
| /> | |||
| <section className={styles.sideBarWrapper}> | |||
| <Menu | |||
| selectedKeys={selectedKeys} | |||
| mode="inline" | |||
| items={items} | |||
| onClick={handleMenuClick} | |||
| style={{ width: 312 }} | |||
| /> | |||
| </section> | |||
| ); | |||
| }; | |||
| @@ -1,3 +1,5 @@ | |||
| import { UploadFile } from 'antd'; | |||
| export const transformFile2Base64 = (val: any): Promise<any> => { | |||
| return new Promise((resolve, reject) => { | |||
| const reader = new FileReader(); | |||
| @@ -26,3 +28,28 @@ export const transformBase64ToFile = ( | |||
| } | |||
| return new File([u8arr], filename, { type: mimeType }); | |||
| }; | |||
| export const normFile = (e: any) => { | |||
| if (Array.isArray(e)) { | |||
| return e; | |||
| } | |||
| return e?.fileList; | |||
| }; | |||
| export const getUploadFileListFromBase64 = (avatar: string) => { | |||
| let fileList: UploadFile[] = []; | |||
| if (avatar) { | |||
| fileList = [{ uid: '1', name: 'file', thumbUrl: avatar, status: 'done' }]; | |||
| } | |||
| return fileList; | |||
| }; | |||
| export const getBase64FromUploadFileList = (fileList?: UploadFile[]) => { | |||
| if (Array.isArray(fileList) && fileList.length > 0) { | |||
| return fileList[0].thumbUrl; | |||
| } | |||
| return ''; | |||
| }; | |||