Skip to content

Commit

Permalink
Develop (#42)
Browse files Browse the repository at this point in the history
* Fix merge problems
  • Loading branch information
slavoyar authored Sep 14, 2024
1 parent f64f97c commit 73c12f1
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 26 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ on:
pull_request:
branches:
- develop
paths:
- "frontend/**"
- "backend/**"

jobs:
lint-build-frontend:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
Warnings:
- A unique constraint covering the columns `[username]` on the table `User` will be added. If there are existing duplicate values, this will fail.
*/
-- CreateIndex
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
31 changes: 27 additions & 4 deletions frontend/src/app/styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,33 @@
@tailwind utilities;

body {
@apply bg-background;
@apply bg-background;
}

#root {
height: 100vh;
width: 100vw;
}
height: 100vh;
width: 100vw;
}

/* Scroll bar stylings */
::-webkit-scrollbar {
width: 10px;
height: 10px;
}

/* Track */
::-webkit-scrollbar-track {
background: var(--lightestgrey);
}

/* Handle */
::-webkit-scrollbar-thumb {
background: #888;
border-radius: 5px;
}

/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: #555;
}

22 changes: 18 additions & 4 deletions frontend/src/features/add-group/index.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
import { Button, CreateDialog, TextField } from '@shared/ui';
import { useState } from 'react';
import { KeyboardEvent, useState } from 'react';
import { useGroupStore } from '@entities/group';

