???
- ??
- ????
- ?? ??
- API
- ?????
- ??? ?
- ?? ????
- ????
- ???
?? ??: https://github.com/aelassas/movinin
??: https://movinin.dynv6.net:3004
??
? ????? ?? ??? ??? ? ?? ??? ??? ???? ?? ??? ??? ?? ???? ?? ?? ????? ???? ??????.
- UI/UX ??: ??? ??? ??? ?? ??? ?? ??? ??????
- ??? ??: ?? ??? ???? ?? ??? ???? ?? ? ??? ?? ??
- ??? DevOps: ???? ??? ????? ???? ?????? ??, ?? ? ????
- ???? ??: ??? ???? ?? ?? ?? ??? ??? ??? ?????
?? ??
?? ???? ? ?? ??? ??? ????.
- ??????
- Node.js
- ??DB
- ??
- ??
- ???
- ?????
- ??
TypeScript? ??? ?? ??? ?? ??? ??? TypeScript? ????? ???????. TypeScript? ??? ???, ?? ? ??? ???? ??? ? ???? ?? ???, ???, ?? ?? ?? ??? ?? ??? ?????.
?? ??? ??? ??? ?? React? ????, ??? ??? ???? ?? MongoDB?, ??? ?? ??? ?? Stripe? ??????.
? ??? ???? ??? ????? ??? ?? ???? ?? ??? ??? ?? ?? ??? ???? ??? ????? ???? ??? ?? ??? ? ?? ??? ???? ????.
?? ??
? ????? ?????, ??? ???? ? ??? ?? ?? ???? ? ? ????.
?????
??????? ??? ?? ??? ???? ????, ???? ??? ? ??? ? ????.
??? ??? ?? ? ??? ???? ?? ??? ??? ??? ? ?? ????? ?? ??????.
??? ??? ??? ??? ??? ? ?? ?? ??? ?? ?????.
??? ??? ???? ????? ? ? ?? ??????.
??? ?? ??????.
??? ??? ?? ??? ???? ??? ? ?? ?? ??????. ??? ???? ?? ?? ??? ??? ??? ? ? ????. ?? ???? ?? ?? ???? ??? ?? ?? ? ??? ???? ?? ???.
??? ??? ??????. ?????? ?? ??? httpOnly, ??, ?? ? ??? sameSite???. ??? ??? XSS, CSRF ? MITM ??? ?????. ?? ??? ??? ????? ?? XST ??????? ?????.
??? ???? ??????.
??? ??? ?? ??? ???? ??? ? ?? ??????.
??? ??? ?? ??? ??? ? ? ?? ??????.
??? ??? ?? ??? ??? ? ?? ??????.
??? ??? ??? ??? ? ?? ??????.
??? ??? ????? ??? ? ?? ??????.
?????. ?????? ?? ??????.
?? ????
? ?? ??? ???:
- ???: ??? ????? ?? ?? ??? ??? ????. ??? ???? ? ? ????.
- ???: ?? ????? ?? ???? ???? ????. ??, ??, ??? ??? ? ????.
- ??: ?????? ??? ??? ???? ? ????. ??? ????? ???? ? ????.
? ???? ?? ???? ????? ???????. ? ???? ?? ?????? ?? ??, ?? ? ??? ??? ? ????. ???? ??? ?????? ??? ?? ????.
????? ???? ???, ??, ??, ?? ? ??? ???? ??? ? ????.
? ???? ???? ??, ?? ? ??? ??? ? ??? ?? ????? ????? ?? ??? ????? ???? ?? ???.
??? ??? ???? ??? ??????.
??? ???? ???? ??? ???? ??? ? ?? ???? ??????.
?? ??? ???? ?? ???? ??? ???? ?????.
??? ??? ???? ??? ? ?? ??????.
??? ???? ???? ???? ?? ??? ???? ??? ??? ??? ? ?? ??????. ?? ??? ???? 0?? ?????. ??? ?? ?? ?? ??? ??????, ??? ??? ???? ?????.
??? ???? ???? ??? ??? ? ?? ??????.
??? ???? ??? ??? ? ?? ??????.
??? ???? ??? ?????? ??? ????? ?? ??? ???? ??????. ??? ?? ?? ????? ?? ??? ??? ?? ????? ???? ??? ???? ?????.
??? ?? ?? ??????.
??? ???? ?? ??????.
??? ?? ????? ???? ??????.
??? ??? ?? ??????.
??? ???? ??? ? ? ?? ??????.
??? ??? ????? ? ? ?? ??????.
??? ???? ???? ??? ??? ? ?? ??????.
?? ???? ??? ??? ????? ?? ??????.
?????. ??? ????? ?? ??????.
API
API? ?? ????, ????? ? ??? ?? ??? ?? ??? ?????. API? MVC ??? ??? ????. ???? JWT? ?????. ??, ??, ?? ??? ??? ?? ? ??? ??? ??? ???? ?? ???? ??? ? ?? ?? ? ?? ?? ? ??? ???? ?? ??? ????.
- ./api/src/models/ ???? MongoDB ??? ???? ????.
- ./api/src/routes/ ???? Express ??? ???? ????.
- ./api/src/controllers/ ???? ????? ???? ????.
- ./api/src/middlewares/ ???? ????? ???? ????.
- ./api/src/config/env.config.ts?? ?? ? TypeScript ?? ??? ???? ????.
- ./api/src/lang/ ???? ???? ???? ????.
- ./api/src/app.ts? ??? ???? ?? ?????.
- ./api/index.ts? API? ?? ??????.
index.ts? API? ?? ??????.
import 'dotenv/config' import process from 'node:process' import fs from 'node:fs/promises' import http from 'node:http' import https, { ServerOptions } from 'node:https' import app from './app' import * as databaseHelper from './common/databaseHelper' import * as env from './config/env.config' import * as logger from './common/logger' if ( await databaseHelper.connect(env.DB_URI, env.DB_SSL, env.DB_DEBUG) && await databaseHelper.initialize() ) { let server: http.Server | https.Server if (env.HTTPS) { https.globalAgent.maxSockets = Number.POSITIVE_INFINITY const privateKey = await fs.readFile(env.PRIVATE_KEY, 'utf8') const certificate = await fs.readFile(env.CERTIFICATE, 'utf8') const credentials: ServerOptions = { key: privateKey, cert: certificate } server = https.createServer(credentials, app) server.listen(env.PORT, () => { logger.info('HTTPS server is running on Port', env.PORT) }) } else { server = app.listen(env.PORT, () => { logger.info('HTTP server is running on Port', env.PORT) }) } const close = () => { logger.info('Gracefully stopping...') server.close(async () => { logger.info(`HTTP${env.HTTPS ? 'S' : ''} server closed`) await databaseHelper.close(true) logger.info('MongoDB connection closed') process.exit(0) }) } ['SIGINT', 'SIGTERM', 'SIGQUIT'].forEach((signal) => process.on(signal, close)) }
Node.js? Express? ???? ??? ???? TypeScript ?????. dotenv, process, fs, http, https, mongoose ? app? ??? ?? ??? ?????. ?? ?? HTTPS ?? ??? true? ???? ??? ????, ???? https ??? ??? ?? ? ? ???? ???? HTTPS ??? ?????. ??? ??? http ??? ???? HTTP ??? ?????. ??? PORT ?? ??? ??? ???? ?? ?????.
?? ??? ???? ??? ????? ????? ?? ??? ???? ????. ??? MongoDB ??? ?? ? ?? ?? 0?? ????? ?????. ????? ????? SIGINT, SIGTERM ?? SIGQUIT ??? ??? ? ??? ?? ??? ?????.
app.ts? API? ?? ??????.
import express from 'express' import compression from 'compression' import helmet from 'helmet' import nocache from 'nocache' import cookieParser from 'cookie-parser' import i18n from './lang/i18n' import * as env from './config/env.config' import cors from './middlewares/cors' import allowedMethods from './middlewares/allowedMethods' import agencyRoutes from './routes/agencyRoutes' import bookingRoutes from './routes/bookingRoutes' import locationRoutes from './routes/locationRoutes' import notificationRoutes from './routes/notificationRoutes' import propertyRoutes from './routes/propertyRoutes' import userRoutes from './routes/userRoutes' import stripeRoutes from './routes/stripeRoutes' import countryRoutes from './routes/countryRoutes' import * as helper from './common/helper' const app = express() app.use(helmet.contentSecurityPolicy()) app.use(helmet.dnsPrefetchControl()) app.use(helmet.crossOriginEmbedderPolicy()) app.use(helmet.frameguard()) app.use(helmet.hidePoweredBy()) app.use(helmet.hsts()) app.use(helmet.ieNoOpen()) app.use(helmet.noSniff()) app.use(helmet.permittedCrossDomainPolicies()) app.use(helmet.referrerPolicy()) app.use(helmet.xssFilter()) app.use(helmet.originAgentCluster()) app.use(helmet.crossOriginResourcePolicy({ policy: 'cross-origin' })) app.use(helmet.crossOriginOpenerPolicy()) app.use(nocache()) app.use(compression({ threshold: 0 })) app.use(express.urlencoded({ limit: '50mb', extended: true })) app.use(express.json({ limit: '50mb' })) app.use(cors()) app.options('*', cors()) app.use(cookieParser(env.COOKIE_SECRET)) app.use(allowedMethods) app.use('/', agencyRoutes) app.use('/', bookingRoutes) app.use('/', locationRoutes) app.use('/', notificationRoutes) app.use('/', propertyRoutes) app.use('/', userRoutes) app.use('/', stripeRoutes) app.use('/', countryRoutes) i18n.locale = env.DEFAULT_LANGUAGE helper.mkdir(env.CDN_USERS) helper.mkdir(env.CDN_TEMP_USERS) helper.mkdir(env.CDN_PROPERTIES) helper.mkdir(env.CDN_TEMP_PROPERTIES) helper.mkdir(env.CDN_LOCATIONS) helper.mkdir(env.CDN_TEMP_LOCATIONS) export default app
?? MongoDB ?? ???? ??? ?? MongoDB ??????? ??? ?????. ?? ?? Express ?? ??? cors, ??, ?? ? nocache? ?? ????? ?????. ?? ???? ?????? ???? ??? ?? ??? ??????. ?? ??? ??, ?? ??, ?? ??, ?? ??, ?? ??, ??? ?? ? ??????? ??? ??? ?? ??? ?? ??? ?????. ????? Express ??? ???? ?? ?????.
API?? 8?? ??? ????. ? ???? MVC ??? ??? SOLID ??? ??? ?? ????? ????. ?? ??? ??? ????.
- userRoutes: ???? ??? REST ??? ??
- agencyRoutes: ???? ?? REST ?? ??
- countryRoutes: ?? ?? REST ?? ??
- locationRoutes: ??? ??? REST ?? ??
- propertyRoutes: ??? ??? REST ??? ?????
- bookingRoutes: ?? ?? REST ?? ??
- notificationRoutes: ?? ?? REST ?? ??
- stripeRoutes: Stripe ?? ????? ?? REST ??? ?????
? ??? ??? ????? ?????. ?? ?? propertyRoutes? ???? ??? ??? ?????? ???????. ????? ???? ?? ??? ? ? ????.
propertyRoutes.ts? ??? ????.
import express from 'express' import multer from 'multer' import routeNames from '../config/propertyRoutes.config' import authJwt from '../middlewares/authJwt' import * as propertyController from '../controllers/propertyController' const routes = express.Router() routes.route(routeNames.create).post(authJwt.verifyToken, propertyController.create) routes.route(routeNames.update).put(authJwt.verifyToken, propertyController.update) routes.route(routeNames.checkProperty).get(authJwt.verifyToken, propertyController.checkProperty) routes.route(routeNames.delete).delete(authJwt.verifyToken, propertyController.deleteProperty) routes.route(routeNames.uploadImage).post([authJwt.verifyToken, multer({ storage: multer.memoryStorage() }).single('image')], propertyController.uploadImage) routes.route(routeNames.deleteImage).post(authJwt.verifyToken, propertyController.deleteImage) routes.route(routeNames.deleteTempImage).post(authJwt.verifyToken, propertyController.deleteTempImage) routes.route(routeNames.getProperty).get(propertyController.getProperty) routes.route(routeNames.getProperties).post(authJwt.verifyToken, propertyController.getProperties) routes.route(routeNames.getBookingProperties).post(authJwt.verifyToken, propertyController.getBookingProperties) routes.route(routeNames.getFrontendProperties).post(propertyController.getFrontendProperties) export default routes
?? Express Router? ????. ?? ?? ??, ???, ???? ? ????? ???? ??? ?????.
routeNames?? propertyRoutes ?? ??? ???? ????.
const routes = { create: '/api/create-property', update: '/api/update-property', delete: '/api/delete-property/:id', uploadImage: '/api/upload-property-image', deleteTempImage: '/api/delete-temp-property-image/:fileName', deleteImage: '/api/delete-property-image/:property/:image', getProperty: '/api/property/:id/:language', getProperties: '/api/properties/:page/:size', getBookingProperties: '/api/booking-properties/:page/:size', getFrontendProperties: '/api/frontend-properties/:page/:size', checkProperty: '/api/check-property/:id', } export default routes
propertyController?? ??? ?? ?? ???? ??? ???? ????. ????? ?? ??? ? ?? ??? ?? ?? ??? ? ?? ??? ???? ?? ??? ?? ???????.
??? ?? ?????:
import { Schema, model } from 'mongoose' import * as movininTypes from ':movinin-types' import * as env from '../config/env.config' const propertySchema = new Schema<env.Property>( { name: { type: String, required: [true, "can't be blank"], }, type: { type: String, enum: [ movininTypes.PropertyType.House, movininTypes.PropertyType.Apartment, movininTypes.PropertyType.Townhouse, movininTypes.PropertyType.Plot, movininTypes.PropertyType.Farm, movininTypes.PropertyType.Commercial, movininTypes.PropertyType.Industrial, ], required: [true, "can't be blank"], }, agency: { type: Schema.Types.ObjectId, required: [true, "can't be blank"], ref: 'User', index: true, }, description: { type: String, required: [true, "can't be blank"], }, available: { type: Boolean, default: true, }, image: { type: String, }, images: { type: [String], }, bedrooms: { type: Number, required: [true, "can't be blank"], validate: { validator: Number.isInteger, message: '{VALUE} is not an integer value', }, }, bathrooms: { type: Number, required: [true, "can't be blank"], validate: { validator: Number.isInteger, message: '{VALUE} is not an integer value', }, }, kitchens: { type: Number, default: 1, validate: { validator: Number.isInteger, message: '{VALUE} is not an integer value', }, }, parkingSpaces: { type: Number, default: 0, validate: { validator: Number.isInteger, message: '{VALUE} is not an integer value', }, }, size: { type: Number, }, petsAllowed: { type: Boolean, required: [true, "can't be blank"], }, furnished: { type: Boolean, required: [true, "can't be blank"], }, minimumAge: { type: Number, required: [true, "can't be blank"], min: env.MINIMUM_AGE, max: 99, }, location: { type: Schema.Types.ObjectId, ref: 'Location', required: [true, "can't be blank"], }, address: { type: String, }, price: { type: Number, required: [true, "can't be blank"], }, hidden: { type: Boolean, default: false, }, cancellation: { type: Number, default: 0, }, aircon: { type: Boolean, default: false, }, rentalTerm: { type: String, enum: [ movininTypes.RentalTerm.Monthly, movininTypes.RentalTerm.Weekly, movininTypes.RentalTerm.Daily, movininTypes.RentalTerm.Yearly, ], required: [true, "can't be blank"], }, }, { timestamps: true, strict: true, collection: 'Property', }, ) const Property = model<env.Property>('Property', propertySchema) export default Property
??? ??? ?????:
export interface Property extends Document { name: string type: movininTypes.PropertyType agency: Types.ObjectId description: string image: string images?: string[] bedrooms: number bathrooms: number kitchens?: number parkingSpaces?: number, size?: number petsAllowed: boolean furnished: boolean minimumAge: number location: Types.ObjectId address?: string price: number hidden?: boolean cancellation?: number aircon?: boolean available?: boolean rentalTerm: movininTypes.RentalTerm }
??? ???? ?????:
- ??
- A??(???,???,??,??,???,??,????)
- ??? ??
- ??
- ?? ???
- ?? ???
- ?? ?
- ??? ?
- ?? ?
- ????
- A???
- ?? ?? ??
- ??
- ??(??)
- ??
- ?? ??(??, ??, ??, ??)
- ?? ??(0?? ???? ??? ????, ???? ???? ?????, ?? ??? ??)
- ???? ?? ?? ??? ???? ???
- ?? ??? ???? ??? ??? ???? ???
- ?? ?? ??? ???? ???
- ??? ?? ?? ??? ???? ???
- ?? ?? ??? ???? ???
??? ???? ?? ?????:
import 'dotenv/config' import process from 'node:process' import fs from 'node:fs/promises' import http from 'node:http' import https, { ServerOptions } from 'node:https' import app from './app' import * as databaseHelper from './common/databaseHelper' import * as env from './config/env.config' import * as logger from './common/logger' if ( await databaseHelper.connect(env.DB_URI, env.DB_SSL, env.DB_DEBUG) && await databaseHelper.initialize() ) { let server: http.Server | https.Server if (env.HTTPS) { https.globalAgent.maxSockets = Number.POSITIVE_INFINITY const privateKey = await fs.readFile(env.PRIVATE_KEY, 'utf8') const certificate = await fs.readFile(env.CERTIFICATE, 'utf8') const credentials: ServerOptions = { key: privateKey, cert: certificate } server = https.createServer(credentials, app) server.listen(env.PORT, () => { logger.info('HTTPS server is running on Port', env.PORT) }) } else { server = app.listen(env.PORT, () => { logger.info('HTTP server is running on Port', env.PORT) }) } const close = () => { logger.info('Gracefully stopping...') server.close(async () => { logger.info(`HTTP${env.HTTPS ? 'S' : ''} server closed`) await databaseHelper.close(true) logger.info('MongoDB connection closed') process.exit(0) }) } ['SIGINT', 'SIGTERM', 'SIGQUIT'].forEach((signal) => process.on(signal, close)) }
?????
?????? Node.js, React, MUI ? TypeScript? ??? ? ?????????. ??? ??????? ??? ??? ??? ?? ?? ??? ??? ???? ??? ??? ? ??? ??? ? ????.
- ./frontend/src/assets/ ???? CSS? ???? ???? ????.
- ./frontend/src/pages/ ???? React ???? ???? ????.
- ./frontend/src/comComponents/ ???? React ?? ??? ???? ????.
- ./frontend/src/services/?? API ????? ???? ???? ????.
- ./frontend/src/App.tsx? ??? ??? ?? React ????.
- ./frontend/src/index.tsx? ?????? ?? ??????.
TypeScript ?? ??? ./packages/movinin-types ???? ???? ????.
App.tsx? ?? ?? ????:
import express from 'express' import compression from 'compression' import helmet from 'helmet' import nocache from 'nocache' import cookieParser from 'cookie-parser' import i18n from './lang/i18n' import * as env from './config/env.config' import cors from './middlewares/cors' import allowedMethods from './middlewares/allowedMethods' import agencyRoutes from './routes/agencyRoutes' import bookingRoutes from './routes/bookingRoutes' import locationRoutes from './routes/locationRoutes' import notificationRoutes from './routes/notificationRoutes' import propertyRoutes from './routes/propertyRoutes' import userRoutes from './routes/userRoutes' import stripeRoutes from './routes/stripeRoutes' import countryRoutes from './routes/countryRoutes' import * as helper from './common/helper' const app = express() app.use(helmet.contentSecurityPolicy()) app.use(helmet.dnsPrefetchControl()) app.use(helmet.crossOriginEmbedderPolicy()) app.use(helmet.frameguard()) app.use(helmet.hidePoweredBy()) app.use(helmet.hsts()) app.use(helmet.ieNoOpen()) app.use(helmet.noSniff()) app.use(helmet.permittedCrossDomainPolicies()) app.use(helmet.referrerPolicy()) app.use(helmet.xssFilter()) app.use(helmet.originAgentCluster()) app.use(helmet.crossOriginResourcePolicy({ policy: 'cross-origin' })) app.use(helmet.crossOriginOpenerPolicy()) app.use(nocache()) app.use(compression({ threshold: 0 })) app.use(express.urlencoded({ limit: '50mb', extended: true })) app.use(express.json({ limit: '50mb' })) app.use(cors()) app.options('*', cors()) app.use(cookieParser(env.COOKIE_SECRET)) app.use(allowedMethods) app.use('/', agencyRoutes) app.use('/', bookingRoutes) app.use('/', locationRoutes) app.use('/', notificationRoutes) app.use('/', propertyRoutes) app.use('/', userRoutes) app.use('/', stripeRoutes) app.use('/', countryRoutes) i18n.locale = env.DEFAULT_LANGUAGE helper.mkdir(env.CDN_USERS) helper.mkdir(env.CDN_TEMP_USERS) helper.mkdir(env.CDN_PROPERTIES) helper.mkdir(env.CDN_TEMP_PROPERTIES) helper.mkdir(env.CDN_LOCATIONS) helper.mkdir(env.CDN_TEMP_LOCATIONS) export default app
? ??? ???? ?? React ?? ??? ???? ????.
?????? ? ???? ???? ??? ?? ??? ???? ? ???? ? ? ????.
??? ?
? ???? Android ? iOS? ?? ??? ?? ?????. ??? ?? React Native, Expo ? TypeScript? ???????. ?????? ????? ??? ???? ??? ??? ??? ??? ?? ?? ??? ??? ???? ??? ??? ? ??? ??? ? ????.
????? ??? ?????? ??? ?? ??? ????. ?? ??? Node.js, Expo Server SDK ? Firebase? ???????.
- ./mobile/assets/ ???? ???? ???? ????.
- ./mobile/screens/ ???? ?? React Native ??? ???? ????.
- ./mobile/comComponents/ ???? React Native ?? ??? ???? ????.
- ./mobile/services/?? API ????? ???? ???? ????.
- ./mobile/App.tsx? ?? React Native ????.
TypeScript ?? ??? ?? ??? ???? ????.
- ./mobile/types/index.d.ts
- ./mobile/types/env.d.ts
- ./mobile/miscellaneous/movininTypes.ts
./mobile/types/? ??? ?? ./mobile/tsconfig.json? ?????.
import 'dotenv/config' import process from 'node:process' import fs from 'node:fs/promises' import http from 'node:http' import https, { ServerOptions } from 'node:https' import app from './app' import * as databaseHelper from './common/databaseHelper' import * as env from './config/env.config' import * as logger from './common/logger' if ( await databaseHelper.connect(env.DB_URI, env.DB_SSL, env.DB_DEBUG) && await databaseHelper.initialize() ) { let server: http.Server | https.Server if (env.HTTPS) { https.globalAgent.maxSockets = Number.POSITIVE_INFINITY const privateKey = await fs.readFile(env.PRIVATE_KEY, 'utf8') const certificate = await fs.readFile(env.CERTIFICATE, 'utf8') const credentials: ServerOptions = { key: privateKey, cert: certificate } server = https.createServer(credentials, app) server.listen(env.PORT, () => { logger.info('HTTPS server is running on Port', env.PORT) }) } else { server = app.listen(env.PORT, () => { logger.info('HTTP server is running on Port', env.PORT) }) } const close = () => { logger.info('Gracefully stopping...') server.close(async () => { logger.info(`HTTP${env.HTTPS ? 'S' : ''} server closed`) await databaseHelper.close(true) logger.info('MongoDB connection closed') process.exit(0) }) } ['SIGINT', 'SIGTERM', 'SIGQUIT'].forEach((signal) => process.on(signal, close)) }
App.tsx? React Native ?? ?? ??????.
'react-native-gesture-handler' ???? import React, { useCallback, useEffect, useRef, useState } from 'react' 'react-native-root-siblings'?? { RootSiblingParent } ???? '@react-navigation/native'?? ???? { NavigationContainer, NavigationContainerRef } 'expo-status-bar'?? { StatusBar? ExpoStatusBar? } ???? 'react-native-safe-area-context'?? { SafeAreaProvider } ???? 'react-native-paper'?? { ??? } ???? *? 'expo-splash-screen'?? SplashScreen?? ???? *? 'expo-notifications'?? ???? ???? '@stripe/stripe-react-native'?? { StripeProvider } ???? './comComponents/DrawerNavigator'?? DrawerNavigator ???? *? './common/helper'?? ???? ???? *? './services/NotificationService'?? NotificationService? ???? *? './services/UserService'?? UserService? ???? './context/GlobalContext'?? { GlobalProvider } ???? * './config/env.config'?? env? ???? ??.setNotificationHandler({ handlerNotification: async () => ({ shouldShowAlert: ??, shouldPlaySound: ??, shouldSetBadge: ??, }), }) // // ? ???? ?? ?? ?? ???? ??? ?? ???? ?? ?????. // SplashScreen.preventAutoHideAsync() .then((result) => console.log(`SplashScreen.preventAutoHideAsync() ??: ${result}`)) .catch(console.warn) // ??? ????? ???? ???? ?? ????. const ? = () => { const [appIsReady, setAppIsReady] = useState(false) const responseListener = useRef<Notifications.Subscription>() const NavigationRef = useRef<NavigationContainerRef<StackParams>>(null) useEffect(() => { const ???? = ???() => { const LoggedIn = UserService.loggedIn()? ?????. if (???) { const currentUser = UserService.getCurrentUser()? ?????. if (??????._id) { helper.registerPushToken(currentUser._id)? ?????. } ? ?? { ???.??() } } } // // ?? ?? ?? ?? // ????() // // ? ???? ???? ??? ???? ??? ????? ??? ?????(?? ?????, ????? ?? ??? ? ??). // responseListener.current = ??.addNotificationResponseReceivedListener(async (??) => { ???? { if (navigationRef.current) { const { ??? } = response.notification.request.content if (data.booking) { if (data.user && data.notification) { ??Service.markAsRead(data.user, [data.notification])? ?????. } NavigationRef.current.navigate('??', { id: data.booking }) } ? ?? { NavigationRef.current.navigate('??', {}) } } } ?? (??) { helper.error(err, false) } }) ??() => { ??.??????(responseListener.current!) } }, []) setTimeout(() => { setAppIsReady(true) }, 500) const onReady = useCallback(async () => { if (appIsReady) { // // ???? ??? ?? ???? ?????! ??? ??? ???? // `setAppIsReady`, ??? ?? ???? ?? ? ??? ??? ? ????. // ?? ??? ???? ? ?? ??? ??????. ??? ??, // ?? ?? ?? ??? ?? ?? ?? ???? ??? ????. // ????? ??????. // SplashScreen.hideAsync()? ?????. } }, [appIsReady]) if (!appIsReady) { null? ?? } ?? ( <??? ???> <SafeAreaProvider> <???> <StripeProvider ?? ?? ?={env.STRIPE_PUBLISHABLE_KEY} MerchantIdentifier={env.STRIPE_MERCHANT_IDENTIFIER}> <RootSiblingParent> <NavigationContainer ref={navigationRef} onReady={onReady}> <??????> <p>??? ?? ??? ??? ???? ???, ????? ???? ???? ?? ? ????.</p> <h2> ?? ???? </h2> <p>?? ????? Node.js, React, MUI ? TypeScript? ??? ? ?????????. ????? ???? ????, ???, ??, ?? ? ??? ???? ??? ? ????. ????? ??? ????? ???? ?? ????? ????? ?? ? ??? ???? ?? ??? ????? ???? ?? ???.</p>
- ./backend/assets/ ???? CSS? ???? ???? ????.
- ./backend/pages/ ???? React ???? ???? ????.
- ./backend/comComponents/ ???? React ?? ??? ???? ????.
- ./backend/services/?? API ????? ???? ???? ????.
- ./backend/App.tsx? ??? ??? ?? React ????.
- ./backend/index.tsx? ?? ????? ?? ??????.
TypeScript ?? ??? ./packages/movinin-types ???? ???? ????.
?? ????? App.tsx? ?????? App.tsx? ??? ??? ????.
?? ????? ? ???? ???? ??? ?? ??? ???? ? ???? ? ? ????.
?? ??
React Native? Expo? ???? ??? ?? ???? ?? ?? ????. Expo? React Native? ??? ??? ??? ?? ???? ????.
???, ?????, ??? ??? ??? ??(TypeScript)? ???? ?? ?????.
TypeScript? ?? ???? ???? ?? ??? ??? ????. JavaScript? ?? ?? ??? ???? ?? ??? ???? ??? ? ???? ?? ???, ???, ?? ? ?? ??? ??? ??? ??? ? ????.
?????! ? ?? ???? ????? ????.
??
- ??
- ??
- ??(?? ???)
- (VPS) ??
-
?? ?(??)
- ?? ???
- SSL
- ????? ??
- ??? ? ??
-
?? ??????
- Windows, Linux ? macOS
- ??
- ???? ??
-
??? ? ??
- ????
- ??
- ?? ??
- ?? ??
- ? ?? ??
- ?? ??? ? ?? ??
- ??
? ??? ???? ????: ??? ?? ???? ???? ?? ??? ?? ?????. ??? ??? PHP ??? ????? ?? ?? ??? ?????!

