renamed: posts/regulations.mdx -> competition/regulations.mdx renamed: posts/festival-schedule.mdx -> competition/schedule.mdx modified: components/Navigation.tsx new file: components/UX/Block.tsx modified: components/UX/index.ts new file: components/UX/styles/block.css modified: package-lock.json modified: package.json modified: pages/_app.tsx modified: pages/_document.tsx modified: pages/about.tsx new file: pages/competition/[slug].tsx renamed: pages/registration.tsx -> pages/competition/registration.tsx modified: pages/contacts.tsx modified: pages/index.tsx modified: pages/posts/[slug].tsx new file: posts/robot-vex-iq-small.mdx deleted: posts/task-completion-examples.mdx new file: public/images/robot_builds/vex_iq_14/00.jpg new file: public/images/robot_builds/vex_iq_14/01.jpg new file: public/images/robot_builds/vex_iq_14/02.jpg new file: public/images/robot_builds/vex_iq_14/03.jpg new file: public/images/robot_builds/vex_iq_14/04.jpg new file: public/images/robot_builds/vex_iq_14/05.jpg new file: public/images/robot_builds/vex_iq_14/06.jpg new file: public/images/robot_builds/vex_iq_14/07.jpg new file: public/images/robot_builds/vex_iq_14/08.jpg new file: public/images/robot_builds/vex_iq_14/09.jpg new file: public/images/robot_builds/vex_iq_14/10.jpg new file: public/images/robot_builds/vex_iq_14/11.jpg new file: public/images/robot_builds/vex_iq_14/12.jpg new file: public/images/robot_builds/vex_iq_14/13.jpg new file: public/images/robot_builds/vex_iq_14/14.jpg new file: public/images/robot_builds/vex_iq_14/15.jpg new file: public/images/robot_builds/vex_iq_14/16.jpg new file: public/images/robot_builds/vex_iq_14/17.jpg new file: public/images/robot_builds/vex_iq_14/18.jpg new file: public/images/robot_builds/vex_iq_14/19.jpg new file: public/images/robot_builds/vex_iq_14/20.jpg new file: public/images/robot_builds/vex_iq_14/21.jpg new file: public/images/robot_builds/vex_iq_14/22.jpg new file: public/images/robot_builds/vex_iq_14/23.jpg new file: public/images/robot_builds/vex_iq_14/24.jpg new file: public/images/robot_builds/vex_iq_14/25.jpg new file: public/images/robot_builds/vex_iq_14/26.jpg new file: public/images/robot_builds/vex_iq_14/27.jpg new file: public/images/robot_builds/vex_iq_14/28.jpg new file: public/images/robot_builds/vex_iq_14/29.jpg new file: public/images/robot_builds/vex_iq_14/30.jpg new file: public/images/robot_builds/vex_iq_14/31.jpg new file: public/images/robot_builds/vex_iq_14/32.jpg new file: public/images/robot_builds/vex_iq_14/33.jpg new file: public/images/videoShort.png new file: public/pdf/robot_builds/vex_iq_14.pdf new file: public/video/shortpreck.mp4 new file: static.config.js modified: styles/globals.css modified: types/layout.ts modified: utils/mdxUtils.ts new file: utils/mdxUtilsComp.ts modified: yarn.lockmaster
@ -0,0 +1,13 @@ |
|||||||
|
import React from 'react'; |
||||||
|
|
||||||
|
type Props = { |
||||||
|
children?: JSX.Element[] | JSX.Element; |
||||||
|
} |
||||||
|
|
||||||
|
export const BlockHead: React.FC<Props> = ({children}) => { |
||||||
|
return( |
||||||
|
<div className='blockHead'> |
||||||
|
{children} |
||||||
|
</div> |
||||||
|
) |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
.blockHead { |
||||||
|
background: #e8e8e8; |
||||||
|
border-radius: 10px; |
||||||
|
} |
||||||
|
.blockHead span { |
||||||
|
background: white; |
||||||
|
display: inline-block; |
||||||
|
width: 100%; |
||||||
|
box-shadow: 0 5px 10px rgba(0,0,0,0.22); |
||||||
|
padding: 15px; |
||||||
|
border-radius: 10px; |
||||||
|
} |
@ -0,0 +1,95 @@ |
|||||||
|
import { format, parseISO } from 'date-fns'; |
||||||
|
import fs from 'fs'; |
||||||
|
import matter from 'gray-matter'; |
||||||
|
import { GetStaticPaths, GetStaticProps } from 'next'; |
||||||
|
import { serialize } from 'next-mdx-remote/serialize'; |
||||||
|
import { MDXRemote, MDXRemoteSerializeResult } from 'next-mdx-remote'; |
||||||
|
import Head from 'next/head'; |
||||||
|
import Image from 'next/image'; |
||||||
|
import Link from 'next/link'; |
||||||
|
import path from 'path'; |
||||||
|
import rehypeAutolinkHeadings from 'rehype-autolink-headings'; |
||||||
|
import rehypeSlug from 'rehype-slug'; |
||||||
|
import Layout, { WEBSITE_HOST_URL } from '../../components/Layout'; |
||||||
|
import { MetaProps } from '../../types/layout'; |
||||||
|
import { PostType } from '../../types/post'; |
||||||
|
import { postFilePathsComp, POSTS_PATH_COMP } from '../../utils/mdxUtilsComp'; |
||||||
|
|
||||||
|
// Custom components/renderers to pass to MDX.
|
||||||
|
// Since the MDX files aren't loaded by webpack, they have no knowledge of how
|
||||||
|
// to handle import statements. Instead, you must include components in scope
|
||||||
|
// here.
|
||||||
|
const components = { |
||||||
|
Head, |
||||||
|
Image, |
||||||
|
Link, |
||||||
|
}; |
||||||
|
|
||||||
|
type PostPageProps = { |
||||||
|
source: MDXRemoteSerializeResult; |
||||||
|
frontMatter: PostType; |
||||||
|
}; |
||||||
|
|
||||||
|
const PostPage = ({ source, frontMatter }: PostPageProps): JSX.Element => { |
||||||
|
const customMeta: MetaProps = { |
||||||
|
title: `${frontMatter.title} - RoboTop`, |
||||||
|
description: frontMatter.description, |
||||||
|
image: `${WEBSITE_HOST_URL}${frontMatter.image}`, |
||||||
|
date: frontMatter.date, |
||||||
|
type: 'article', |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<Layout customMeta={customMeta}> |
||||||
|
<article className="max-w"> |
||||||
|
<h1 className="mb-3 text-gray-900 dark:text-white"> |
||||||
|
{frontMatter.title} |
||||||
|
</h1> |
||||||
|
<p className="mb-10 text-sm text-gray-500 dark:text-gray-400"> |
||||||
|
{format(parseISO(frontMatter.date), 'MMMM dd, yyyy')} |
||||||
|
</p> |
||||||
|
<div className="prose dark:prose-dark"> |
||||||
|
<MDXRemote {...source} components={components} /> |
||||||
|
</div> |
||||||
|
</article> |
||||||
|
</Layout> |
||||||
|
); |
||||||
|
}; |
||||||
|
|
||||||
|
export const getStaticProps: GetStaticProps = async ({ params }) => { |
||||||
|
const postFilePath = path.join(POSTS_PATH_COMP, `${params.slug}.mdx`); |
||||||
|
const source = fs.readFileSync(postFilePath); |
||||||
|
|
||||||
|
const { content, data } = matter(source); |
||||||
|
|
||||||
|
const mdxSource = await serialize(content, { |
||||||
|
// Optionally pass remark/rehype plugins
|
||||||
|
mdxOptions: { |
||||||
|
remarkPlugins: [require('remark-code-titles')], |
||||||
|
rehypePlugins: [rehypeSlug, rehypeAutolinkHeadings], |
||||||
|
}, |
||||||
|
scope: data, |
||||||
|
}); |
||||||
|
|
||||||
|
return { |
||||||
|
props: { |
||||||
|
source: mdxSource, |
||||||
|
frontMatter: data, |
||||||
|
}, |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
export const getStaticPaths: GetStaticPaths = async () => { |
||||||
|
const paths = postFilePathsComp |
||||||
|
// Remove file extensions for page paths
|
||||||
|
.map((path) => path.replace(/\.mdx?$/, '')) |
||||||
|
// Map the path into the static paths object required by Next.js
|
||||||
|
.map((slug) => ({ params: { slug } })); |
||||||
|
|
||||||
|
return { |
||||||
|
paths, |
||||||
|
fallback: false, |
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
export default PostPage; |
@ -1,10 +1,10 @@ |
|||||||
import React, {useEffect, useState} from 'react'; |
import React, {useEffect, useState} from 'react'; |
||||||
import Layout from '../components/Layout'; |
import Layout from '../../components/Layout'; |
||||||
import RegistrationForm from '../components/RegistrationForm'; |
import RegistrationForm from '../../components/RegistrationForm'; |
||||||
import LoadingTeamsForm from '../components/LoadingTeamsForm'; |
import LoadingTeamsForm from '../../components/LoadingTeamsForm'; |
||||||
import { useSelector } from 'react-redux'; |
import { useSelector } from 'react-redux'; |
||||||
import { useAppDispatch } from '../redux/store'; |
import { useAppDispatch } from '../../redux/store'; |
||||||
import { fetchUser, selectUserData } from '../redux/user'; |
import { fetchUser, selectUserData } from '../../redux/user'; |
||||||
import { ToastContainer, toast } from 'react-toastify'; |
import { ToastContainer, toast } from 'react-toastify'; |
||||||
import 'react-toastify/dist/ReactToastify.css'; |
import 'react-toastify/dist/ReactToastify.css'; |
||||||
|
|
@ -0,0 +1,19 @@ |
|||||||
|
--- |
||||||
|
title: Робот на VEX IQ размером не больше 14х14х14 см |
||||||
|
description: Данный робот создавался для городского этапа олимпиады по технологии. |
||||||
|
date: '2022-12-23' |
||||||
|
--- |
||||||
|
|
||||||
|
## Робот на VEX IQ размером не больше 14х14х14 см |
||||||
|
|
||||||
|
<Image |
||||||
|
alt={`Регламент проведения соревнования.`} |
||||||
|
src={`/images/robot_builds/vex_iq_14/00.jpg`} |
||||||
|
width={3360} |
||||||
|
height={2250} |
||||||
|
priority |
||||||
|
/> |
||||||
|
|
||||||
|
### [Скачать инструкцию в формате pdf](../pdf/robot_builds/vex_iq_14.pdf) |
||||||
|
|
||||||
|
На главную [Home](/) |
@ -1,11 +0,0 @@ |
|||||||
--- |
|
||||||
title: Примеры выполнения задания |
|
||||||
description: Видео по выполнения заданий и материалы по сборке и программирования робота |
|
||||||
date: '2022-07-02' |
|
||||||
--- |
|
||||||
|
|
||||||
На данный момент мы подготавливаем материал для публикации на сайте. |
|
||||||
Весь материал будет опубликован до 14 ноября 2022 года. |
|
||||||
|
|
||||||
|
|
||||||
На главную [Home](/) |
|
After Width: | Height: | Size: 343 KiB |
After Width: | Height: | Size: 157 KiB |
After Width: | Height: | Size: 156 KiB |
After Width: | Height: | Size: 162 KiB |
After Width: | Height: | Size: 163 KiB |
After Width: | Height: | Size: 137 KiB |
After Width: | Height: | Size: 143 KiB |
After Width: | Height: | Size: 128 KiB |
After Width: | Height: | Size: 177 KiB |
After Width: | Height: | Size: 166 KiB |
After Width: | Height: | Size: 351 KiB |
After Width: | Height: | Size: 240 KiB |
After Width: | Height: | Size: 142 KiB |
After Width: | Height: | Size: 96 KiB |
After Width: | Height: | Size: 126 KiB |
After Width: | Height: | Size: 154 KiB |
After Width: | Height: | Size: 151 KiB |
After Width: | Height: | Size: 122 KiB |
After Width: | Height: | Size: 175 KiB |
After Width: | Height: | Size: 387 KiB |
After Width: | Height: | Size: 226 KiB |
After Width: | Height: | Size: 245 KiB |
After Width: | Height: | Size: 224 KiB |
After Width: | Height: | Size: 218 KiB |
After Width: | Height: | Size: 264 KiB |
After Width: | Height: | Size: 332 KiB |
After Width: | Height: | Size: 146 KiB |
After Width: | Height: | Size: 167 KiB |
After Width: | Height: | Size: 265 KiB |
After Width: | Height: | Size: 280 KiB |
After Width: | Height: | Size: 279 KiB |
After Width: | Height: | Size: 247 KiB |
After Width: | Height: | Size: 306 KiB |
After Width: | Height: | Size: 343 KiB |
After Width: | Height: | Size: 735 KiB |
@ -0,0 +1,3 @@ |
|||||||
|
export default { |
||||||
|
plugins: ["react-static-plugin-mdx"] |
||||||
|
}; |
@ -0,0 +1,11 @@ |
|||||||
|
import fs from 'fs'; |
||||||
|
import path from 'path'; |
||||||
|
|
||||||
|
// POSTS_PATH is useful when you want to get the path to a specific file
|
||||||
|
export const POSTS_PATH_COMP = path.join(process.cwd(), 'competition'); |
||||||
|
|
||||||
|
// postFilePaths is the list of all mdx files inside the POSTS_PATH directory
|
||||||
|
export const postFilePathsComp = fs |
||||||
|
.readdirSync(POSTS_PATH_COMP) |
||||||
|
// Only include md(x) files
|
||||||
|
.filter((path) => /\.mdx?$/.test(path)); |