Files
commit-it/src/App.tsx
2026-03-27 11:20:54 +09:00

224 lines
9.0 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState } from 'react'
import { motion, useMotionValueEvent, useScroll } from "motion/react"
import TypingEffect from './components/TypingEffect'
import CardsSection from './components/CardsSection'
import Section from './components/Section'
import Marquee from './components/Marquee'
import Navbar from './components/Navbar'
import ServicesSection from './components/ServicesSection'
import ProductsSection from './components/ProductsSection'
import CaseSection from './components/CaseSection'
import Footer from './components/Footer'
import AboutSection from './components/AboutSection'
import LicenseSection from './components/LicenseSection'
import MissionSection from './components/MissionSection'
import { TypingSpan } from './components/TypingSpan'
import DirectorSection from './components/DirectorSection'
function App() {
const { scrollY } = useScroll()
const [hidden, setHidden] = useState(false)
const [isAtTop, setIsAtTop] = useState(true)
useMotionValueEvent(scrollY, "change", (current) => {
const previous = scrollY.getPrevious() ?? 0
setIsAtTop(current === 0)
if (current > previous && current > 150) {
setHidden(true)
} else {
setHidden(false)
}
})
const partners = [
{
src: '/xkvadrat.svg'
},
{
src: '/rcit-BccMYqhE.svg'
},
{
src: '/vodokanal.svg'
},
{
src: '/tesaldan.svg'
},
{
src: '/tehnopark.svg'
},
{
src: '/sakhaspectrans-xe6pCR8Q.svg'
},
{
src: '/jkhsakha.svg'
},
]
const handleLink = () => {
const modal = document.getElementById('my_modal_2')
if (modal) {
(modal as HTMLDialogElement).close()
}
}
const languages = ['/python.svg', '/csharp.svg', '/js.svg', '/1c.svg']
const programs = ['/1c_franch.svg', '/astralinux.svg', '/drweb.svg', '/kasperskylab.svg']
return (
<main className='w-full flex flex-col sm:gap-8 items-center'>
<dialog id="my_modal_2" className="modal modal-end">
<div className="modal-box w-3/4 flex flex-col gap-8">
<div className='flex flex-row justify-between items-center'>
<div className="logo">
<img className="dark:invert dark:hue-rotate-180" width={180} src='/logo-commit.png' />
</div>
<form method="dialog">
<button className="btn btn-sm btn-circle btn-ghost p-2 text-2xl"></button>
</form>
</div>
<form method="dialog" className='flex flex-col gap-4'>
<a onClick={handleLink} href="#about" className='text-xl text-gray-500 hover:text-blue-500'>О компании</a>
<a onClick={handleLink} href="#products" className='text-xl text-gray-500 hover:text-blue-500'>Программные продукты</a>
<a onClick={handleLink} href="#services" className='text-xl text-gray-500 hover:text-blue-500'>Услуги</a>
<a onClick={handleLink} href="#case" className='text-xl text-gray-500 hover:text-blue-500'>Главный кейс</a>
<a onClick={handleLink} href="#contacts" className='text-xl text-gray-500 hover:text-blue-500'>Контакты</a>
</form>
</div>
<form method="dialog" className="modal-backdrop backdrop-blur-xs">
<button>close</button>
</form>
</dialog>
<Section>
<div className='h-full flex flex-col'>
<motion.header
className={`top-0 left-0 right-0 w-full backdrop-blur-2xl flex justify-center`}
initial={{ opacity: '0' }}
whileInView={{ opacity: '1' }}
>
<Navbar />
</motion.header>
<motion.header
className={`${isAtTop ? 'hidden' : ''} z-10 w-full fixed top-0 left-0 right-0 backdrop-blur-lg bg-base-100/70 flex justify-center`}
animate={{
y: hidden ? -140 : 0,
opacity: hidden ? 0 : 1,
}}
transition={{ duration: 0.3, ease: "easeInOut" }}
>
<Navbar />
</motion.header>
<div className='relative grid sm:grid-cols-2 h-auto grow gap-8 rounded-2xl bg-base-200 p-8'>
<div className='z-1 h-auto grow flex flex-col gap-4'>
<span className='text-xs text-gray-500 bg-base-100 rounded-2xl p-2 flex justify-center'>Все наши специалисты имеют профессиональное образование и опыт более 15 лет работы</span>
<div className='text-3xl grid grid-rows-[repeat(4,1fr)] md:grid-rows-[1fr_1fr]'>
<span className='row-span-2 md:row-span-1'>Программное обеспечение</span>
<div className='row-span-2 inline-flex flex-wrap w-full text-blue-400 h-min'>
<TypingSpan typingSpeed={40} deletingSpeed={20} pauseTime={2000} />
</div>
{/* <span> — полный цикл разработки и технической поддержки</span> */}
</div>
<span className='text-gray-500'>
Берём ответственность за ваши ИТ-решения, снимая риски и операционную нагрузку, выступая надёжным технологическим партнёром по разработке и сопровождению
</span>
<div className='flex flex-col gap-4'>
<span className='text-xs text-gray-500'>
Работаем с такими языками программирования, как:
</span>
<div className='flex flex-row'>
{languages.map((lang, index) => (
<div key={index} style={{ marginLeft: index === 0 ? '' : '-0.5rem' }} className='border-2 border-base-200 w-12.5 h-12.5 flex justify-center items-center p-2 rounded-full overflow-hidden bg-white'>
<img src={lang} />
</div>
))}
</div>
<span className='text-xs text-gray-500'>
Работаем с такими программами, как:
</span>
<div className='flex flex-row'>
{programs.map((lang, index) => (
<div key={index} style={{ marginLeft: index === 0 ? '' : '-0.5rem' }} className='border-2 border-base-200 w-12.5 h-12.5 flex justify-center items-center p-2 rounded-full overflow-hidden bg-white'>
<img src={lang} />
</div>
))}
</div>
</div>
</div>
<div className='absolute blur-xs sm:blur-none inset-0 sm:relative h-full w-full p-4'>
<TypingEffect text={`/*
Совет из продакшена:
если код "гениальный" — готовься его переписывать.
если код простой — скорее всего, он переживёт тебя.
*/
@font-face {
font-family: "HiddenFont";
src: local("Arial");
unicode-range: U+043F, U+043E, U+043C, U+043E, U+0433, U+0430, U+0435,
U+043C, U+0020, U+0441, U+0020, U+0440, U+0430, U+0437,
U+0440, U+0430, U+0431, U+043E, U+0442, U+043A, U+043E,
U+0439, U+043E, U+045E, U+048E, U+056E, U+068E, U+069E,
U+070E, U+074E, U+077E, U+079E, U+081E, U+083E, U+086E,
U+089E, U+091E, U+094E, U+095E, U+098E, U+099E, U+0533,
U+0536, U+0539, U+0555, U+0563, U+781, U+783, U+789;
body {
margin: 0;
font-family: Arial, sans-serif;
}
Если ты это читаешь:
— сборка прошла
— багов нет
/*
мы помогаем с разработкой программного обеспечения
и бережно сопровождаем на всех этапах работ
/*
TODO: не удалять — это не хаос, это философия */
`} speed={0.01} />
<div className='absolute inset-0 bg-linear-to-b from-base-200 to-transparent'></div>
</div>
</div>
</div>
</Section>
<CardsSection />
<AboutSection />
<div className="w-full overflow-hidden select-none py-8 bg-base-200">
<Marquee speed={20} items={partners} from={0} to={"-100%"} />
</div>
<DirectorSection />
<MissionSection />
<ProductsSection />
<ServicesSection />
<LicenseSection />
<CaseSection />
<Footer />
</main>
)
}
export default App