? AI ??

Undress AI Tool
??? ???? ??

Undresser.AI Undress
???? ?? ??? ??? ?? AI ?? ?

AI Clothes Remover
???? ?? ???? ??? AI ?????.

Clothoff.io
AI ? ???

Video Face Swap
??? ??? AI ?? ?? ??? ???? ?? ???? ??? ?? ????!

?? ??

??? ??

???++7.3.1
???? ?? ?? ?? ???

SublimeText3 ??? ??
??? ??, ???? ?? ????.

???? 13.0.1 ???
??? PHP ?? ?? ??

???? CS6
??? ? ?? ??

SublimeText3 Mac ??
? ??? ?? ?? ?????(SublimeText3)

??? ??











Java ? JavaScript? ?? ?? ????? ??? ?? ?? ?? ???? ????? ?????. Java? ??? ? ??? ?????? ??? ???? JavaScript? ?? ? ??? ??? ?????.

JavaScriptCommentsareEnsentialformaining, ?? ? ???? 1) Single-LinecommentsERUSEDFORQUICKEXPLANATIONS.2) Multi-linecommentSexplaincleClexLogicOrprovidedEdeDDocumentation.3) inlineecommentsClarifySpecificPartSofcode.bestPractic

JavaScript?? ??? ??? ?? ? ? ?? ??? ???????. 1. ?? ??? ??? ???? ?? ??? ????. ISO ?? ???? ???? ???? ???? ?? ????. 2. ?? ??? ?? ???? ??? ?? ???? ??? ? ??? ? ?? 0?? ????? ?? ??????. 3. ?? ?? ???? ???? ???? ?? ?????? ??? ? ????. 4. Luxon? ?? ???? ???? ?????? ???? ?? ????. ??? ?? ???? ????? ???? ??? ????? ?? ? ????.

