Profile settings

This commit is contained in:
kvakazyambra 2022-11-25 00:37:43 +03:00
parent ef7f334909
commit b0f4f92aa9
19 changed files with 327 additions and 57 deletions

6
public/icons/remove.svg Normal file
View File

@ -0,0 +1,6 @@
<svg width="18" height="21" viewBox="0 0 18 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.9082 6.97827L6.35974 6.92188L6.73364 16.535L5.2821 16.5914L4.9082 6.97827Z" fill="black"/>
<path d="M11.0469 16.538L11.4228 6.9248L12.8744 6.98149L12.4984 16.5946L11.0469 16.538Z" fill="black"/>
<path d="M8.16797 6.94727H9.6207V16.5683H8.16797V6.94727Z" fill="black"/>
<path d="M17.7692 3.01065H11.9374V0.484375H5.83184V3.01065H0V4.46332H1.32641L2.12649 20.4844H15.6218L16.4219 4.46332H17.7483L17.7482 3.01065H17.7692ZM7.28454 1.93701H10.5057V3.03178H7.28454V1.93701ZM14.2533 19.0317H3.51595L2.77915 4.46332H14.9902L14.2533 19.0317Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 664 B

View File

@ -30,7 +30,7 @@ export const ProfilePopup = (props: ProfilePopupProps) => {
<a href="#">Закладки</a> <a href="#">Закладки</a>
</li> </li>
<li> <li>
<a href="#">Настройки</a> <a href="/profile/settings/">Настройки</a>
</li> </li>
<li class={styles.topBorderItem}> <li class={styles.topBorderItem}>
<a <a

View File

@ -3,7 +3,7 @@ import { PageWrap } from '../_shared/PageWrap'
export const ConnectPage = () => { export const ConnectPage = () => {
return ( return (
<PageWrap> <PageWrap>
<article class="container container--static-page"> <article class="wide-container container--static-page">
<div class="row"> <div class="row">
<div class="col-sm-10 col-md-8 col-lg-7 col-xl-6 shift-content"> <div class="col-sm-10 col-md-8 col-lg-7 col-xl-6 shift-content">
<h1> <h1>

View File

@ -5,7 +5,7 @@ export const DiscussionRulesPage = () => {
const title = t('Discussion rules') const title = t('Discussion rules')
return ( return (
<PageWrap> <PageWrap>
<article class="container container--static-page"> <article class="wide-container container--static-page">
<div class="row"> <div class="row">
<div class="col-md-6 col-xl-7 shift-content order-md-first"> <div class="col-md-6 col-xl-7 shift-content order-md-first">
<h1> <h1>

View File

@ -5,7 +5,7 @@ import { PageWrap } from '../../_shared/PageWrap'
export const DogmaPage = () => { export const DogmaPage = () => {
return ( return (
<PageWrap> <PageWrap>
<article class="container container--static-page"> <article class="wide-container container--static-page">
<div class="row"> <div class="row">
<div class="col-md-6 col-xl-7 shift-content order-md-first"> <div class="col-md-6 col-xl-7 shift-content order-md-first">
<h4>Редакционные принципы</h4> <h4>Редакционные принципы</h4>

View File

@ -20,9 +20,9 @@ export const GuidePage = () => {
{/*<Meta property="og:image:width" content="1200" />*/} {/*<Meta property="og:image:width" content="1200" />*/}
{/*<Meta property="og:image:height" content="630" />*/} {/*<Meta property="og:image:height" content="630" />*/}
<article class="container container--static-page"> <article class="wide-container container--static-page">
<div class="row"> <div class="row">
<div class="col-md-4 col-lg-3 order-md-last"> <div class="col-md-3 col-lg-2 order-md-last">
<button class="button button--content-index" onClick={toggleIndexExpanded}> <button class="button button--content-index" onClick={toggleIndexExpanded}>
<Show when={!indexExpanded()}> <Show when={!indexExpanded()}>
<Icon name="content-index-control" /> <Icon name="content-index-control" />

View File

@ -17,9 +17,9 @@ export const HelpPage = () => {
{/*<Modal name="thank">Благодарим!</Modal>*/} {/*<Modal name="thank">Благодарим!</Modal>*/}
<article class="container container--static-page discours-help"> <article class="wide-container container--static-page discours-help">
<div class="row"> <div class="row">
<div class="col-md-4 col-lg-3 order-md-last"> <div class="col-md-3 col-lg-2 order-md-last">
<button class="button button--content-index" onClick={toggleIndexExpanded}> <button class="button button--content-index" onClick={toggleIndexExpanded}>
<Show when={!indexExpanded()}> <Show when={!indexExpanded()}>
<Icon name="content-index-control" /> <Icon name="content-index-control" />

View File

@ -21,9 +21,9 @@ export const ManifestPage = () => {
<Modal name="subscribe"> <Modal name="subscribe">
<Subscribe /> <Subscribe />
</Modal> </Modal>
<article class="container container--static-page"> <article class="wide-container container--static-page">
<div class="row"> <div class="row">
<div class="col-md-4 col-lg-3 order-md-last"> <div class="col-md-3 col-lg-2 order-md-last">
<button class="button button--content-index" onClick={toggleIndexExpanded}> <button class="button button--content-index" onClick={toggleIndexExpanded}>
<Show when={!indexExpanded()}> <Show when={!indexExpanded()}>
<Icon name="content-index-control" /> <Icon name="content-index-control" />

View File

@ -6,7 +6,7 @@ import { t } from '../../../utils/intl'
export const PartnersPage = () => { export const PartnersPage = () => {
return ( return (
<PageWrap> <PageWrap>
<article class="container container--static-page"> <article class="wide-container container--static-page">
<div class="row"> <div class="row">
<div class="col-md-6 col-xl-7 shift-content order-md-first"> <div class="col-md-6 col-xl-7 shift-content order-md-first">
<h1>{t('Partners')}</h1> <h1>{t('Partners')}</h1>

View File

@ -5,7 +5,7 @@ export const PrinciplesPage = () => {
const title = t('Principles') const title = t('Principles')
return ( return (
<PageWrap> <PageWrap>
<article class="container container--static-page"> <article class="wide-container container--static-page">
<div class="row"> <div class="row">
<div class="col-md-6 col-xl-7 shift-content order-md-first"> <div class="col-md-6 col-xl-7 shift-content order-md-first">
<h1> <h1>

View File

@ -6,7 +6,7 @@ import { t } from '../../../utils/intl'
export const ProjectsPage = () => { export const ProjectsPage = () => {
return ( return (
<PageWrap> <PageWrap>
<article class="container container--static-page"> <article class="wide-container container--static-page">
<div class="row"> <div class="row">
<div class="col-md-6 col-xl-7 shift-content order-md-first"> <div class="col-md-6 col-xl-7 shift-content order-md-first">
<h1>{t('Projects')}</h1> <h1>{t('Projects')}</h1>

View File

@ -15,9 +15,9 @@ export const TermsOfUsePage = () => {
{/*<Meta name="keywords" content={`Discours.io, ${t('Terms of use')}, ${t('Terms of use', 'en')}`} />*/} {/*<Meta name="keywords" content={`Discours.io, ${t('Terms of use')}, ${t('Terms of use', 'en')}`} />*/}
{/*<Meta property="og:title" content={title} />*/} {/*<Meta property="og:title" content={title} />*/}
{/*<Meta property="og:description" content={title} />*/} {/*<Meta property="og:description" content={title} />*/}
<article class="container container--static-page"> <article class="wide-container container--static-page">
<div class="row"> <div class="row">
<div class="col-md-4 col-lg-3 order-md-last"> <div class="col-md-3 col-lg-2 order-md-last">
<button class="button button--content-index" onClick={toggleIndexExpanded}> <button class="button button--content-index" onClick={toggleIndexExpanded}>
<Show when={!indexExpanded()}> <Show when={!indexExpanded()}>
<Icon name="content-index-control" /> <Icon name="content-index-control" />

View File

@ -10,7 +10,7 @@ export const ThanksPage = () => {
{/*<Meta property="og:title" content={title} />*/} {/*<Meta property="og:title" content={title} />*/}
{/*<Meta property="og:description" content={title} />*/} {/*<Meta property="og:description" content={title} />*/}
<article class="container container--static-page"> <article class="wide-container container--static-page">
<div class="row"> <div class="row">
<div class="col-md-6 col-xl-7 shift-content order-md-first"> <div class="col-md-6 col-xl-7 shift-content order-md-first">
<h1> <h1>

View File

@ -0,0 +1,127 @@
import { PageWrap } from '../../_shared/PageWrap'
import type { PageProps } from '../../types'
import { createSignal, onMount, Show } from 'solid-js'
import { Loading } from '../../Loading'
import styles from './Settings.module.scss'
import { Icon } from '../../_shared/Icon'
import { clsx } from 'clsx'
export const ProfileSettingsPage = (props: PageProps) => {
return (
<PageWrap>
<div class="wide-container">
<div class="shift-content">
<div class="left-col">
<div class="left-navigation">zhopa</div>
</div>
<div class="row">
<div class="col-md-10 col-lg-9 col-xl-8">
<h1>Настройки профиля</h1>
<p class="description">Здесь можно настроить свой профиль так, как вы хотите.</p>
<form>
<h4>Аватар</h4>
<div class="pretty-form__item">
<div class={styles.avatarContainer}>
<img class={styles.avatar} />
<input
type="file"
name="avatar"
class={styles.avatarInput}
accept="image/jpeg,image/png,image/gif,image/webp"
/>
</div>
</div>
<h4>Имя</h4>
<p class="description">
Ваше имя появится на&nbsp;странице вашего профиля и&nbsp;как ваша подпись
в&nbsp;публикациях, комментариях и&nbsp;откликах
</p>
<div class="pretty-form__item">
<input type="text" name="username" id="username" placeholder="Имя" />
<label for="username">Имя</label>
</div>
<h4>Адрес на&nbsp;Дискурсе</h4>
<div class="pretty-form__item">
<div class={styles.discoursName}>
<label for="user-address">https://discours.io/user/</label>
<div class={styles.discoursNameField}>
<input type="text" name="user-address" id="user-address" class="nolabel" />
<p class="form-message form-message--error">
Увы, этот адрес уже занят, выберите другой
</p>
</div>
</div>
</div>
<h4>Представление</h4>
<div class="pretty-form__item">
<textarea name="presentation" id="presentation" placeholder="Представление"></textarea>
<label for="presentation">Представление</label>
</div>
<h4>О себе</h4>
<div class="pretty-form__item">
<textarea name="about" id="about" placeholder="О себе"></textarea>
<label for="about">О себе</label>
</div>
<h4>Чем могу помочь/навыки</h4>
<div class="pretty-form__item">
<input type="text" name="skills" id="skills" />
</div>
<h4>Откуда</h4>
<div class="pretty-form__item">
<input type="text" name="location" id="location" placeholder="Откуда" />
<label for="location">Откуда</label>
</div>
<h4>Дата рождения</h4>
<div class="pretty-form__item">
<input
type="date"
name="birthdate"
id="birthdate"
placeholder="Дата рождения"
class="nolabel"
/>
</div>
<div class={clsx(styles.multipleControls, 'pretty-form__item')}>
<div class={styles.multipleControlsHeader}>
<h4>Социальные сети</h4>
<button class="button">+</button>
</div>
<div class={styles.multipleControlsItem}>
<input type="text" name="social1" class="nolabel" />
<button>
<Icon name="remove" class={styles.icon} />
</button>
</div>
<div class={styles.multipleControlsItem}>
<input type="text" name="social1" class="nolabel" />
<button>
<Icon name="remove" class={styles.icon} />
</button>
</div>
</div>
<br />
<p>
<button class="button button--submit">Сохранить настройки</button>
</p>
</form>
</div>
</div>
</div>
</div>
</PageWrap>
)
}
// for lazy loading
export default ProfileSettingsPage

View File

@ -0,0 +1,105 @@
h4 {
font-weight: 500;
}
.avatarContainer {
border-radius: 100%;
overflow: hidden;
position: relative;
height: 18rem;
width: 18rem;
}
.avatar,
.avatarInput {
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.avatar {
background: #ccc;
border: none;
object-fit: cover;
object-position: center;
}
.avatarInput {
border-radius: 100%;
cursor: pointer;
opacity: 0;
z-index: 1;
}
.multipleControls {
margin-top: 3rem;
}
.multipleControlsItem {
position: relative;
button {
background-color: #fff;
padding: 0.5em;
position: absolute;
right: 0.8em;
top: 50%;
transform: translateY(-50%);
transition: background-color 0.3s;
&:hover {
background-color: #000;
.icon {
filter: invert(1);
}
}
.icon {
filter: invert(0);
transition: filter 0.3s;
}
}
form & input {
padding-right: 5rem;
}
}
.multipleControlsHeader {
display: flex;
margin-bottom: 0.5em;
h4 {
flex: 1;
margin-bottom: 0;
}
button {
margin-left: 1em;
padding-bottom: 0.5rem;
padding-top: 0.5rem;
}
}
.discoursName {
display: flex;
@include media-breakpoint-down(sm) {
flex-wrap: wrap;
input {
min-width: 250px;
}
}
label {
margin: 0.6em 0.5em 0 0;
}
}
.discoursNameField {
flex: 1;
}

View File

@ -32,6 +32,7 @@ import { ConnectPage } from './Pages/ConnectPage'
import { InboxPage } from './Pages/InboxPage' import { InboxPage } from './Pages/InboxPage'
import { LayoutShoutsPage } from './Pages/LayoutShoutsPage' import { LayoutShoutsPage } from './Pages/LayoutShoutsPage'
import { SessionProvider } from '../context/session' import { SessionProvider } from '../context/session'
import { ProfileSettingsPage } from './Pages/profile/ProfileSettingsPage'
// TODO: lazy load // TODO: lazy load
// const SomePage = lazy(() => import('./Pages/SomePage')) // const SomePage = lazy(() => import('./Pages/SomePage'))
@ -58,7 +59,8 @@ const pagesMap: Record<keyof Routes, Component<PageProps>> = {
partners: PartnersPage, partners: PartnersPage,
principles: PrinciplesPage, principles: PrinciplesPage,
termsOfUse: TermsOfUsePage, termsOfUse: TermsOfUsePage,
thanks: ThanksPage thanks: ThanksPage,
profileSettings: ProfileSettingsPage
} }
export const Root = (props: PageProps) => { export const Root = (props: PageProps) => {

View File

@ -0,0 +1,12 @@
---
import Prerendered from '../../main.astro'
import { Root } from '../../components/Root'
import { initRouter } from '../../stores/router'
const { pathname, search } = Astro.url
initRouter(pathname, search)
---
<Prerendered>
<Root client:load />
</Prerendered>

View File

@ -27,6 +27,8 @@ export interface Routes {
thanks: void thanks: void
expo: 'layout' expo: 'layout'
inbox: void // TODO: добавить ID текущего юзера inbox: void // TODO: добавить ID текущего юзера
profile: void
profileSettings: void
} }
const searchParamsStore = createSearchParams() const searchParamsStore = createSearchParams()
@ -53,7 +55,9 @@ const routerStore = createRouter<Routes>(
projects: '/about/projects', projects: '/about/projects',
termsOfUse: '/about/terms-of-use', termsOfUse: '/about/terms-of-use',
thanks: '/about/thanks', thanks: '/about/thanks',
expo: '/expo/:layout' expo: '/expo/:layout',
profile: '/profile',
profileSettings: '/profile/settings'
}, },
{ {
search: false, search: false,

View File

@ -67,6 +67,7 @@ section {
margin: 0 auto; margin: 0 auto;
max-width: 1400px; max-width: 1400px;
padding: 0 divide($container-padding-x, 2); padding: 0 divide($container-padding-x, 2);
width: 100%;
@include media-breakpoint-up(sm) { @include media-breakpoint-up(sm) {
padding: 0 $container-padding-x; padding: 0 $container-padding-x;
@ -299,6 +300,12 @@ button {
} }
} }
.button--submit {
@include font-size(2rem);
padding: 1.6rem 2rem;
}
form { form {
.pretty-form__item { .pretty-form__item {
position: relative; position: relative;
@ -317,6 +324,7 @@ form {
input[type='password'], input[type='password'],
input[type='search'], input[type='search'],
input[type='tel'], input[type='tel'],
input[type='date'],
textarea, textarea,
select { select {
border: 2px solid #e8e8e8; border: 2px solid #e8e8e8;
@ -351,6 +359,19 @@ form {
transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1); transition-timing-function: cubic-bezier(0, 0.25, 0.5, 1);
user-select: none; user-select: none;
} }
& + .form-message {
margin-top: -1.2rem;
}
&.nolabel {
padding-bottom: 1.8rem;
padding-top: 1.7rem;
}
}
.form-message--error {
color: #d00820;
} }
select { select {
@ -378,6 +399,10 @@ form {
top: 3rem; top: 3rem;
} }
} }
.form-message {
@include font-size(1.2rem);
}
} }
.input--short { .input--short {
@ -415,45 +440,6 @@ input[type='checkbox'] {
display: none !important; display: none !important;
} }
.article__author {
font-size: 1.5rem;
font-weight: 400;
&,
a {
color: #9fa1a7;
}
a {
background: transparent;
transition: background-color 0.2s;
&:hover {
background: #000;
color: #fff;
}
}
}
.article__topic {
font-size: 1.2rem;
letter-spacing: 0.08em;
margin-bottom: 0.8rem;
text-transform: uppercase;
transition: background-color 0.2s;
a {
background: transparent;
border: none;
color: $link-color;
&:hover {
background: $link-color;
color: #fff;
}
}
}
figure { figure {
margin: 2em 0; margin: 2em 0;
} }
@ -677,6 +663,8 @@ astro-island {
} }
.shift-content { .shift-content {
position: relative;
@include media-breakpoint-up(md) { @include media-breakpoint-up(md) {
margin-left: 161px; margin-left: 161px;
} }
@ -684,6 +672,27 @@ astro-island {
@include media-breakpoint-up(lg) { @include media-breakpoint-up(lg) {
margin-left: 235px; margin-left: 235px;
} }
.left-col {
height: 100%;
padding-right: 2rem;
position: absolute;
right: 100%;
top: 0;
@include media-breakpoint-up(md) {
width: 161px;
}
@include media-breakpoint-up(lg) {
width: 235px;
}
}
.left-navigation {
position: sticky;
top: 0;
}
} }
.center { .center {
@ -790,3 +799,8 @@ details {
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
white-space: normal; white-space: normal;
} }
.description {
@include font-size(1.4rem);
color: rgba(0 0 0 / 40%);
}