feat: full screen form for mobile

This commit is contained in:
2025-07-18 15:06:50 +04:00
parent e033938a03
commit 964641a58d
11 changed files with 71 additions and 12 deletions

View File

@ -6,7 +6,7 @@ import PageContainer from "@/components/PageContainer/PageContainer";
export default function CreateIdPage() { export default function CreateIdPage() {
return ( return (
<PageContainer center> <PageContainer center>
<PageItem> <PageItem fullScreenMobile>
<Logo title={"Создание аккаунта"} /> <Logo title={"Создание аккаунта"} />
<LoginForm isCreatingId /> <LoginForm isCreatingId />
</PageItem> </PageItem>

View File

@ -8,6 +8,7 @@ import {
import Header from "@/components/Header/Header"; import Header from "@/components/Header/Header";
import { theme } from "@/theme"; import { theme } from "@/theme";
import "@/app/global.css"; import "@/app/global.css";
import Footer from "@/components/Footer/Footer";
export const metadata = { export const metadata = {
title: "LogiDex ID", title: "LogiDex ID",
@ -45,6 +46,7 @@ export default function RootLayout({ children }: Props) {
defaultColorScheme={"dark"}> defaultColorScheme={"dark"}>
<Header /> <Header />
{children} {children}
<Footer />
</MantineProvider> </MantineProvider>
</body> </body>
</html> </html>

View File

@ -6,7 +6,7 @@ import PageContainer from "@/components/PageContainer/PageContainer";
export default function MainPage() { export default function MainPage() {
return ( return (
<PageContainer center> <PageContainer center>
<PageItem> <PageItem fullScreenMobile>
<Logo title={"Вход"} /> <Logo title={"Вход"} />
<LoginForm /> <LoginForm />
</PageItem> </PageItem>

View File

@ -0,0 +1,30 @@
import Link from "next/link";
import { Group, Text } from "@mantine/core";
const Footer = () => {
return (
<Group
justify={"flex-end"}
align={"flex-end"}
h={"7vh"}
p={"md"}>
<Group gap={"xl"}>
<Link
href={"#"}
style={{
textDecoration: "none",
color: "inherit",
fontSize: 14,
}}>
Help and support
</Link>
<Group gap={5}>
<Text style={{ fontSize: 18 }}>©</Text>
<Text style={{ fontSize: 14 }}>2025, LogiDex</Text>
</Group>
</Group>
</Group>
);
};
export default Footer;

View File

@ -31,7 +31,7 @@ const LoginForm: FC<Props> = ({ isCreatingId = false }) => {
return ( return (
<form onSubmit={form.onSubmit(handleSubmit)}> <form onSubmit={form.onSubmit(handleSubmit)}>
<Stack w={350}> <Stack>
<PhoneInput {...form.getInputProps("phoneNumber")} /> <PhoneInput {...form.getInputProps("phoneNumber")} />
{isCreatingId ? ( {isCreatingId ? (
<> <>

View File

@ -22,3 +22,20 @@
.container-no-border-radius { .container-no-border-radius {
border-radius: 0 !important; border-radius: 0 !important;
} }
.container-full-screen-mobile {
@media (max-width: 48em) {
min-height: 100vh;
height: 100vh;
width: 100vw;
border-radius: 0 !important;
padding: rem(40) rem(20) rem(20);
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 100;
overflow-y: auto;
}
}

View File

@ -8,6 +8,7 @@ type Props = {
fullHeight?: boolean; fullHeight?: boolean;
fullHeightFixed?: boolean; fullHeightFixed?: boolean;
noBorderRadius?: boolean; noBorderRadius?: boolean;
fullScreenMobile?: boolean;
}; };
const PageItem: FC<Props> = ({ const PageItem: FC<Props> = ({
@ -16,6 +17,7 @@ const PageItem: FC<Props> = ({
fullHeight = false, fullHeight = false,
fullHeightFixed = false, fullHeightFixed = false,
noBorderRadius = false, noBorderRadius = false,
fullScreenMobile = false,
}) => { }) => {
return ( return (
<div <div
@ -24,7 +26,8 @@ const PageItem: FC<Props> = ({
styles.container, styles.container,
fullHeight && styles["container-full-height"], fullHeight && styles["container-full-height"],
fullHeightFixed && styles["container-full-height-fixed"], fullHeightFixed && styles["container-full-height-fixed"],
noBorderRadius && styles["container-no-border-radius"] noBorderRadius && styles["container-no-border-radius"],
fullScreenMobile && styles["container-full-screen-mobile"]
)}> )}>
{children} {children}
</div> </div>

View File

@ -2,6 +2,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: rem(10); gap: rem(10);
min-height: 70vh; min-height: 86vh;
background-color: transparent; background-color: transparent;
} }

View File

@ -14,7 +14,3 @@
} }
border-radius: 15px; border-radius: 15px;
} }
.country-dropdown {
border-radius: 15px;
}

View File

@ -41,6 +41,7 @@ const PhoneInput = ({
initialData.current.localValue initialData.current.localValue
); );
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const [dropdownWidth, setDropdownWidth] = useState<number>(300);
const lastNotifiedValue = useRef<string | null>(value ?? ""); const lastNotifiedValue = useRef<string | null>(value ?? "");
@ -71,6 +72,11 @@ const PhoneInput = ({
const { readOnly, disabled } = props; const { readOnly, disabled } = props;
const leftSectionWidth = 90; const leftSectionWidth = 90;
useEffect(() => {
if (!inputRef.current?.offsetWidth) return;
setDropdownWidth(inputRef.current?.offsetWidth);
}, [inputRef.current?.offsetWidth]);
return ( return (
<InputBase <InputBase
{...props} {...props}
@ -89,6 +95,7 @@ const PhoneInput = ({
} }
}} }}
leftSectionWidth={leftSectionWidth} leftSectionWidth={leftSectionWidth}
inputWidth={dropdownWidth}
/> />
} }
leftSectionWidth={leftSectionWidth} leftSectionWidth={leftSectionWidth}

View File

@ -21,6 +21,7 @@ type Props = {
setCountry: (country: Country) => void; setCountry: (country: Country) => void;
disabled: boolean | undefined; disabled: boolean | undefined;
leftSectionWidth: number; leftSectionWidth: number;
inputWidth?: number;
}; };
const CountrySelect = ({ const CountrySelect = ({
@ -28,6 +29,7 @@ const CountrySelect = ({
setCountry, setCountry,
disabled, disabled,
leftSectionWidth, leftSectionWidth,
inputWidth,
}: Props) => { }: Props) => {
const [search, setSearch] = useState(""); const [search, setSearch] = useState("");
@ -84,10 +86,12 @@ const CountrySelect = ({
return ( return (
<Combobox <Combobox
store={combobox} store={combobox}
width={350}
position={"bottom-start"} position={"bottom-start"}
classNames={{ styles={{
dropdown: style["country-dropdown"], dropdown: {
borderRadius: "15px",
minWidth: `${inputWidth}px`,
},
}} }}
onOptionSubmit={val => { onOptionSubmit={val => {
setCountry(countryOptionsDataMap[val]); setCountry(countryOptionsDataMap[val]);