diff --git a/repomix-output.xml b/repomix-output.xml new file mode 100644 index 0000000..7245ce0 --- /dev/null +++ b/repomix-output.xml @@ -0,0 +1,678 @@ +This file is a merged representation of a subset of the codebase, containing files not matching ignore patterns, combined into a single document by Repomix. + + +This section contains a summary of this file. + + +This file contains a packed representation of the entire repository's contents. +It is designed to be easily consumable by AI systems for analysis, code review, +or other automated processes. + + + +The content is organized as follows: +1. This summary section +2. Repository information +3. Directory structure +4. Repository files, each consisting of: + - File path as an attribute + - Full contents of the file + + + +- This file should be treated as read-only. Any changes should be made to the + original repository files, not this packed version. +- When processing this file, use the file path to distinguish + between different files in the repository. +- Be aware that this file may contain sensitive information. Handle it with + the same level of security as you would the original repository. + + + +- Some files may have been excluded based on .gitignore rules and Repomix's configuration +- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files +- Files matching these patterns are excluded: bun.lock, node_modules/, .vscode/ +- Files matching patterns in .gitignore are excluded +- Files matching default ignore patterns are excluded +- Files are sorted by Git change count (files with more changes are at the bottom) + + + + + + + + + +public/ + vite.svg +src/ + assets/ + preact.svg + components/ + ui/ + Button.module.scss + Button.tsx + Input.module.scss + Input.tsx + layout.tsx + menu.module.scss + menu.tsx + pages/ + login.module.scss + login.tsx + profile.module.scss + profile.tsx + providers/ + AuthProvider.tsx + utils/ + class-merge.ts + app.module.scss + app.tsx + index.scss + main.tsx + vite-env.d.ts +.gitattributes +.gitignore +.prettierrc +eslint.config.mjs +index.html +package.json +postcss.config.mts +tsconfig.app.json +tsconfig.json +tsconfig.node.json +vite.config.ts + + + +This section contains the contents of the repository's files. + + +import { signal, Signal } from "@preact/signals"; +import { createContext, JSX } from "preact"; +import { useContext } from "preact/hooks"; + +interface AppContextValue { + isLoggedIn: Signal; +} + +const AppContext = createContext({ + isLoggedIn: signal(false), +}); + +const AppProvider = ({ children }: { children: JSX.Element }) => { + const value: AppContextValue = { + isLoggedIn: signal(false), + }; + + return {children}; +}; + +const useAppContext = () => { + const context = useContext(AppContext); + if (!context) { + throw new Error("useAppContext must be used within AppProvider"); + } + return context; +}; + +export { AppProvider, useAppContext }; + + + + + + + + + + + +import { useAppContext } from "@/providers/AuthProvider"; +import { FunctionComponent } from "preact"; +import { Route, Router, useLocation } from "preact-iso"; +import { useEffect } from "preact/hooks"; +import Menu from "./menu"; + +const Layout: FunctionComponent = () => { + const { isLoggedIn } = useAppContext(); + const location = useLocation(); + useEffect(() => { + console.log(isLoggedIn.value); + }, [isLoggedIn]); + return ( +
+
+ + { + // location.route("/settings"); + return

Home

; + }} + /> +

Test

} /> +

Test2

} /> +

