Merge Problems with Web/To be tested
47
.gitignore
vendored
@ -1,24 +1,29 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# 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
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
.env
|
||||
|
||||
# vscode
|
||||
.vscode
|
||||
8
.idea/.gitignore
vendored
@ -1,8 +0,0 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="jdk" jdkName="Python 3.11" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
@ -1,19 +0,0 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredPackages">
|
||||
<value>
|
||||
<list size="5">
|
||||
<item index="0" class="java.lang.String" itemvalue="pandas" />
|
||||
<item index="1" class="java.lang.String" itemvalue="networkx" />
|
||||
<item index="2" class="java.lang.String" itemvalue="seaborn" />
|
||||
<item index="3" class="java.lang.String" itemvalue="matplotlib" />
|
||||
<item index="4" class="java.lang.String" itemvalue="Pillow" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
@ -1,6 +0,0 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.11" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/SOS12.iml" filepath="$PROJECT_DIR$/.idea/SOS12.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
86
README.md
@ -1,70 +1,20 @@
|
||||
# Getting Started with Create React App
|
||||
# Build and Deploy a Fantastic 3D Portfolio Website with Three.js and React.js
|
||||

|
||||
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
## Introduction
|
||||
The most impressive websites in the world use 3D graphics and animations to bring their content to life. Learn how to build your own ThreeJS 3D Developer Portfolio today!
|
||||
|
||||
In this course, you'll learn the following:
|
||||
- ThreeJS - a powerful 3D graphics library for rendering and animating the 3D model
|
||||
- React Three Fiber - a popular library for creating 3D graphics with ThreeJS in React
|
||||
- TailwindCSS - a popular utility-first CSS styling framework
|
||||
- Framer Motion - the most popular library used to bring your React website to life with animations
|
||||
You'll also learn how to:
|
||||
- Load, create and customize stunning 3D models and geometries with various lights, as well as understand the 3D world with a camera and positioning of an object in space.
|
||||
- Make your code reusable and scalable using Higher Order Components (HOCs) and other industry-standard best practices
|
||||
- Implement sending emails through a form on the website
|
||||
- Ensure responsiveness across all devices and improve your site's performance using Suspense and Preload.
|
||||
|
||||
## Available Scripts
|
||||
|
||||
In the project directory, you can run:
|
||||
|
||||
### `npm start`
|
||||
|
||||
Runs the app in the development mode.\
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
|
||||
|
||||
The page will reload when you make changes.\
|
||||
You may also see any lint errors in the console.
|
||||
|
||||
### `npm test`
|
||||
|
||||
Launches the test runner in the interactive watch mode.\
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
|
||||
### `npm run build`
|
||||
|
||||
Builds the app for production to the `build` folder.\
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
|
||||
The build is minified and the filenames include the hashes.\
|
||||
Your app is ready to be deployed!
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
|
||||
### `npm run eject`
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can't go back!**
|
||||
|
||||
If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
|
||||
|
||||
You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
|
||||
|
||||
## Learn More
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
|
||||
### Code Splitting
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
|
||||
## Want to land your dream programming job in 3 - 6 months?
|
||||
⭐ JSM Masterclass Experience - https://jsmastery.pro/masterclass
|
||||
Become a Software Engineer. Guaranteed.
|
||||
|
||||
13
index.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="./public/logo.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>SOS CAMP | 12TH</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.jsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
17945
package-lock.json
generated
69
package.json
@ -1,48 +1,43 @@
|
||||
{
|
||||
"name": "sos12-web",
|
||||
"version": "0.1.0",
|
||||
"name": "3dfolio",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emailjs/browser": "^3.11.0",
|
||||
"@emailjs/browser": "^3.10.0",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@fontsource/roboto": "^5.0.3",
|
||||
"@mui/icons-material": "^5.11.16",
|
||||
"@headlessui/react": "^1.7.15",
|
||||
"@heroicons/react": "^2.0.18",
|
||||
"@mui/material": "^5.13.6",
|
||||
"@mui/styled-engine-sc": "^5.12.0",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"emailjs": "^4.0.2",
|
||||
"@react-three/drei": "^9.56.24",
|
||||
"@react-three/fiber": "^8.11.1",
|
||||
"add": "^2.0.6",
|
||||
"framer-motion": "^9.0.7",
|
||||
"maath": "^0.5.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-switch": "^7.0.0",
|
||||
"styled-components": "^5.3.11",
|
||||
"web-vitals": "^2.1.4"
|
||||
"react-icons": "^4.10.1",
|
||||
"react-router-dom": "^6.8.1",
|
||||
"react-scroll": "^1.8.9",
|
||||
"react-three-fiber": "^6.0.13",
|
||||
"react-tilt": "^0.1.4",
|
||||
"react-vertical-timeline-component": "^3.6.0",
|
||||
"three": "^0.154.0",
|
||||
"yarn": "^1.22.19"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.0.27",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"@vitejs/plugin-react": "^3.1.0",
|
||||
"autoprefixer": "^10.4.13",
|
||||
"postcss": "^8.4.21",
|
||||
"tailwindcss": "^3.2.6",
|
||||
"vite": "^4.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
6
postcss.config.cjs
Normal file
@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
}
|
||||
}
|
||||
@ -1,10 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Hello world</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
1
public/logo.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
254
src/App.jsx
@ -1,228 +1,32 @@
|
||||
import * as React from 'react';
|
||||
import AppBar from '@mui/material/AppBar';
|
||||
import Button from '@mui/material/Button';
|
||||
import Card from '@mui/material/Card';
|
||||
import CardActions from '@mui/material/CardActions';
|
||||
import CardContent from '@mui/material/CardContent';
|
||||
import CardMedia from '@mui/material/CardMedia';
|
||||
import CssBaseline from '@mui/material/CssBaseline';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import Box from '@mui/material/Box';
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Container from '@mui/material/Container';
|
||||
import Link from '@mui/material/Link';
|
||||
import Checkbox from '@mui/material/Checkbox';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import {styled} from '@mui/material/styles';
|
||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import {createTheme, ThemeProvider} from '@mui/material/styles';
|
||||
import cards from './Card';
|
||||
import Contact from "./Contact";
|
||||
import {createContext, useState} from "react";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import { Menu, Guide, Navbar, Contacts, StarsCanvas, Problems, Faq } from "./components";
|
||||
import "./index.css"
|
||||
import "./components/Problems.css"
|
||||
|
||||
export const ThemeContext = createContext(null);
|
||||
|
||||
// switch theme button ---------------------------------------------------------------
|
||||
const MaterialUISwitch = styled(Switch)(({theme}) => ({
|
||||
width: 62,
|
||||
height: 34,
|
||||
padding: 7,
|
||||
'& .MuiSwitch-switchBase': {
|
||||
margin: 1,
|
||||
padding: 0,
|
||||
transform: 'translateX(6px)',
|
||||
'&.Mui-checked': {
|
||||
color: '#fff',
|
||||
transform: 'translateX(22px)',
|
||||
'& .MuiSwitch-thumb:before': {
|
||||
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
|
||||
'#fff',
|
||||
)}" d="M4.2 2.5l-.7 1.8-1.8.7 1.8.7.7 1.8.6-1.8L6.7 5l-1.9-.7-.6-1.8zm15 8.3a6.7 6.7 0 11-6.6-6.6 5.8 5.8 0 006.6 6.6z"/></svg>')`,
|
||||
},
|
||||
'& + .MuiSwitch-track': {
|
||||
opacity: 1,
|
||||
backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : 'white',
|
||||
},
|
||||
},
|
||||
},
|
||||
'& .MuiSwitch-thumb': {
|
||||
backgroundColor: theme.palette.mode === 'dark' ? '#003892' : '#7892B5',
|
||||
width: 32,
|
||||
height: 32,
|
||||
'&:before': {
|
||||
content: "''",
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
left: 0,
|
||||
top: 0,
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundPosition: 'center',
|
||||
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
|
||||
'#fff',
|
||||
)}" d="M9.305 1.667V3.75h1.389V1.667h-1.39zm-4.707 1.95l-.982.982L5.09 6.072l.982-.982-1.473-1.473zm10.802 0L13.927 5.09l.982.982 1.473-1.473-.982-.982zM10 5.139a4.872 4.872 0 00-4.862 4.86A4.872 4.872 0 0010 14.862 4.872 4.872 0 0014.86 10 4.872 4.872 0 0010 5.139zm0 1.389A3.462 3.462 0 0113.471 10a3.462 3.462 0 01-3.473 3.472A3.462 3.462 0 016.527 10 3.462 3.462 0 0110 6.528zM1.665 9.305v1.39h2.083v-1.39H1.666zm14.583 0v1.39h2.084v-1.39h-2.084zM5.09 13.928L3.616 15.4l.982.982 1.473-1.473-.982-.982zm9.82 0l-.982.982 1.473 1.473.982-.982-1.473-1.473zM9.305 16.25v2.083h1.389V16.25h-1.39z"/></svg>')`,
|
||||
},
|
||||
},
|
||||
'& .MuiSwitch-track': {
|
||||
opacity: 1,
|
||||
backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : '#aab4be',
|
||||
borderRadius: 20 / 2,
|
||||
},
|
||||
}));
|
||||
// switch theme button ----------------------------------------------------------------
|
||||
|
||||
function Copyright() {
|
||||
return (
|
||||
<Typography variant="body2" color="#5585A4" align="center">
|
||||
{'Copyright © '}
|
||||
<Link color="inherit" href="https://mui.com/">
|
||||
Your Website
|
||||
</Link>{' '}
|
||||
{new Date().getFullYear()}
|
||||
{'.'}
|
||||
</Typography>
|
||||
);
|
||||
const App = () => {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<div className='relative z-0 bg-primary'>
|
||||
<div className='bg-[#050816]'>
|
||||
<Navbar />
|
||||
<Routes>
|
||||
<Route path="/" element={<Menu />} />
|
||||
<Route path="/problems" element={<Problems />} />
|
||||
<Route path="/guide" element={<Guide />} />
|
||||
<Route path="/contacts" element={<Contacts />} />
|
||||
<Route path="/contact" element={<Contacts />} />
|
||||
<Route path="/faq" element={<Faq />} />
|
||||
</Routes>
|
||||
</div>
|
||||
<StarsCanvas />
|
||||
<div className='relative z-0'>
|
||||
{/* <Contact /> */}
|
||||
{/* <StarsCanvas /> */}
|
||||
</div>
|
||||
</div>
|
||||
</BrowserRouter>
|
||||
);
|
||||
}
|
||||
|
||||
const defaultTheme = createTheme();
|
||||
|
||||
export default function App() {
|
||||
|
||||
const [theme, setTheme] = useState('light');
|
||||
|
||||
const toggleTheme = () => {
|
||||
setTheme(theme === 'light' ? 'dark' : 'light');
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="App" id={theme}>
|
||||
<ThemeContext.Provider value={{theme, toggleTheme}}>
|
||||
|
||||
<ThemeProvider theme={defaultTheme}>
|
||||
<CssBaseline/>
|
||||
|
||||
<AppBar position="relative">
|
||||
<Toolbar>
|
||||
<Typography variant="h6" color="inherit" noWrap>
|
||||
SOS12 Problems Collection
|
||||
</Typography>
|
||||
|
||||
<Typography variant="h6" color="inherit" noWrap className='anotherNav'>
|
||||
<a href="https://www.youtube.com" target="_self">Another Nav </a>
|
||||
</Typography>
|
||||
<FormControlLabel
|
||||
control={<MaterialUISwitch sx={{m: 1}} defaultChecked/>}
|
||||
label=""
|
||||
onChange={toggleTheme}
|
||||
checked={theme === 'dark'}
|
||||
/>
|
||||
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
|
||||
<main>
|
||||
{/* Hero unit */}
|
||||
<Box sx={{pt: 8, pb: 6,}}>
|
||||
<Container maxWidth="sm">
|
||||
<Typography
|
||||
component="h1"
|
||||
variant="h2"
|
||||
align="center"
|
||||
gutterBottom
|
||||
>
|
||||
SOS12
|
||||
</Typography>
|
||||
<Typography component="h5" variant="h5" align="center" paragraph>
|
||||
Welcome to the 12th SOS camp, a preparation camp for SKE21 students.
|
||||
We hope that students will definitely gain knowledge
|
||||
and enjoyment.
|
||||
</Typography>
|
||||
<Stack
|
||||
sx={{pt: 4}}
|
||||
direction="row"
|
||||
spacing={2}
|
||||
justifyContent="center"
|
||||
>
|
||||
<Button
|
||||
className="headButton"
|
||||
variant="contained"
|
||||
href="https://www.cpe.ku.ac.th/?lang=th">
|
||||
CPE website
|
||||
</Button>
|
||||
<Button
|
||||
className="headButton"
|
||||
variant="contained"
|
||||
href="https://www.cpe.ku.ac.th/?lang=th">
|
||||
Secondary action
|
||||
</Button>
|
||||
</Stack>
|
||||
</Container>
|
||||
</Box>
|
||||
<Container
|
||||
sx={{py: 8}} maxWidth="fit-content">
|
||||
{/* End hero unit */}
|
||||
<Grid container spacing={4}>
|
||||
|
||||
{/*# TODO:Edit the Jode here */}
|
||||
{cards.map((card) => (
|
||||
<Grid item xs={12} sm={6} md={4}>
|
||||
{/*<img src={require("./images/syntax.jpeg")} alt="jode"/>*/}
|
||||
<Card
|
||||
sx={{
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<CardMedia
|
||||
component="div"
|
||||
sx={{
|
||||
// 16:9
|
||||
pt: '56.25%',
|
||||
height: 0,
|
||||
// objectFit: 'cover',
|
||||
}}
|
||||
image={require(`${card.img}`)}
|
||||
/>
|
||||
|
||||
<CardContent sx={{flexGrow: 1}}>
|
||||
<Typography gutterBottom variant="h5" component="h2"
|
||||
color="#7DD6F6">
|
||||
{card.title}
|
||||
</Typography>
|
||||
<Typography color="aliceblue">
|
||||
{card.describe}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button size="small"><a
|
||||
href={card.link}>View</a></Button>
|
||||
<Checkbox className="jodeCheckBox"/>
|
||||
</CardActions>
|
||||
</Card>
|
||||
</Grid>
|
||||
))}
|
||||
|
||||
</Grid>
|
||||
<Contact />
|
||||
</Container>
|
||||
</main>
|
||||
{/* Footer */}
|
||||
<Box sx={{p: 6}} component="footer">
|
||||
<Typography variant="h6" align="center" gutterBottom>
|
||||
Footer
|
||||
</Typography>
|
||||
<Typography variant="subtitle1" align="center" component="p">
|
||||
Something here to give the footer a purpose!
|
||||
</Typography>
|
||||
<Copyright/>
|
||||
</Box>
|
||||
{/* End footer */}
|
||||
</ThemeProvider>
|
||||
|
||||
</ThemeContext.Provider>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default App;
|
||||
|
||||
BIN
src/assets/Discord.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
src/assets/carrent.png
Normal file
|
After Width: | Height: | Size: 741 KiB |
3
src/assets/close.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.4099 9L16.7099 2.71C16.8982 2.5217 17.004 2.2663 17.004 2C17.004 1.7337 16.8982 1.47831 16.7099 1.29C16.5216 1.1017 16.2662 0.995911 15.9999 0.995911C15.7336 0.995911 15.4782 1.1017 15.2899 1.29L8.99994 7.59L2.70994 1.29C2.52164 1.1017 2.26624 0.995911 1.99994 0.995911C1.73364 0.995911 1.47824 1.1017 1.28994 1.29C1.10164 1.47831 0.995847 1.7337 0.995847 2C0.995847 2.2663 1.10164 2.5217 1.28994 2.71L7.58994 9L1.28994 15.29C1.19621 15.383 1.12182 15.4936 1.07105 15.6154C1.02028 15.7373 0.994141 15.868 0.994141 16C0.994141 16.132 1.02028 16.2627 1.07105 16.3846C1.12182 16.5064 1.19621 16.617 1.28994 16.71C1.3829 16.8037 1.4935 16.8781 1.61536 16.9289C1.73722 16.9797 1.86793 17.0058 1.99994 17.0058C2.13195 17.0058 2.26266 16.9797 2.38452 16.9289C2.50638 16.8781 2.61698 16.8037 2.70994 16.71L8.99994 10.41L15.2899 16.71C15.3829 16.8037 15.4935 16.8781 15.6154 16.9289C15.7372 16.9797 15.8679 17.0058 15.9999 17.0058C16.132 17.0058 16.2627 16.9797 16.3845 16.9289C16.5064 16.8781 16.617 16.8037 16.7099 16.71C16.8037 16.617 16.8781 16.5064 16.9288 16.3846C16.9796 16.2627 17.0057 16.132 17.0057 16C17.0057 15.868 16.9796 15.7373 16.9288 15.6154C16.8781 15.4936 16.8037 15.383 16.7099 15.29L10.4099 9Z" fill="#FFFFFF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/company/meta.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
src/assets/company/shopify.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
src/assets/company/starbucks.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/assets/company/tesla.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
src/assets/contacts.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
src/assets/facebook.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
src/assets/faq.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
src/assets/github.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
src/assets/guide.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
src/assets/herobg.png
Normal file
|
After Width: | Height: | Size: 909 KiB |
42
src/assets/index.js
Normal file
@ -0,0 +1,42 @@
|
||||
import logo from "./logo.svg";
|
||||
import problems from "./problems.png";
|
||||
import guide from "./guide.png";
|
||||
import github from "./github.png";
|
||||
import menu from "./menu.svg";
|
||||
import close from "./close.svg";
|
||||
import contacts_pic from "./contacts.png"
|
||||
import faq_pic from "./faq.png"
|
||||
|
||||
import meta from "./company/meta.png";
|
||||
import shopify from "./company/shopify.png";
|
||||
import starbucks from "./company/starbucks.png";
|
||||
import tesla from "./company/tesla.png";
|
||||
|
||||
import carrent from "./carrent.png";
|
||||
import jobit from "./jobit.png";
|
||||
import tripguide from "./tripguide.png";
|
||||
|
||||
import discord_icon from './Discord.png';
|
||||
import instagram_icon from './instagram.png';
|
||||
import facebook_icon from './facebook.png';
|
||||
|
||||
export {
|
||||
logo,
|
||||
guide,
|
||||
problems,
|
||||
github,
|
||||
menu,
|
||||
close,
|
||||
meta,
|
||||
shopify,
|
||||
starbucks,
|
||||
tesla,
|
||||
carrent,
|
||||
jobit,
|
||||
tripguide,
|
||||
contacts_pic,
|
||||
faq_pic,
|
||||
discord_icon,
|
||||
instagram_icon,
|
||||
facebook_icon,
|
||||
};
|
||||
BIN
src/assets/instagram.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
src/assets/jobit.png
Normal file
|
After Width: | Height: | Size: 737 KiB |
1
src/assets/logo.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
3
src/assets/menu.svg
Normal file
@ -0,0 +1,3 @@
|
||||
<svg width="20" height="12" viewBox="0 0 20 12" fill="#FFF" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9 2L19 2C19.2652 2 19.5196 1.89464 19.7071 1.70711C19.8946 1.51957 20 1.26522 20 1C20 0.734784 19.8946 0.480429 19.7071 0.292892C19.5196 0.105356 19.2652 0 19 0L9 0C8.73478 0 8.48043 0.105356 8.29289 0.292892C8.10536 0.480429 8 0.734784 8 1C8 1.26522 8.10536 1.51957 8.29289 1.70711C8.48043 1.89464 8.73478 2 9 2ZM19 10L1 10C0.734784 10 0.480429 10.1054 0.292892 10.2929C0.105356 10.4804 0 10.7348 0 11C0 11.2652 0.105356 11.5196 0.292892 11.7071C0.480429 11.8946 0.734784 12 1 12L19 12C19.2652 12 19.5196 11.8946 19.7071 11.7071C19.8946 11.5196 20 11.2652 20 11C20 10.7348 19.8946 10.4804 19.7071 10.2929C19.5196 10.1054 19.2652 10 19 10V10ZM1 7L19 7C19.2652 7 19.5196 6.89464 19.7071 6.70711C19.8946 6.51957 20 6.26522 20 6C20 5.73478 19.8946 5.48043 19.7071 5.29289C19.5196 5.10536 19.2652 5 19 5L1 5C0.734784 5 0.480429 5.10536 0.292892 5.29289C0.105356 5.48043 0 5.73478 0 6C0 6.26522 0.105356 6.51957 0.292892 6.70711C0.480429 6.89464 0.734784 7 1 7Z" fill="#FFFFFF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/problems.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
src/assets/tripguide.png
Normal file
|
After Width: | Height: | Size: 3.3 MiB |
@ -4,9 +4,9 @@ import emailjs from '@emailjs/browser';
|
||||
|
||||
function Contact(){
|
||||
const form = useRef();
|
||||
const serviceKey = process.env.SERVICE_KEY;
|
||||
const template = process.env.TEMPLATE;
|
||||
const token = process.env.TOKEN;
|
||||
const serviceKey = import.meta.env.SERVICE_KEY;
|
||||
const template = import.meta.env.TEMPLATE;
|
||||
const token = import.meta.env.TOKEN;
|
||||
|
||||
function sendEmail(e) {
|
||||
e.preventDefault();
|
||||
10
src/components/Contacts.jsx
Normal file
@ -0,0 +1,10 @@
|
||||
import React from "react";
|
||||
import { SectionWrapper } from "../hoc";
|
||||
|
||||
const Contacts = () => {
|
||||
return (
|
||||
<div></div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SectionWrapper(Contacts, "");
|
||||
170
src/components/Faq.jsx
Normal file
@ -0,0 +1,170 @@
|
||||
import React, { useState } from 'react';
|
||||
import { styles } from "../styles";
|
||||
import { motion } from "framer-motion";
|
||||
import { textVariant } from "../utils/motion";
|
||||
import { SectionWrapper } from "../hoc";
|
||||
import { faqs } from '../constants';
|
||||
|
||||
const Faq = () => {
|
||||
const [activeIndex, setActiveIndex] = useState(null);
|
||||
const [activeSection, setActiveSection] = useState(null);
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
|
||||
const toggleFAQ = (sectionIndex, faqIndex) => {
|
||||
setActiveIndex((prevIndex) => {
|
||||
if (
|
||||
prevIndex !== null &&
|
||||
prevIndex[0] === sectionIndex &&
|
||||
prevIndex[1] === faqIndex
|
||||
) {
|
||||
return null; // Collapse the clicked FAQ
|
||||
}
|
||||
return [sectionIndex, faqIndex]; // Expand the clicked FAQ
|
||||
});
|
||||
};
|
||||
|
||||
const toggleSection = (section) => {
|
||||
setActiveSection((prevSection) => {
|
||||
if (prevSection === section) {
|
||||
return null; // Close the clicked section
|
||||
}
|
||||
return section; // Open the clicked section
|
||||
});
|
||||
};
|
||||
|
||||
const filteredFaqs = faqs.filter(
|
||||
(faq) =>
|
||||
faq.section.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
faq.question.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
faq.answer.toLowerCase().includes(searchTerm.toLowerCase())
|
||||
);
|
||||
|
||||
const groupedFaqs = filteredFaqs.reduce((acc, curr) => {
|
||||
const foundIndex = acc.findIndex((item) => item.section === curr.section);
|
||||
if (foundIndex === -1) {
|
||||
acc.push({
|
||||
section: curr.section,
|
||||
faqs: [curr],
|
||||
});
|
||||
} else {
|
||||
acc[foundIndex].faqs.push(curr);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
const handleSearch = (e) => {
|
||||
setSearchTerm(e.target.value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<motion.div variants={textVariant()}>
|
||||
<p className={`${styles.sectionSubText} `}>ถามหน่อย</p>
|
||||
<h2 className={`${styles.sectionHeadText}`}>Frequently Asked Questions</h2>
|
||||
</motion.div>
|
||||
<hr className="h-px my-8 bg-gray-200 border-0 dark:bg-gray-700"></hr>
|
||||
<form>
|
||||
<label htmlFor="default-search" className="mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white">
|
||||
Search
|
||||
</label>
|
||||
<div className="relative">
|
||||
<div className="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
className="w-5 h-5 text-gray-500 dark:text-gray-400"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth="2"
|
||||
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<input
|
||||
type="search"
|
||||
id="default-search"
|
||||
className="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
|
||||
placeholder="Search..."
|
||||
value={searchTerm}
|
||||
onChange={handleSearch}
|
||||
/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<hr className="h-px my-8 bg-gray-200 border-0 dark:bg-gray-700"></hr>
|
||||
<div className="grid gap-6 grid-cols-1 sm:grid-cols-2">
|
||||
{groupedFaqs.map(({ section, faqs }, sectionIndex) => (
|
||||
<div key={sectionIndex} className="mb-8">
|
||||
<div
|
||||
className={`flex items-center justify-between cursor-pointer ${
|
||||
activeSection === section ? 'text-blue-700' : 'text-white-900'
|
||||
}`}
|
||||
onClick={() => toggleSection(section)}
|
||||
>
|
||||
<h2 className="text-2xl font-semibold mb-4">{section}</h2>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={`w-6 h-6 ${
|
||||
activeSection === section ? 'text-blue-700' : 'text-gray-500'
|
||||
}`}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d={
|
||||
activeSection === section
|
||||
? 'M19 9l-7 7-7-7'
|
||||
: 'M9 5l7 7-7 7'
|
||||
}
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
{activeSection === section && (
|
||||
<div>
|
||||
{faqs.map((faq, faqIndex) => (
|
||||
<a
|
||||
key={faqIndex}
|
||||
href="#"
|
||||
className={`block p-6 bg-white border border-gray-200 rounded-lg shadow hover:bg-gray-100 dark:bg-gray-800 dark:border-gray-700 dark:hover:bg-gray-700 ${
|
||||
activeIndex &&
|
||||
activeIndex[0] === sectionIndex &&
|
||||
activeIndex[1] === faqIndex
|
||||
? 'mb-4'
|
||||
: 'mb-2'
|
||||
}`}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
toggleFAQ(sectionIndex, faqIndex);
|
||||
}}
|
||||
>
|
||||
<h5 className="mb-2 text-xl font-semibold tracking-tight text-gray-900 dark:text-white">
|
||||
{faq.question}
|
||||
</h5>
|
||||
{activeIndex &&
|
||||
activeIndex[0] === sectionIndex &&
|
||||
activeIndex[1] === faqIndex && (
|
||||
<p className="font-normal text-gray-700 dark:text-gray-400">
|
||||
{faq.answer}
|
||||
</p>
|
||||
)}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SectionWrapper(Faq, "");
|
||||
11
src/components/Guide.jsx
Normal file
@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
import { SectionWrapper } from "../hoc";
|
||||
|
||||
|
||||
const Guide = () => {
|
||||
return (
|
||||
<div></div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SectionWrapper(Guide, "work");
|
||||
54
src/components/Hero.jsx
Normal file
@ -0,0 +1,54 @@
|
||||
import { motion } from "framer-motion";
|
||||
import { Canvas } from "@react-three/fiber";
|
||||
import { styles } from "../styles";
|
||||
import { ComputersCanvas } from "./canvas";
|
||||
import Model from "./canvas/Bananacat";
|
||||
import { DirectionalLight } from "three";
|
||||
import * as THREE from 'three'
|
||||
|
||||
const Hero = () => {
|
||||
return (
|
||||
<section className={`relative w-full h-screen mx-auto`}>
|
||||
<div
|
||||
className={`absolute inset-0 top-[120px] max-w-7xl mx-auto ${styles.paddingX} flex flex-row items-start gap-5`}
|
||||
>
|
||||
<div className='flex flex-col justify-center items-center mt-5'>
|
||||
<div className='w-5 h-5 rounded-full bg-[#915EFF]' />
|
||||
<div className='w-1 sm:h-80 h-40 violet-gradient' />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1 className={`${styles.heroHeadText} text-white`}>
|
||||
Hi, I'm <span className='text-[#915EFF]'>Adrian</span>
|
||||
</h1>
|
||||
<p className={`${styles.heroSubText} mt-2 text-white-100`}>
|
||||
I develop 3D visuals, user <br className='sm:block hidden' />
|
||||
interfaces and web applications
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <ComputersCanvas /> */}
|
||||
|
||||
<div className='absolute xs:bottom-10 bottom-32 w-full flex justify-center items-center'>
|
||||
<a href='#about'>
|
||||
<div className='w-[35px] h-[64px] rounded-3xl border-4 border-secondary flex justify-center items-start p-2'>
|
||||
<motion.div
|
||||
animate={{
|
||||
y: [0, 24, 0],
|
||||
}}
|
||||
transition={{
|
||||
duration: 1.5,
|
||||
repeat: Infinity,
|
||||
repeatType: "loop",
|
||||
}}
|
||||
className='w-3 h-3 rounded-full bg-secondary mb-1'
|
||||
/>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Hero;
|
||||
31
src/components/Loader.jsx
Normal file
@ -0,0 +1,31 @@
|
||||
import { Html, useProgress } from "@react-three/drei";
|
||||
|
||||
const CanvasLoader = () => {
|
||||
const { progress } = useProgress();
|
||||
return (
|
||||
<Html
|
||||
as='div'
|
||||
center
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
flexDirection: "column",
|
||||
}}
|
||||
>
|
||||
<span className='canvas-loader'></span>
|
||||
<p
|
||||
style={{
|
||||
fontSize: 14,
|
||||
color: "#F1F1F1",
|
||||
fontWeight: 800,
|
||||
marginTop: 40,
|
||||
}}
|
||||
>
|
||||
{progress.toFixed(2)}%
|
||||
</p>
|
||||
</Html>
|
||||
);
|
||||
};
|
||||
|
||||
export default CanvasLoader;
|
||||
78
src/components/Menu.jsx
Normal file
@ -0,0 +1,78 @@
|
||||
import React from "react";
|
||||
import Tilt from "react-tilt";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
import { styles } from "../styles";
|
||||
import { menu } from "../constants";
|
||||
import { SectionWrapper } from "../hoc";
|
||||
import { fadeIn, textVariant } from "../utils/motion";
|
||||
import { StarsCanvas } from "./canvas";
|
||||
|
||||
const ServiceCard = ({ index, title, icon, url }) => (
|
||||
<Tilt className='xs:w-[250px] w-full'>
|
||||
<motion.div
|
||||
variants={fadeIn("right", "spring", index * 0.5, 0.75)}
|
||||
className='w-full green-pink-gradient p-[1px] rounded-[20px] shadow-card'
|
||||
>
|
||||
<a href={url} className='block'>
|
||||
<div
|
||||
options={{
|
||||
max: 45,
|
||||
scale: 1,
|
||||
speed: 450,
|
||||
}}
|
||||
className='bg-tertiary rounded-[20px] py-5 px-12 min-h-[280px] flex justify-evenly items-center flex-col'
|
||||
>
|
||||
<img
|
||||
src={icon}
|
||||
alt='web-development'
|
||||
className='w-16 h-16 object-contain'
|
||||
/>
|
||||
|
||||
<h3 className='text-white text-[20px] font-bold text-center'>
|
||||
{title}
|
||||
</h3>
|
||||
</div>
|
||||
</a>
|
||||
</motion.div>
|
||||
</Tilt>
|
||||
);
|
||||
|
||||
const Menu = () => {
|
||||
return (
|
||||
<>
|
||||
<motion.div variants={textVariant()}>
|
||||
<p className={styles.sectionSubTextCenter}>สวัสดีฮ๊าฟ ฟู่วววว~~</p>
|
||||
<h2 className={styles.sectionCenterText}>SOS CAMP 12th</h2>
|
||||
</motion.div>
|
||||
|
||||
<motion.p
|
||||
variants={fadeIn("", "", 0.1, 1)}
|
||||
className='mt-4 text-secondary text-[17px] max-w-3xl leading-[30px] mx-auto text-center'
|
||||
>
|
||||
Hello, Welcome, Have Room, Have Condo
|
||||
Have K-Y, Good Take Care, Do Everything
|
||||
Eat Chicken, Eat Duck
|
||||
Drink Cola, Drink fanta
|
||||
Drink aLong the Way, Good Job, Programmer Job
|
||||
Steve Job, Job Job, Python Job, Dangerous Job
|
||||
Look into my eyes, Thank you xoxo
|
||||
</motion.p>
|
||||
|
||||
<div className='mt-20 flex flex-wrap gap-10'>
|
||||
{menu.map((service, index) => (
|
||||
<ServiceCard
|
||||
key={service.title}
|
||||
index={index}
|
||||
title={service.title}
|
||||
icon={service.icon}
|
||||
url={`/${service.title.replace(/\s+/g, '-').toLowerCase()}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<StarsCanvas />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SectionWrapper(Menu, "about");
|
||||
102
src/components/Navbar.jsx
Normal file
@ -0,0 +1,102 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
import { styles } from "../styles";
|
||||
import { navLinks } from "../constants";
|
||||
import { logo, menu, close } from "../assets";
|
||||
|
||||
const Navbar = () => {
|
||||
const [active, setActive] = useState("");
|
||||
const [toggle, setToggle] = useState(false);
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
const scrollTop = window.scrollY;
|
||||
if (scrollTop > 100) {
|
||||
setScrolled(true);
|
||||
} else {
|
||||
setScrolled(false);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<nav
|
||||
className={`${
|
||||
styles.paddingX
|
||||
} w-full flex items-center py-5 fixed top-0 z-20 ${
|
||||
scrolled ? "bg-primary" : "bg-transparent"
|
||||
}`}
|
||||
>
|
||||
<div className='w-full flex justify-between items-center max-w-7xl mx-auto'>
|
||||
<Link
|
||||
to='/'
|
||||
className='flex items-center gap-2'
|
||||
onClick={() => {
|
||||
setActive("");
|
||||
window.scrollTo(0, 0);
|
||||
}}
|
||||
>
|
||||
<img src={logo} alt='logo' className='w-9 h-9 object-contain' />
|
||||
<p className='text-white text-[18px] font-bold cursor-pointer flex '>
|
||||
SOS CAMP
|
||||
<span className='sm:block hidden'> | 12th</span>
|
||||
</p>
|
||||
</Link>
|
||||
|
||||
<ul className='list-none hidden sm:flex flex-row gap-10'>
|
||||
{navLinks.map((nav) => (
|
||||
<li
|
||||
key={nav.id}
|
||||
className={`${
|
||||
active === nav.title ? "text-white" : "text-secondary"
|
||||
} hover:text-white text-[18px] font-medium cursor-pointer`}
|
||||
onClick={() => setActive(nav.title)}
|
||||
>
|
||||
<a href={`${nav.id}`}>{nav.title}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className='sm:hidden flex flex-1 justify-end items-center'>
|
||||
<img
|
||||
src={toggle ? close : menu}
|
||||
alt='menu'
|
||||
className='w-[28px] h-[28px] object-contain'
|
||||
onClick={() => setToggle(!toggle)}
|
||||
/>
|
||||
|
||||
<div
|
||||
className={`${
|
||||
!toggle ? "hidden" : "flex"
|
||||
} p-6 black-gradient absolute top-20 right-0 mx-4 my-2 min-w-[140px] z-10 rounded-xl`}
|
||||
>
|
||||
<ul className='list-none flex justify-end items-start flex-1 flex-col gap-4'>
|
||||
{navLinks.map((nav) => (
|
||||
<li
|
||||
key={nav.id}
|
||||
className={`font-poppins font-medium cursor-pointer text-[16px] ${
|
||||
active === nav.title ? "text-white" : "text-secondary"
|
||||
}`}
|
||||
onClick={() => {
|
||||
setToggle(!toggle);
|
||||
setActive(nav.title);
|
||||
}}
|
||||
>
|
||||
<a href={`#${nav.id}`}>{nav.title}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
};
|
||||
|
||||
export default Navbar;
|
||||
26
src/components/Preproblems.jsx
Normal file
@ -0,0 +1,26 @@
|
||||
import React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
import { styles } from "../styles";
|
||||
import { SectionWrapper } from "../hoc";
|
||||
import { fadeIn, textVariant } from "../utils/motion";
|
||||
|
||||
const Preproblems = () => {
|
||||
return (
|
||||
<>
|
||||
<motion.div variants={textVariant()}>
|
||||
<p className={styles.sectionSubTextCenter}>เทสๆ</p>
|
||||
<h2 className={styles.sectionCenterText}>Problems</h2>
|
||||
</motion.div>
|
||||
|
||||
<motion.p
|
||||
variants={fadeIn("", "", 0.1, 1)}
|
||||
className='mt-4 text-secondary text-[17px] max-w-3xl leading-[30px] mx-auto text-center'
|
||||
>
|
||||
Welcome to the 12th SOS camp, a preparation camp for SKE21 students. We hope that students will definitely gain knowledge and enjoyment.
|
||||
</motion.p>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SectionWrapper(Preproblems, "about");
|
||||
180
src/components/Problems.jsx
Normal file
@ -0,0 +1,180 @@
|
||||
import * as React from 'react';
|
||||
import AppBar from '@mui/material/AppBar';
|
||||
import Button from '@mui/material/Button';
|
||||
import Card from '@mui/material/Card';
|
||||
import CardActions from '@mui/material/CardActions';
|
||||
import CardContent from '@mui/material/CardContent';
|
||||
import CardMedia from '@mui/material/CardMedia';
|
||||
import CssBaseline from '@mui/material/CssBaseline';
|
||||
import Grid from '@mui/material/Grid';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import Box from '@mui/material/Box';
|
||||
import Toolbar from '@mui/material/Toolbar';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import Container from '@mui/material/Container';
|
||||
import Link from '@mui/material/Link';
|
||||
import Checkbox from '@mui/material/Checkbox';
|
||||
import Switch from '@mui/material/Switch';
|
||||
import {styled} from '@mui/material/styles';
|
||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import {createTheme, ThemeProvider} from '@mui/material/styles';
|
||||
import cards from '../constants/Card';
|
||||
import {createContext, useState} from "react";
|
||||
import { StarsCanvas } from "./canvas";
|
||||
import myimage from '../images/syntax.jpeg'
|
||||
import { SectionWrapper } from "../hoc";
|
||||
import Preproblems from "./Preproblems";
|
||||
|
||||
export const ThemeContext = createContext(null);
|
||||
|
||||
// switch theme button ---------------------------------------------------------------
|
||||
const MaterialUISwitch = styled(Switch)(({theme}) => ({
|
||||
width: 62,
|
||||
height: 34,
|
||||
padding: 7,
|
||||
'& .MuiSwitch-switchBase': {
|
||||
margin: 1,
|
||||
padding: 0,
|
||||
transform: 'translateX(6px)',
|
||||
'&.Mui-checked': {
|
||||
color: '#fff',
|
||||
transform: 'translateX(22px)',
|
||||
'& .MuiSwitch-thumb:before': {
|
||||
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
|
||||
'#fff',
|
||||
)}" d="M4.2 2.5l-.7 1.8-1.8.7 1.8.7.7 1.8.6-1.8L6.7 5l-1.9-.7-.6-1.8zm15 8.3a6.7 6.7 0 11-6.6-6.6 5.8 5.8 0 006.6 6.6z"/></svg>')`,
|
||||
},
|
||||
'& + .MuiSwitch-track': {
|
||||
opacity: 1,
|
||||
backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : 'white',
|
||||
},
|
||||
},
|
||||
},
|
||||
'& .MuiSwitch-thumb': {
|
||||
backgroundColor: theme.palette.mode === 'dark' ? '#003892' : '#7892B5',
|
||||
width: 32,
|
||||
height: 32,
|
||||
'&:before': {
|
||||
content: "''",
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
left: 0,
|
||||
top: 0,
|
||||
backgroundRepeat: 'no-repeat',
|
||||
backgroundPosition: 'center',
|
||||
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
|
||||
'#fff',
|
||||
)}" d="M9.305 1.667V3.75h1.389V1.667h-1.39zm-4.707 1.95l-.982.982L5.09 6.072l.982-.982-1.473-1.473zm10.802 0L13.927 5.09l.982.982 1.473-1.473-.982-.982zM10 5.139a4.872 4.872 0 00-4.862 4.86A4.872 4.872 0 0010 14.862 4.872 4.872 0 0014.86 10 4.872 4.872 0 0010 5.139zm0 1.389A3.462 3.462 0 0113.471 10a3.462 3.462 0 01-3.473 3.472A3.462 3.462 0 016.527 10 3.462 3.462 0 0110 6.528zM1.665 9.305v1.39h2.083v-1.39H1.666zm14.583 0v1.39h2.084v-1.39h-2.084zM5.09 13.928L3.616 15.4l.982.982 1.473-1.473-.982-.982zm9.82 0l-.982.982 1.473 1.473.982-.982-1.473-1.473zM9.305 16.25v2.083h1.389V16.25h-1.39z"/></svg>')`,
|
||||
},
|
||||
},
|
||||
'& .MuiSwitch-track': {
|
||||
opacity: 1,
|
||||
backgroundColor: theme.palette.mode === 'dark' ? '#8796A5' : '#aab4be',
|
||||
borderRadius: 20 / 2,
|
||||
},
|
||||
}));
|
||||
// switch theme button ----------------------------------------------------------------
|
||||
|
||||
function Copyright() {
|
||||
return (
|
||||
<Typography variant="body2" color="#5585A4" align="center">
|
||||
{'Copyright © '}
|
||||
<Link color="inherit" href="https://mui.com/">
|
||||
Your Website
|
||||
</Link>{' '}
|
||||
{new Date().getFullYear()}
|
||||
{'.'}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
const defaultTheme = createTheme();
|
||||
|
||||
const Problems = () => {
|
||||
|
||||
const [theme, setTheme] = useState('dark');
|
||||
|
||||
const toggleTheme = () => {
|
||||
setTheme(theme === 'light' ? 'dark' : 'light');
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="Problems">
|
||||
{/* <Preproblems /> */}
|
||||
<ThemeContext.Provider value={{theme, toggleTheme}}>
|
||||
|
||||
<ThemeProvider theme={defaultTheme}>
|
||||
<CssBaseline/>
|
||||
<main>
|
||||
{/* Hero unit */}
|
||||
<Container
|
||||
sx={{py: 8}} maxWidth="fit-content">
|
||||
{/* End hero unit */}
|
||||
<div className="flex mt-4 border border-gray-500 p-4">
|
||||
<Grid container spacing={4}>
|
||||
{/*# TODO:Edit the Jode here */}
|
||||
{cards.map((card) => (
|
||||
<Grid item xs={12} sm={6} md={4} key={card.id}>
|
||||
{/*<img src={require("./images/syntax.jpeg")} alt="jode"/>*/}
|
||||
<Card
|
||||
sx={{
|
||||
height: '100%',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
}}
|
||||
>
|
||||
<CardMedia
|
||||
component="div"
|
||||
sx={{
|
||||
// 16:9
|
||||
pt: '56.25%',
|
||||
height: 0,
|
||||
// objectFit: 'cover',
|
||||
}}
|
||||
image={myimage}
|
||||
/>
|
||||
|
||||
<CardContent sx={{flexGrow: 1}}>
|
||||
<Typography gutterBottom variant="h5" component="h2"
|
||||
color="#7DD6F6">
|
||||
{card.title}
|
||||
</Typography>
|
||||
<Typography color="aliceblue">
|
||||
{card.describe}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
<CardActions>
|
||||
<Button size="small"><a
|
||||
href={card.link}>View</a></Button>
|
||||
<Checkbox className="jodeCheckBox"/>
|
||||
</CardActions>
|
||||
</Card>
|
||||
</Grid>
|
||||
))}
|
||||
|
||||
</Grid>
|
||||
</div>
|
||||
<StarsCanvas />
|
||||
{/* <Contact /> */}
|
||||
</Container>
|
||||
</main>
|
||||
{/* Footer */}
|
||||
{/* <Box sx={{p: 6}} component="footer">
|
||||
<Typography variant="h6" align="center" gutterBottom>
|
||||
Footer
|
||||
</Typography>
|
||||
<Typography variant="subtitle1" align="center" component="p">
|
||||
Something here to give the footer a purpose!
|
||||
</Typography>
|
||||
<Copyright/>
|
||||
</Box> */}
|
||||
{/* End footer */}
|
||||
</ThemeProvider> */
|
||||
|
||||
</ThemeContext.Provider>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SectionWrapper(Problems, "");
|
||||
44
src/components/canvas/Stars.jsx
Normal file
@ -0,0 +1,44 @@
|
||||
import { useState, useRef, Suspense } from "react";
|
||||
import { Canvas, useFrame } from "@react-three/fiber";
|
||||
import { Points, PointMaterial, Preload } from "@react-three/drei";
|
||||
import * as random from "maath/random/dist/maath-random.esm";
|
||||
|
||||
const Stars = (props) => {
|
||||
const ref = useRef();
|
||||
const [sphere] = useState(() => random.inSphere(new Float32Array(5000), { radius: 1.2 }));
|
||||
|
||||
useFrame((state, delta) => {
|
||||
ref.current.rotation.x -= delta / 10;
|
||||
ref.current.rotation.y -= delta / 15;
|
||||
});
|
||||
|
||||
return (
|
||||
<group rotation={[0, 0, Math.PI / 4]}>
|
||||
<Points ref={ref} positions={sphere} stride={3} frustumCulled {...props}>
|
||||
<PointMaterial
|
||||
transparent
|
||||
color='#f272c8'
|
||||
size={0.002}
|
||||
sizeAttenuation={true}
|
||||
depthWrite={false}
|
||||
/>
|
||||
</Points>
|
||||
</group>
|
||||
);
|
||||
};
|
||||
|
||||
const StarsCanvas = () => {
|
||||
return (
|
||||
<div className='w-full h-auto absolute inset-0 z-[-1]'>
|
||||
<Canvas camera={{ position: [0, 0, 1] }}>
|
||||
<Suspense fallback={null}>
|
||||
<Stars />
|
||||
</Suspense>
|
||||
|
||||
<Preload all />
|
||||
</Canvas>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default StarsCanvas;
|
||||
3
src/components/canvas/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
import StarsCanvas from "./Stars";
|
||||
|
||||
export { StarsCanvas };
|
||||
4
src/components/index.css
Normal file
@ -0,0 +1,4 @@
|
||||
body {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
21
src/components/index.js
Normal file
@ -0,0 +1,21 @@
|
||||
import { StarsCanvas } from './canvas';
|
||||
import Navbar from "./Navbar";
|
||||
import Menu from "./Menu";
|
||||
import Guide from "./Guide";
|
||||
import Contacts from "./Contacts";
|
||||
import CanvasLoader from "./Loader";
|
||||
import Faq from './Faq';
|
||||
import Problems from './Problems';
|
||||
import Preproblems from './Preproblems';
|
||||
|
||||
export {
|
||||
Navbar,
|
||||
Menu,
|
||||
Guide,
|
||||
Contacts,
|
||||
CanvasLoader,
|
||||
StarsCanvas,
|
||||
Faq,
|
||||
Problems,
|
||||
Preproblems,
|
||||
};
|
||||
@ -3,129 +3,150 @@ const cards = [
|
||||
'title': 'Syntax',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'https://elabsheet.org/elab/taskpads/show/jr070sqaqp/',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':1
|
||||
},
|
||||
{
|
||||
'title': 'Variables',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'https://elabsheet.org/elab/taskpads/change/jr070sqaqp/yqxiczozva/',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':2
|
||||
},
|
||||
{
|
||||
'title': 'Data Type 01',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':3
|
||||
},
|
||||
{
|
||||
'title': 'Data Type 02',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':4
|
||||
},
|
||||
{
|
||||
'title': 'Data Type 03',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':5
|
||||
},
|
||||
{
|
||||
'title': 'Numbers, Casting, String',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':6
|
||||
},
|
||||
{
|
||||
'title': 'Strings',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'https://elabsheet.org/elab/taskpads/change/4k422fwoou/v49ajp3qgh/',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':7
|
||||
},
|
||||
{
|
||||
'title': 'Boolean 01',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':8
|
||||
},
|
||||
{
|
||||
'title': 'Boolean 02',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':9
|
||||
},
|
||||
{
|
||||
'title': 'Operators 01',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':10
|
||||
},
|
||||
{
|
||||
'title': 'Operators 02',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':11
|
||||
},
|
||||
{
|
||||
'title': 'Lists',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':12
|
||||
},
|
||||
{
|
||||
'title': 'Tuples',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':13
|
||||
},
|
||||
{
|
||||
'title': 'Sets',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':14
|
||||
},
|
||||
{
|
||||
'title': 'Dictionaries',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':15
|
||||
},
|
||||
{
|
||||
'title': 'If Else 01',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':16
|
||||
},
|
||||
{
|
||||
'title': 'If Else 02',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':17
|
||||
},
|
||||
{
|
||||
'title': 'If Else 03',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':18
|
||||
},
|
||||
{
|
||||
'title': 'While Loops',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':19
|
||||
|
||||
},
|
||||
{
|
||||
'title': 'For Loops',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':20
|
||||
|
||||
},
|
||||
{
|
||||
'title': 'Functions',
|
||||
'describe': 'Mai tum leaw',
|
||||
'link': 'www.',
|
||||
'img': './images/syntax.jpeg'
|
||||
'img': './images/syntax.jpeg',
|
||||
'id':21
|
||||
|
||||
}
|
||||
]
|
||||
67
src/constants/index.js
Normal file
@ -0,0 +1,67 @@
|
||||
import {
|
||||
guide,
|
||||
contacts_pic,
|
||||
faq_pic,
|
||||
problems,
|
||||
} from "../assets";
|
||||
|
||||
export const navLinks = [
|
||||
{
|
||||
id: "problems",
|
||||
title: "Problems",
|
||||
},
|
||||
{
|
||||
id: "guide",
|
||||
title: "Guide",
|
||||
},
|
||||
{
|
||||
id: "faq",
|
||||
title: "FAQ",
|
||||
},
|
||||
{
|
||||
id: "contact",
|
||||
title: "Contacts",
|
||||
},
|
||||
];
|
||||
|
||||
const menu = [
|
||||
{
|
||||
title: "Problems",
|
||||
icon: problems,
|
||||
},
|
||||
{
|
||||
title: "Guide",
|
||||
icon: guide,
|
||||
},
|
||||
{
|
||||
title: "FAQ",
|
||||
icon: faq_pic,
|
||||
},
|
||||
{
|
||||
title: "Contacts",
|
||||
icon: contacts_pic,
|
||||
},
|
||||
];
|
||||
|
||||
const faqs = [
|
||||
{
|
||||
section: 'Python',
|
||||
question: 'How do I install Python?',
|
||||
answer: 'To install Python, you can follow the step-by-step tutorial in this guide: [Python Installation Tutorial](https://www.example.com/python-installation-tutorial). It will walk you through the process of installing Python on your system.',
|
||||
link: 'https://www.example.com/python-installation-tutorial'
|
||||
},
|
||||
{
|
||||
section: 'General',
|
||||
question: 'How do I brush my teeth?',
|
||||
answer: 'To brush your teeth, follow these steps:\n1. Wet your toothbrush with water.\n2. Apply toothpaste to the bristles.\n3. Hold the toothbrush at a 45-degree angle to your gums.\n4. Brush gently in circular motions for 2 minutes.\n5. Spit out the toothpaste and rinse your mouth with water.',
|
||||
link: null
|
||||
},
|
||||
{
|
||||
section: 'Miscellaneous',
|
||||
question: 'What is the capital of France?',
|
||||
answer: 'The capital of France is Paris.'
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
export { menu, faqs };
|
||||
25
src/hoc/SectionWrapper.jsx
Normal file
@ -0,0 +1,25 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
import { styles } from "../styles";
|
||||
import { staggerContainer } from "../utils/motion";
|
||||
|
||||
const StarWrapper = (Component, idName) =>
|
||||
function HOC() {
|
||||
return (
|
||||
<motion.section
|
||||
variants={staggerContainer()}
|
||||
initial='hidden'
|
||||
whileInView='show'
|
||||
viewport={{ once: true, amount: 0.25 }}
|
||||
className={`${styles.padding} max-w-7xl mx-auto relative z-0`}
|
||||
>
|
||||
<span className='hash-span' id={idName}>
|
||||
|
||||
</span>
|
||||
|
||||
<Component />
|
||||
</motion.section>
|
||||
);
|
||||
};
|
||||
|
||||
export default StarWrapper;
|
||||
3
src/hoc/index.js
Normal file
@ -0,0 +1,3 @@
|
||||
import SectionWrapper from "./SectionWrapper";
|
||||
|
||||
export { SectionWrapper };
|
||||
202
src/index.css
@ -1,8 +1,204 @@
|
||||
body {
|
||||
background: black;
|
||||
color: white;
|
||||
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@100;200;300;400;500;600;700;800;900&display=swap");
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
font-family: "Poppins", sans-serif;
|
||||
scroll-behavior: smooth;
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
.hash-span {
|
||||
margin-top: -100px;
|
||||
padding-bottom: 100px;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.black-gradient {
|
||||
background: #000000; /* fallback for old browsers */
|
||||
background: -webkit-linear-gradient(
|
||||
to right,
|
||||
#434343,
|
||||
#000000
|
||||
); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background: linear-gradient(
|
||||
to right,
|
||||
#434343,
|
||||
#000000
|
||||
); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
}
|
||||
|
||||
.violet-gradient {
|
||||
background: #804dee;
|
||||
background: linear-gradient(-90deg, #804dee 0%, rgba(60, 51, 80, 0) 100%);
|
||||
background: -webkit-linear-gradient(
|
||||
-90deg,
|
||||
#804dee 0%,
|
||||
rgba(60, 51, 80, 0) 100%
|
||||
);
|
||||
}
|
||||
|
||||
.green-pink-gradient {
|
||||
background: "#00cea8";
|
||||
background: linear-gradient(90.13deg, #00cea8 1.9%, #bf61ff 97.5%);
|
||||
background: -webkit-linear-gradient(-90.13deg, #00cea8 1.9%, #bf61ff 97.5%);
|
||||
}
|
||||
|
||||
.orange-text-gradient {
|
||||
background: #f12711; /* fallback for old browsers */
|
||||
background: -webkit-linear-gradient(
|
||||
to top,
|
||||
#f12711,
|
||||
#f5af19
|
||||
); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
#f12711,
|
||||
#f5af19
|
||||
); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.green-text-gradient {
|
||||
background: #11998e; /* fallback for old browsers */
|
||||
background: -webkit-linear-gradient(
|
||||
to top,
|
||||
#11998e,
|
||||
#38ef7d
|
||||
); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
#11998e,
|
||||
#38ef7d
|
||||
); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.blue-text-gradient {
|
||||
/* background: -webkit-linear-gradient(#eee, #333); */
|
||||
background: #56ccf2; /* fallback for old browsers */
|
||||
background: -webkit-linear-gradient(
|
||||
to top,
|
||||
#2f80ed,
|
||||
#56ccf2
|
||||
); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
#2f80ed,
|
||||
#56ccf2
|
||||
); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.pink-text-gradient {
|
||||
background: #ec008c; /* fallback for old browsers */
|
||||
background: -webkit-linear-gradient(
|
||||
to top,
|
||||
#ec008c,
|
||||
#fc6767
|
||||
); /* Chrome 10-25, Safari 5.1-6 */
|
||||
background: linear-gradient(
|
||||
to top,
|
||||
#ec008c,
|
||||
#fc6767
|
||||
); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
|
||||
/* canvas- styles */
|
||||
.canvas-loader {
|
||||
font-size: 10px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
text-indent: -9999em;
|
||||
animation: mulShdSpin 1.1s infinite ease;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
@keyframes mulShdSpin {
|
||||
0%,
|
||||
100% {
|
||||
box-shadow: 0em -2.6em 0em 0em #ffffff,
|
||||
1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2),
|
||||
2.5em 0em 0 0em rgba(255, 255, 255, 0.2),
|
||||
1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2),
|
||||
0em 2.5em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-2.6em 0em 0 0em rgba(255, 255, 255, 0.5),
|
||||
-1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
12.5% {
|
||||
box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.7),
|
||||
1.8em -1.8em 0 0em #ffffff, 2.5em 0em 0 0em rgba(255, 255, 255, 0.2),
|
||||
1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2),
|
||||
0em 2.5em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-2.6em 0em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
25% {
|
||||
box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.5),
|
||||
1.8em -1.8em 0 0em rgba(255, 255, 255, 0.7), 2.5em 0em 0 0em #ffffff,
|
||||
1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2),
|
||||
0em 2.5em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-2.6em 0em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
37.5% {
|
||||
box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2),
|
||||
1.8em -1.8em 0 0em rgba(255, 255, 255, 0.5),
|
||||
2.5em 0em 0 0em rgba(255, 255, 255, 0.7), 1.75em 1.75em 0 0em #ffffff,
|
||||
0em 2.5em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-2.6em 0em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
50% {
|
||||
box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2),
|
||||
1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2),
|
||||
2.5em 0em 0 0em rgba(255, 255, 255, 0.5),
|
||||
1.75em 1.75em 0 0em rgba(255, 255, 255, 0.7), 0em 2.5em 0 0em #ffffff,
|
||||
-1.8em 1.8em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-2.6em 0em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
62.5% {
|
||||
box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2),
|
||||
1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2),
|
||||
2.5em 0em 0 0em rgba(255, 255, 255, 0.2),
|
||||
1.75em 1.75em 0 0em rgba(255, 255, 255, 0.5),
|
||||
0em 2.5em 0 0em rgba(255, 255, 255, 0.7), -1.8em 1.8em 0 0em #ffffff,
|
||||
-2.6em 0em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
75% {
|
||||
box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2),
|
||||
1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2),
|
||||
2.5em 0em 0 0em rgba(255, 255, 255, 0.2),
|
||||
1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2),
|
||||
0em 2.5em 0 0em rgba(255, 255, 255, 0.5),
|
||||
-1.8em 1.8em 0 0em rgba(255, 255, 255, 0.7), -2.6em 0em 0 0em #ffffff,
|
||||
-1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
87.5% {
|
||||
box-shadow: 0em -2.6em 0em 0em rgba(255, 255, 255, 0.2),
|
||||
1.8em -1.8em 0 0em rgba(255, 255, 255, 0.2),
|
||||
2.5em 0em 0 0em rgba(255, 255, 255, 0.2),
|
||||
1.75em 1.75em 0 0em rgba(255, 255, 255, 0.2),
|
||||
0em 2.5em 0 0em rgba(255, 255, 255, 0.2),
|
||||
-1.8em 1.8em 0 0em rgba(255, 255, 255, 0.5),
|
||||
-2.6em 0em 0 0em rgba(255, 255, 255, 0.7), -1.8em -1.8em 0 0em #ffffff;
|
||||
}
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import "./index.css"
|
||||
import "./App.css"
|
||||
|
||||
ReactDOM.render(<App/>,
|
||||
document.querySelector("#root"))
|
||||
11
src/main.jsx
Normal file
@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
|
||||
import App from "./App";
|
||||
import "./index.css";
|
||||
|
||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
21
src/styles.js
Normal file
@ -0,0 +1,21 @@
|
||||
const styles = {
|
||||
paddingX: "sm:px-16 px-6",
|
||||
paddingY: "sm:py-16 py-6",
|
||||
padding: "sm:px-16 px-6 sm:py-16 py-10",
|
||||
|
||||
heroHeadText:
|
||||
"font-black text-white lg:text-[80px] sm:text-[60px] xs:text-[50px] text-[40px] lg:leading-[98px] mt-2",
|
||||
heroSubText:
|
||||
"text-[#dfd9ff] font-medium lg:text-[30px] sm:text-[26px] xs:text-[20px] text-[16px] lg:leading-[40px]",
|
||||
|
||||
sectionHeadText:
|
||||
"text-white font-black md:text-[60px] sm:text-[50px] xs:text-[40px] text-[30px]",
|
||||
sectionSubText:
|
||||
"sm:text-[18px] text-[14px] text-secondary uppercase tracking-wider",
|
||||
sectionSubTextCenter:
|
||||
"sm:text-[18px] text-[14px] text-secondary uppercase tracking-wider text-center",
|
||||
sectionCenterText:
|
||||
"text-white font-black md:text-[60px] sm:text-[50px] xs:text-[40px] text-[30px] text-center"
|
||||
};
|
||||
|
||||
export { styles };
|
||||
88
src/utils/motion.js
Normal file
@ -0,0 +1,88 @@
|
||||
export const textVariant = (delay) => {
|
||||
return {
|
||||
hidden: {
|
||||
y: -50,
|
||||
opacity: 0,
|
||||
},
|
||||
show: {
|
||||
y: 0,
|
||||
opacity: 1,
|
||||
transition: {
|
||||
type: "spring",
|
||||
duration: 1.25,
|
||||
delay: delay,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const fadeIn = (direction, type, delay, duration) => {
|
||||
return {
|
||||
hidden: {
|
||||
x: direction === "left" ? 100 : direction === "right" ? -100 : 0,
|
||||
y: direction === "up" ? 100 : direction === "down" ? -100 : 0,
|
||||
opacity: 0,
|
||||
},
|
||||
show: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
opacity: 1,
|
||||
transition: {
|
||||
type: type,
|
||||
delay: delay,
|
||||
duration: duration,
|
||||
ease: "easeOut",
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const zoomIn = (delay, duration) => {
|
||||
return {
|
||||
hidden: {
|
||||
scale: 0,
|
||||
opacity: 0,
|
||||
},
|
||||
show: {
|
||||
scale: 1,
|
||||
opacity: 1,
|
||||
transition: {
|
||||
type: "tween",
|
||||
delay: delay,
|
||||
duration: duration,
|
||||
ease: "easeOut",
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const slideIn = (direction, type, delay, duration) => {
|
||||
return {
|
||||
hidden: {
|
||||
x: direction === "left" ? "-100%" : direction === "right" ? "100%" : 0,
|
||||
y: direction === "up" ? "100%" : direction === "down" ? "100%" : 0,
|
||||
},
|
||||
show: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
transition: {
|
||||
type: type,
|
||||
delay: delay,
|
||||
duration: duration,
|
||||
ease: "easeOut",
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const staggerContainer = (staggerChildren, delayChildren) => {
|
||||
return {
|
||||
hidden: {},
|
||||
show: {
|
||||
transition: {
|
||||
staggerChildren: staggerChildren,
|
||||
delayChildren: delayChildren || 0,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
27
tailwind.config.cjs
Normal file
@ -0,0 +1,27 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./src/**/*.{js,jsx}"],
|
||||
mode: "jit",
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: "#050816",
|
||||
secondary: "#aaa6c3",
|
||||
tertiary: "#151030",
|
||||
"black-100": "#100d25",
|
||||
"black-200": "#090325",
|
||||
"white-100": "#f3f3f3",
|
||||
},
|
||||
boxShadow: {
|
||||
card: "0px 35px 120px -15px #211e35",
|
||||
},
|
||||
screens: {
|
||||
xs: "450px",
|
||||
},
|
||||
backgroundImage: {
|
||||
"hero-pattern": "url('/src/assets/herobg.png')",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
7
vite.config.js
Normal file
@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||