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 Layout from '../components/Layout'; |
||||
import RegistrationForm from '../components/RegistrationForm'; |
||||
import LoadingTeamsForm from '../components/LoadingTeamsForm'; |
||||
import Layout from '../../components/Layout'; |
||||
import RegistrationForm from '../../components/RegistrationForm'; |
||||
import LoadingTeamsForm from '../../components/LoadingTeamsForm'; |
||||
import { useSelector } from 'react-redux'; |
||||
import { useAppDispatch } from '../redux/store'; |
||||
import { fetchUser, selectUserData } from '../redux/user'; |
||||
import { useAppDispatch } from '../../redux/store'; |
||||
import { fetchUser, selectUserData } from '../../redux/user'; |
||||
import { ToastContainer, toast } from 'react-toastify'; |
||||
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)); |