404

} /> +
+
+ +
+ ); +}; + +export default Layout; +
+ + +@reference "../index.scss"; + + + +import Layout from "@/components/layout"; +import { FunctionComponent } from "preact"; + +const ProfilePage: FunctionComponent = () => { + return ; +}; + +export default ProfilePage; + + + +import { ClassValue, clsx } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(...inputs)); +} + + + +@reference "./index.scss"; + +.text { + @apply text-9xl text-red-500; +} + + + +import { render } from "preact"; +import { App } from "./app.tsx"; +import "./index.scss"; + +render(, document.getElementById("app")!); + + + +/// + + + +* text=auto +bun.lock binary + + + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + + + +// @ts-check + +import eslint from "@eslint/js"; +import tseslint from "typescript-eslint"; + +export default tseslint.config({ + extends: [eslint.configs.recommended, tseslint.configs.recommended], + ignores: ["*.d.ts"], + languageOptions: { + ecmaVersion: "latest", + sourceType: "module", + parserOptions: { ecmaFeatures: { jsx: true } }, + }, + settings: { + env: { + browser: true, + es6: true, + }, + }, +}); + + + +export default { + plugins: { + "@tailwindcss/postcss": {}, + }, +}; + + + +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2020", + "useDefineForClassFields": true, + "module": "ESNext", + "lib": [ + "ES2020", + "DOM", + "DOM.Iterable" + ], + "skipLibCheck": true, + "paths": { + "react": [ + "./node_modules/preact/compat/" + ], + "react-dom": [ + "./node_modules/preact/compat/" + ], + "@/*": [ + "./src/*" + ] + }, + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + "jsxImportSource": "preact", + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": [ + "src" + ] +} + + + +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} + + + +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} + + + +import preact from '@preact/preset-vite'; +import tailwindcss from '@tailwindcss/vite'; +import { defineConfig } from 'vite'; +import tsConfigPaths from 'vite-tsconfig-paths'; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [preact(), tailwindcss(), tsConfigPaths()], +}); + + + +@reference '../../index.scss'; + +.button { + @apply rounded-2xl border-2 py-3 font-semibold text-white transition-colors hover:cursor-pointer; +} + + + +import { FunctionComponent } from "preact"; +import { tv } from "tailwind-variants"; +import classes from "./Button.module.scss"; +const button = tv({ + base: classes.button, + variants: { + color: { + primary: "bg-blue-400 hover:bg-blue-500", + secondary: "bg-red-400 hover:bg-red-500", + }, + }, +}); + +const Button: FunctionComponent<{ onClick: () => void }> = (props) => { + return ( + + ); +}; + +export default Button; + + + +import { FunctionComponent } from "preact"; +import { tv } from "tailwind-variants"; +import classes from "./Input.module.scss"; + +const input = tv({ + base: classes.input_field, + variants: { + "text-align": { + center: "text-center", + left: "text-left", + }, + }, + defaultVariants: { + "text-align": "left", + }, +}); + +interface InputProps { + isPassword?: boolean; + placeholder?: string; + textAlign?: "center" | "left"; +} + +const Input: FunctionComponent = ({ isPassword = false, placeholder = "", textAlign }: InputProps) => { + return ( + + ); +}; + +export default Input; + + + +@reference "../index.scss"; + +.menu_container { + @apply flex min-h-8 min-w-screen flex-col items-center gap-4 border-l border-l-gray-500 px-5 pt-5 md:min-h-screen md:min-w-[300px]; +} + +.menu_item { + @apply w-full cursor-pointer rounded-md px-6 py-2 text-center hover:bg-gray-200; +} + + + +import { FunctionComponent } from "preact"; +import { useLocation } from "preact-iso"; +import { tv } from "tailwind-variants"; +import classes from "./menu.module.scss"; + +interface MenuItemProps { + title: string; + link: string; +} + +const MenuItem: FunctionComponent = ({ title, link }: MenuItemProps) => { + const location = useLocation(); + const active = location.path === link; + const menuItemClasses = tv({ + base: classes.menu_item, + variants: { + activity: { + active: "bg-gray-200", + inactive: "bg-gray-100", + }, + }, + defaultVariants: { + activity: "inactive", + }, + }); + return ( +
location.route(link)}> + {title} +
+ ); +}; + +interface MenuItems { + title: string; + link: string; +} + +const Menu: FunctionComponent = () => { + const menu_items: MenuItems[] = [ + { + title: "Профиль", + link: "/profile", + }, + { + title: "Задачи", + link: "/tasks", + }, + { + title: "Календарь", + link: "/calendar", + }, + ]; + return ( +
+ {menu_items.map(({ title, link }) => ( + + ))} +
+ ); +}; + +export default Menu; +
+ + +@reference "../index.scss"; + +.login_container { + @apply flex min-h-screen flex-col items-center justify-center; +} + +.login_card { + @apply flex w-[95%] min-w-[300px] flex-col justify-center gap-2 rounded-md border-gray-400 p-5 shadow-md md:w-[350px]; +} + + + +import Button from "@/components/ui/Button"; +import Input from "@/components/ui/Input"; +import { useAppContext } from "@/providers/AuthProvider"; +import { FunctionComponent } from "preact"; +import { useLocation } from "preact-iso"; +import classes from "./login.module.scss"; +const LoginPage: FunctionComponent = () => { + const { isLoggedIn } = useAppContext(); + const location = useLocation(); + return ( +
+
+ + + +
+
+ ); +}; + +export default LoginPage; +
+ + +@import "tailwindcss"; +@import url("https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap"); +:root { + font-family: "Montserrat", sans-serif; +} + + + + + + + + + + Антихвост + + +
+ + + +
+ + +@reference "../../index.scss"; + +.input_field { + @apply rounded-md border border-gray-300 p-2 placeholder:transition focus:outline-0 focus:placeholder:opacity-25; +} + + + +import { FunctionComponent } from "preact"; +import { ErrorBoundary, lazy, LocationProvider, Route, Router, useLocation } from "preact-iso"; +import "preact/debug"; +import LoginPage from "./pages/login"; +import { AppProvider } from "./providers/AuthProvider"; + +const HomePage: FunctionComponent = () => { + const location = useLocation(); + location.route("/login"); + return
Redirecting to login...
; +}; + +export function App() { + return ( + + + + + + + import("./pages/profile"))} /> + + + + + ); +} +
+ + +{ + "tabWidth": 2, + "printWidth": 120, + "arrowParens": "always", + "singleQuote": false, + "trailingComma": "es5", + "useTabs": false, + "semi": true, + "bracketSpacing": true, + "plugins": ["prettier-plugin-tailwindcss"], + "tailwindFunctions": ["tv"] +} + + + +{ + "name": "anti-hvost", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "preview": "vite preview" + }, + "dependencies": { + "@preact/signals": "^2.0.2", + "@tailwindcss/postcss": "^4.0.17", + "@tailwindcss/vite": "^4.0.17", + "clsx": "^2.1.1", + "postcss": "^8.5.3", + "preact": "^10.26.2", + "preact-iso": "^2.9.1", + "tailwind-merge": "^3.0.2", + "tailwind-variants": "^1.0.0", + "tailwindcss": "^4.0.17" + }, + "devDependencies": { + "@eslint/js": "^9.23.0", + "@preact/preset-vite": "^2.10.1", + "@typescript-eslint/parser": "^8.28.0", + "eslint": "^9.23.0", + "eslint-config-prettier": "^10.1.1", + "prettier": "^3.5.3", + "prettier-eslint": "^16.3.0", + "prettier-plugin-tailwindcss": "^0.6.11", + "sass-embedded": "^1.86.0", + "typescript": "~5.7.2", + "typescript-eslint": "^8.28.0", + "vite": "^6.2.0", + "vite-tsconfig-paths": "^5.1.4" + } +} + + +
diff --git a/src/pages/profile_tasks.tsx b/src/pages/profile_tasks.tsx index 109aa7a..da96cf0 100644 --- a/src/pages/profile_tasks.tsx +++ b/src/pages/profile_tasks.tsx @@ -3,6 +3,7 @@ import Task from "@/components/task"; import ModalCalendar from "@/components/ModalCalendar"; import ModalTags, { ITags } from "@/components/ModalTags"; import Button from "@/components/ui/Button"; +import Dialog from "@/components/ui/Dialog"; import ModalWindow from "@/components/ui/Modal"; import { withTitle } from "@/constructors/Component"; import { UrlsTitle } from "@/enums/urls"; @@ -26,7 +27,6 @@ import { SubmitHandler, useForm } from "react-hook-form"; import { v4 as uuid } from "uuid"; import { ITask, ITaskForm } from "./profile_tasks.dto"; import classes from "./profile_tasks.module.scss"; -import Dialog from "@/components/ui/Dialog"; const example_tags: { first: string[]; second: string[] } = { first: ["Программирование", "Информатика", "Физика", "Математика"], @@ -117,29 +117,27 @@ const ProfileTasks: FunctionComponent = () => { const groupTasksByDate = useMemo(() => { const today = new Date(); today.setHours(0, 0, 0, 0); - + const tomorrow = new Date(today); tomorrow.setDate(tomorrow.getDate() + 1); - + const groupedTasks = { today: [] as ITask[], tomorrow: [] as ITask[], future: [] as { date: Date; tasks: ITask[] }[], }; - tasks.forEach(task => { + tasks.forEach((task) => { const taskDate = new Date(task.date); taskDate.setHours(0, 0, 0, 0); - + if (taskDate.getTime() === today.getTime()) { groupedTasks.today.push(task); } else if (taskDate.getTime() === tomorrow.getTime()) { groupedTasks.tomorrow.push(task); } else if (taskDate > tomorrow) { - const existingGroup = groupedTasks.future.find(group => - group.date.getTime() === taskDate.getTime() - ); - + const existingGroup = groupedTasks.future.find((group) => group.date.getTime() === taskDate.getTime()); + if (existingGroup) { existingGroup.tasks.push(task); } else { @@ -152,7 +150,7 @@ const ProfileTasks: FunctionComponent = () => { groupedTasks.today.sort((a, b) => a.date.getTime() - b.date.getTime()); groupedTasks.tomorrow.sort((a, b) => a.date.getTime() - b.date.getTime()); groupedTasks.future.sort((a, b) => a.date.getTime() - b.date.getTime()); - groupedTasks.future.forEach(group => { + groupedTasks.future.forEach((group) => { group.tasks.sort((a, b) => a.date.getTime() - b.date.getTime()); }); @@ -163,7 +161,7 @@ const ProfileTasks: FunctionComponent = () => { return new Intl.DateTimeFormat("ru-RU", { day: "numeric", month: "long", - year: "numeric" + year: "numeric", }).format(date); }; @@ -483,7 +481,7 @@ const ProfileTasks: FunctionComponent = () => { ) : ( <>
Начни уже сегодня!
-