export const AddGroup = () => {
const [isOpen, setIsOpen] = useState(false);
const [name, setName] = useState('');
const createGroup = useGroupStore((state) => state.create);

const handleClose = () => {
setIsOpen(false);
setName('');
};

const saveHandler = async () => {
try {
await createGroup(name);
} finally {
setIsOpen(false);
setName('');
handleClose();
}
};

const handleEnter = (e: KeyboardEvent<HTMLInputElement>) => {
if (name && e.key === 'Enter') {
saveHandler();
}
};

return (
<>
<Button variant='secondary' onClick={() => setIsOpen(true)}>
Expand All @@ -23,11 +34,14 @@ export const AddGroup = () => {
</Button>
<CreateDialog
onSave={() => saveHandler()}
isDisabled={!name}
isOpen={isOpen}
title='Create group'
onClose={() => setIsOpen(false)}
onClose={handleClose}
>
<TextField
autoFocus
onKeyUp={handleEnter}
placeholder='Enter group name'
onInput={(e) => setName(e.currentTarget.value)}
value={name}
Expand Down
15 changes: 12 additions & 3 deletions frontend/src/pages/main/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { useGroupStore } from '@entities/group';
import { useEffect } from 'react';
import { useEffect, useRef } from 'react';
import { useNavigate } from 'react-router-dom';
import { Route } from '@shared/types';
import { Groups } from '@widgets/groups';
import { StudyModes } from '@widgets/study-modes';

const GAP = 24;
const DEFAULT_OFFSET = 200;

export const Main = () => {
const studyModesRef = useRef<HTMLDivElement>(null);
const fetchGroups = useGroupStore((state) => state.fetch);
const navigate = useNavigate();

Expand All @@ -14,10 +18,15 @@ export const Main = () => {
navigate(Route.SignIn);
});
}, []);

return (
<div className='md:w-6/12 m-auto h-full flex flex-col gap-6'>
<StudyModes />
<Groups />
<StudyModes ref={studyModesRef} />
<Groups
style={{
maxHeight: `calc(100% - ${(studyModesRef.current?.offsetHeight ?? DEFAULT_OFFSET) + GAP}px`,
}}
/>
</div>
);
};
23 changes: 23 additions & 0 deletions frontend/src/pages/main/ui.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import Groups from '@widgets/groups';
import { useGroupStore } from '@entities/group';
import { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { Route } from '@shared/types';

const Main = () => {
const fetchGroups = useGroupStore((state) => state.fetch);
const navigate = useNavigate();

useEffect(() => {
fetchGroups().catch(() => {
navigate(Route.SignIn);
});
}, []);
return (
<div className='md:w-6/12 m-auto h-full'>
<Groups />
</div>
);
};

export default Main;
42 changes: 42 additions & 0 deletions frontend/src/shared/stores/authStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { create } from 'zustand';
import { authService } from '@shared/api';
import { persist } from 'zustand/middleware';

interface State {
username: string;
}

interface Action {
login: (username: string, password: string) => Promise<void>;
register: (username: string, password: string) => Promise<void>;
signOut: () => void;
}

export const useAuthStore = create(
persist<State & Action>(
(set) => ({
username: '',

login: async (username, password) => {
try {
await authService.login(username, password);
set(() => ({ username }));
} catch {
set(() => ({ username: '' }));
}
},
register: async (username, password) => {
try {
await authService.register(username, password);
set(() => ({ username }));
} catch {
set(() => ({ username: '' }));
}
},
signOut: () => {
set(() => ({ username: '' }));
},
}),
{ name: 'auth' }
)
);
11 changes: 9 additions & 2 deletions frontend/src/shared/ui/dialog/create-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ interface Props extends Omit<DialogProps, 'footer'> {
onSave: () => void;
saveTitle?: string;
closeTitle?: string;
isDisabled?: boolean;
}

export const CreateDialog: FC<Props> = ({
onSave,
onClose,
isDisabled,
saveTitle = 'Create',
closeTitle = 'Cancel',
...props
Expand All @@ -21,10 +23,15 @@ export const CreateDialog: FC<Props> = ({
onClose={onClose}
footer={
<div className='flex w-full gap-4'>
<Button variant='primary' onClick={() => onSave()}>
<Button
className='w-full'
variant='primary'
disabled={isDisabled ?? false}
onClick={() => onSave()}
>
{saveTitle}
</Button>
<Button variant='secondary' onClick={() => onClose()}>
<Button className='w-full' variant='secondary' onClick={() => onClose()}>
{closeTitle}
</Button>
</div>
Expand Down
11 changes: 7 additions & 4 deletions frontend/src/shared/ui/text-field/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { FC, InputHTMLAttributes } from 'react';
import { InputHTMLAttributes, forwardRef } from 'react';
import './style.css';

interface TextFieldProps extends InputHTMLAttributes<HTMLInputElement> {
interface Props extends InputHTMLAttributes<HTMLInputElement> {
variant?: 'primary';
autoFocus?: boolean;
}

export const TextField: FC<TextFieldProps> = ({ variant = 'primary', ...props }) => (
<input className={`input input--${variant}`} {...props} />
export const TextField = forwardRef<HTMLInputElement, Props>(
({ variant = 'primary', ...props }, ref) => (
<input ref={ref} className={`input input--${variant}`} {...props} />
)
);
10 changes: 7 additions & 3 deletions frontend/src/widgets/groups/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { CardList, useCardStore } from '@entities/card';
import { Group, GroupList, useGroupStore } from '@entities/group';
import { AddGroup } from '@features/add-group';
import { AddWord } from '@features/add-word';
import { HTMLAttributes } from 'react';

export const Groups = () => {
export const Groups = (props: HTMLAttributes<HTMLDivElement>) => {
const [cardsPerGroup, fetchCards] = useCardStore((state) => [state.cardsPerGroup, state.fetch]);
const decrementWordCount = useGroupStore((state) => state.decrementWordCount);

Expand All @@ -14,12 +15,15 @@ export const Groups = () => {
};

return (
<div className='md:p-10 p-5 bg-secondary-900 rounded-2xl flex flex-col md:gap-10 gap-5 h-fit max-h-full'>
<div
className='md:p-10 p-5 bg-secondary-900 rounded-2xl flex flex-col md:gap-10 gap-5 h-fit max-h-full'
{...props}
>
<div className='flex items-center justify-between'>
<div className='text-2xl text-white'>Folders</div>
<AddGroup />
</div>
<div className='overflow-auto h-full'>
<div className='overflow-auto h-full p-2'>
<GroupList
content={(item) => (
<div>
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/widgets/study-modes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { WriteStudy } from '@features/write-study';
import { forwardRef } from 'react';

export const StudyModes = () => (
<div className='flex flex-col gap-2'>
export const StudyModes = forwardRef<HTMLDivElement>((_, ref) => (
<div ref={ref} className='flex flex-col gap-2'>
<h1 className='text-white text-xl text-center'>Study modes</h1>
<div className='w-full justify-center flex'>
<WriteStudy />
</div>
</div>
);
));

0 comments on commit 73c12f1

Please sign in to comment.