TAGGSATTHEBOTTOMOFABLOGPOSTORWEBPAGESERVESPRACTICALPURSEO, USEREXPERIENCE, andDESIGN.1.ITHELPSWITHEOBYOWNSESPORENGENSTOESTOCESKESKERKESKERKERKERDER-RELEVANTTAGSWITHOUTHINGTEMAINCONTENT.2.ITIMPROVESEREXPERKEEPINGTOPONTEFOCUSOFOFOFOCUSOFOFOFOCUCUSONTHEATECLL

JavaScriptIspreferredforwebDevelopment, whithjavaisbetterforlarge-scalebackendsystemsandandandoidapps.1) javascriptexcelsincreatinginteractivewebexperiences withitsdynatureanddommanipulation.2) javaoffersstrongtypingandobject-Orientededededededededededededededededdec

javascriptassevenfundamentalDatatatypes : ??, ???, ??, unull, ??, ? symbol.1) ?? seAdouble-precisionformat, ??? forwidevaluerangesbutbecautiouswithfatingfointarithmetic.2) stringsareimmutable, useefficientconcatenationmethendsf

??? ?? ? ??? DOM?? ??? ??? ? ?????. ??? ?? ????? ?? ??????, ??? ?? ???? ?? ????????. 1. ??? ??? addeventListener? usecapture ?? ??? true? ???? ?????. 2. ??? ??? ?? ???? usecapture? ???? ????? ?????. 3. ??? ??? ??? ??? ???? ? ??? ? ????. 4. ??? ?? ?? ?? ??? ?? ??? ??????? ??? ???? ?????. 5. ??? ?? ?? ?? ??? ?? ???? ?? ???? ? ??? ? ????. ? ? ??? ???? ???? JavaScript? ??? ??? ??? ????? ???? ???? ??? ??????.

Java? JavaScript? ?? ????? ?????. 1. Java? ???? ???? ??? ? ??? ?????? ?????? ? ?? ???? ?????. 2. JavaScript? ?? ? ?? ?? ? ??? ?? ??? ???? ??? ? ?? ? ?? ?????.
