This commit is contained in:
2026-01-13 15:10:13 +08:00
parent 38f0885a85
commit 45d5debead
134 changed files with 16980 additions and 1 deletions

9
argon-pro-react-native/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
node_modules/**/*
.expo/*
npm-debug.*
package-lock.json
yarn.lock
*.jks
*.p12
*.key
*.mobileprovision

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1,101 @@
import React, { useCallback, useEffect, useState } from "react";
import * as SplashScreen from "expo-splash-screen";
import * as Font from "expo-font";
import { Asset } from "expo-asset";
import { Block, GalioProvider } from "galio-framework";
import { NavigationContainer } from "@react-navigation/native";
import { Image } from "react-native";
import { Provider } from "react-redux";
import { NativeBaseProvider } from "native-base";
// Keep the splash screen visible while we fetch resources
SplashScreen.preventAutoHideAsync();
// Before rendering any navigation stack
import { enableScreens } from "react-native-screens";
enableScreens();
import Screens from "./navigation/Screens";
import { Images, articles, argonTheme } from "./constants";
import store from "./src/store";
import nativeBaseTheme from "./src/theme";
import { AuthProvider } from "./src/contexts/AuthContext";
// cache app images
const assetImages = [
Images.Onboarding,
Images.LogoOnboarding,
Images.Logo,
Images.Pro,
Images.ArgonLogo,
Images.iOSLogo,
Images.androidLogo,
];
// cache product images
articles.map((article) => assetImages.push(article.image));
function cacheImages(images) {
return images.map((image) => {
if (typeof image === "string") {
return Image.prefetch(image);
} else {
return Asset.fromModule(image).downloadAsync();
}
});
}
export default function App() {
const [appIsReady, setAppIsReady] = useState(false);
useEffect(() => {
async function prepare() {
try {
//Load Resources
await _loadResourcesAsync();
// Pre-load fonts, make any API calls you need to do here
await Font.loadAsync({
"open-sans-regular": require("./assets/font/OpenSans-Regular.ttf"),
"open-sans-light": require("./assets/font/OpenSans-Light.ttf"),
"open-sans-bold": require("./assets/font/OpenSans-Bold.ttf"),
});
} catch (e) {
console.warn(e);
} finally {
// Tell the application to render
setAppIsReady(true);
}
}
prepare();
}, []);
const _loadResourcesAsync = async () => {
return Promise.all([...cacheImages(assetImages)]);
};
const onLayoutRootView = useCallback(async () => {
if (appIsReady) {
await SplashScreen.hideAsync();
}
}, [appIsReady]);
if (!appIsReady) {
return null;
}
return (
<Provider store={store}>
<NativeBaseProvider theme={nativeBaseTheme}>
<AuthProvider>
<NavigationContainer onReady={onLayoutRootView}>
<GalioProvider theme={argonTheme}>
<Block flex>
<Screens />
</Block>
</GalioProvider>
</NavigationContainer>
</AuthProvider>
</NativeBaseProvider>
</Provider>
);
}

View File

@@ -0,0 +1,220 @@
# [Argon PRO React Native](https://creativetimofficial.github.io/argon-pro-react-native/docs/#) [![Tweet](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&logo=twitter)](https://twitter.com/intent/tweet?text=Start%20Your%20Development%20With%20A%20Badass%20React%20Native%20app%20inspired%20by%20Argon%20Design%20System.%0Ahttps%3A//demos.creative-tim.com/argon-pro-react-native/)
![version](https://img.shields.io/badge/version-1.6.0-blue.svg) [![GitHub issues open](https://img.shields.io/github/issues/creativetimofficial/ct-argon-pro-react-native.svg?style=flat)](https://github.com/creativetimofficial/ct-argon-pro-react-native/issues?q=is%3Aopen+is%3Aissue) [![GitHub issues closed](https://img.shields.io/github/issues-closed-raw/creativetimofficial/ct-argon-pro-react-native.svg?maxAge=2592000)](https://github.com/creativetimofficial/ct-argon-pro-react-native/issues?q=is%3Aissue+is%3Aclosed)
![Product Gif](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-pro-react-native/argp-rn-thumbnail.jpg)
Argon PRO React Native is a fully coded app template built over [Galio.io](https://galio.io/?ref=creativetim), [React Native](https://facebook.github.io/react-native/?ref=creativetim) and [Expo](https://expo.io/?ref=creativetim) to allow you to create powerful and beautiful e-commerce mobile applications. We have redesigned all the usual components in Galio to make it look like Argon's Design System, minimalistic and easy to use.
Start your development with a badass Design System for React Native inspired by Argon Design System. If you like Argon's Design System, you will love this react native app template! It features a huge number of components and screens built to fit together and look amazing.
### FULLY CODED COMPONENTS
Argon PRO React Native features over 200 variations of components like buttons, inputs, cards, navigations etc, giving you the freedom of choosing and combining. All components can take variations in colour, that you can easily modify inside our theme file.
You will save a lot of time going from prototyping to full-functional code, because all elements are implemented. We wanted the design process to be seamless, so switching from image to the real page is very easy to do.
### Components & Cards
Argon PRO React Native comes packed with a large number of components and cards. Putting together a mobile app has never been easier than matching together different components. From the profile screen to a settings screen, you can easily customise and build your screens. We have created multiple options for you to put together and customise into pixel perfect screens.
View [ all components/cards here](https://demos.creative-tim.com/argon-pro-react-native/index.html#cards).
### Example Screens
If you want to get inspiration or just show something directly to your clients, you can jump start your development with our pre-built example screens. From onboarding screens to profile or discover screens, you will be able to quickly set up the basic structure for your React Native mobile project.
View [all screens here](https://demos.creative-tim.com/argon-pro-react-native/index.html#screens).
Let us know your thoughts below. And good luck with development!
## Table of Contents
* [Versions](#versions)
* [Demo](#demo)
* [Quick Start](#quick-start)
* [Documentation](#documentation)
* [File Structure](#file-structure)
* [OS Support](#os-support)
* [Resources](#resources)
* [Reporting Issues](#reporting-issues)
* [Technical Support or Questions](#technical-support-or-questions)
* [Licensing](#licensing)
* [Useful Links](#useful-links)
## Versions
[<img src="https://github.com/creativetimofficial/public-assets/blob/master/logos/html-logo.jpg?raw=true" width="60" height="60" />](https://www.creative-tim.com/product/argon-design-system)[<img src="https://github.com/creativetimofficial/public-assets/blob/master/logos/vue-logo.jpg?raw=true" width="60" height="60" />](https://www.creative-tim.com/product/vue-argon-design-system)[<img src="https://github.com/creativetimofficial/public-assets/blob/master/logos/react-logo.jpg?raw=true" width="60" height="60" />](https://www.creative-tim.com/product/argon-design-system-react)[<img src="https://github.com/creativetimofficial/public-assets/blob/master/logos/react-native-logo.jpg?raw=true" width="60" height="60" />](https://www.creative-tim.com/product/argon-pro-react-native)[<img src="https://github.com/creativetimofficial/public-assets/blob/master/logos/angular-logo.jpg?raw=true" width="60" height="60" />](https://www.creative-tim.com/product/argon-dashboard-angular)
| HTML | React | Angular |
| --- | --- | --- |
| [![Argon Design System](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-design-system/argon-design-system.jpg)](https://www.creative-tim.com/product/argon-design-system) | [![Argon Design System React](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-design-system-react/argon-design-system-react.jpg)](https://www.creative-tim.com/product/argon-design-system-react) | [![Argon Design System Angular](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-design-system-angular/argon-design-system-angular.jpg)](https://www.creative-tim.com/product/argon-design-system-angular)
## Demo
| Home Screen | Profile Screen | Onboarding Screen | Register Screen |
| --- | --- | --- | --- |
| [![Home Screen](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-react-native/home-screen.png)](https://demos.creative-tim.com/argon-pro-react-native/) | [![Profile Screen](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-react-native/profile-screen.png)](https://demos.creative-tim.com/argon-pro-react-native/) | [![Onboarding Screen](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-pro-react-native/onboarding_screen.PNG)](https://demos.creative-tim.com/argon-pro-react-native/) | [![Register Screen](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-react-native/register-screen.png)](https://demos.creative-tim.com/argon-pro-react-native/) |
- [Start page](https://demos.creative-tim.com/argon-pro-react-native)
- [How to install our product](https://demos.creative-tim.com/argon-pro-react-native/docs/#/install)
[View more](https://demos.creative-tim.com/argon-pro-react-native)
## Quick start
- Buy from [Creative Tim](https://www.creative-tim.com/product/argon-pro-react-native)
## Documentation
The documentation for the Argon PRO React Native is hosted at our [website](https://demos.creative-tim.com/argon-pro-react-native/docs/).
## File Structure
Within the download you'll find the following directories and files:
```
argon-pro-react-native/
├── App.js
├── CHANGELOG.md
├── ISSUE_TEMPLATE.md
├── LICENSE.md
├── README.md
├── app.json
├── assets
│ ├── font
│ ├── imgs
│ └── nucleo\ icons
├── babel.config.js
├── components
│ ├── Button.js
│ ├── Card.js
│ ├── DrawerItem.js
│ ├── Header.js
│ ├── Icon.js
│ ├── Input.js
│ ├── Notification.js
│ ├── Select.js
│ ├── Switch.js
│ ├── Tabs.js
│ └── index.js
├── constants
│ ├── Images.js
│ ├── Theme.js
│ ├── articles.js
│ ├── cart.js
│ ├── categories.js
│ ├── deals.js
│ ├── index.js
│ ├── tabs.js
│ └── utils.js
├── navigation
│ ├── Menu.js
│ └── Screens.js
├── package.json
└── screens
├── About.js
├── Agreement.js
├── Articles.js
├── Beauty.js
├── Cart.js
├── Category.js
├── Chat.js
├── Elements.js
├── Fashion.js
├── Gallery.js
├── Home.js
├── Notifications.js
├── Onboarding.js
├── PersonalNotifications.js
├── Privacy.js
├── Pro.js
├── Product.js
├── Profile.js
├── Register.js
├── Search.js
├── Settings.js
└── SystemNotifications.js
```
## OS Support
At present, we officially aim to support the last two versions of the following operating systems:
[<img src="https://raw.githubusercontent.com/creativetimofficial/ct-material-kit-pro-react-native/master/assets/android-logo.png" width="60" height="60" />](https://www.creative-tim.com/product/material-kit-pro-react-native)[<img src="https://raw.githubusercontent.com/creativetimofficial/ct-material-kit-pro-react-native/master/assets/apple-logo.png" width="60" height="60" />](https://www.creative-tim.com/product/material-kit-pro-react-native)
## Resources
- Demo: <https://demos.creative-tim.com/argon-pro-react-native>
- Download Page: <https://www.creative-tim.com/product/argon-pro-react-native>
- Documentation: <https://demos.creative-tim.com/argon-pro-react-native/docs>
- License Agreement: <https://www.creative-tim.com/license>
- Support: <https://www.creative-tim.com/contact-us>
- Issues: [Github Issues Page](https://github.com/creativetimofficial/ct-argon-pro-react-native/issues)
- [Argon Design System](https://www.creative-tim.com/product/argon-design-system?ref=argonrn-readme) - For Front End Development
- **Dashboards:**
| HTML | React | Vue |
| --- | --- | --- |
| [![Argon HTML](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-dashboard-pro/argon-dashboard-pro.jpg)](https://www.creative-tim.com/product/argon-dashboard-pro) | [![Argon Dashboard React](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-dashboard-pro-react/argon-dashboard-pro-react.jpg)](https://www.creative-tim.com/product/argon-dashboard-pro-react) | [![Argon Dashboard Vue](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/vue-argon-dashboard-pro/vue-argon-dashboard-pro.jpg)](https://www.creative-tim.com/product/vue-argon-dashboard-pro)
| Node.js | Nuxt | Laravel |
| --- | --- | --- |
| [![Argon Dashboard PRO NodeJS](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-dashboard-pro-nodejs/argon-dashboard-pro-nodejs.jpg)](https://www.creative-tim.com/product/argon-dashboard-pro-nodejs) | [![Argon Dashboard PRO Nuxt](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/nuxt-argon-dashboard-pro/nuxt-argon-dashboard-pro.jpg)](https://www.creative-tim.com/product/nuxt-argon-dashboard-pro) | [![Argon Dashboard PRO Laravel](https://raw.githubusercontent.com/creativetimofficial/public-assets/master/argon-dashboard-pro-laravel/argon-dashboard-pro-laravel.jpg)](https://www.creative-tim.com/product/argon-dashboard-pro-laravel)
## Reporting Issues
We use GitHub Issues as the official bug tracker for the Argon PRO React Native. Here are some advices for our users that want to report an issue:
1. Make sure that you are using the latest version of the Argon PRO React Native.
2. Providing us reproducible steps for the issue will shorten the time it takes for it to be fixed.
3. Some issues may be platform specific, so specifying on what platform you encountered the issue might help.
### Technical Support or Questions
If you have questions or need help integrating the product please [contact us](https://www.creative-tim.com/contact-us) instead of opening an issue.
## Licensing
- Copyright 2019 Creative Tim (https://www.creative-tim.com/)
- Creative Tim [license](https://creative-tim.com/license)
## Useful Links
- [Tutorials](https://www.youtube.com/channel/UCVyTG4sCw-rOvB9oHkzZD1w)
- [Affiliate Program](https://www.creative-tim.com/affiliates/new) (earn money)
- [Blog Creative Tim](http://blog.creative-tim.com/)
- [Free Products](https://www.creative-tim.com/bootstrap-themes/free) from Creative Tim
- [Premium Products](https://www.creative-tim.com/bootstrap-themes/premium) from Creative Tim
- [React Products](https://www.creative-tim.com/bootstrap-themes/react-themes) from Creative Tim
- [Angular Products](https://www.creative-tim.com/bootstrap-themes/angular-themes) from Creative Tim
- [VueJS Products](https://www.creative-tim.com/bootstrap-themes/vuejs-themes) from Creative Tim
- [More products](https://www.creative-tim.com/bootstrap-themes) from Creative Tim
- Check our Bundles [here](https://www.creative-tim.com/bundles?ref="argon-github-readme")
### Social Media
Twitter: <https://twitter.com/CreativeTim>
Facebook: <https://www.facebook.com/CreativeTim>
Dribbble: <https://dribbble.com/creativetim>
Google+: <https://plus.google.com/+CreativetimPage>
Instagram: <https://www.instagram.com/CreativeTimOfficial>

View File

@@ -0,0 +1,37 @@
{
"expo": {
"name": "价值前沿",
"slug": "valuefrontier",
"privacy": "public",
"platforms": [
"ios",
"android"
],
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/logo.jpg",
"splash": {
"image": "./assets/logo.jpg",
"resizeMode": "contain",
"backgroundColor": "#000000"
},
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.valuefrontier.meagent"
},
"android": {
"package": "com.valuefrontier.meagent",
"adaptiveIcon": {
"foregroundImage": "./assets/logo.jpg",
"backgroundColor": "#000000"
}
},
"description": "价值前沿 - 智能投资助手"
}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="24" height="24"><g class="nc-icon-wrapper" fill="#444444"><path fill="#444444" d="M20,0H4C2.3,0,1,1.3,1,3v20c0,0.6,0.4,1,1,1h20c0.6,0,1-0.4,1-1V3C23,1.3,21.7,0,20,0z M12,16 c-3.3,0-6-2.7-6-6c0-0.6,0.4-1,1-1s1,0.4,1,1c0,2.2,1.8,4,4,4s4-1.8,4-4c0-0.6,0.4-1,1-1s1,0.4,1,1C18,13.3,15.3,16,12,16z M20,4H4 C3.4,4,3,3.6,3,3s0.4-1,1-1h16c0.6,0,1,0.4,1,1S20.6,4,20,4z"/></g></svg>

After

Width:  |  Height:  |  Size: 497 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 12 12" width="12" height="12"><g class="nc-icon-wrapper" fill="#444444"><path d="M1,10.5A1.5,1.5,0,0,0,2.5,12h7A1.5,1.5,0,0,0,11,10.5V7H1Z" fill="#444444"/> <path d="M9.838,4,8.171.665a.75.75,0,0,0-1.342.67L8.162,4H3.838L5.171,1.335A.75.75,0,0,0,3.829.665L2.162,4H0V6H12V4Z" fill="#444444" data-color="color-2"/></g></svg>

After

Width:  |  Height:  |  Size: 434 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="24" height="24"><g class="nc-icon-wrapper" fill="#444444"><path d="M20,10V8A8,8,0,0,0,4,8v2a4.441,4.441,0,0,1-1.547,3.193A4.183,4.183,0,0,0,1,16c0,2.5,4.112,4,11,4s11-1.5,11-4a4.183,4.183,0,0,0-1.453-2.807A4.441,4.441,0,0,1,20,10Z" fill="#444444"/> <path data-color="color-2" d="M9.145,21.9a2.992,2.992,0,0,0,5.71,0c-.894.066-1.844.1-2.855.1S10.039,21.968,9.145,21.9Z" fill="#444444"/></g></svg>

After

Width:  |  Height:  |  Size: 521 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="24" height="24"><g class="nc-icon-wrapper" fill="#444444"><rect data-color="color-2" x="4" y="10" width="4" height="3" fill="#444444"/> <rect data-color="color-2" x="10" y="10" width="4" height="3" fill="#444444"/> <rect data-color="color-2" x="4" y="15" width="4" height="3" fill="#444444"/> <rect data-color="color-2" x="10" y="15" width="4" height="3" fill="#444444"/> <rect data-color="color-2" x="16" y="10" width="4" height="3" fill="#444444"/> <path d="M23,3H18V1a1,1,0,0,0-2,0V3H8V1A1,1,0,0,0,6,1V3H1A1,1,0,0,0,0,4V22a1,1,0,0,0,1,1H23a1,1,0,0,0,1-1V4A1,1,0,0,0,23,3ZM22,21H2V7H22Z" fill="#444444"/></g></svg>

After

Width:  |  Height:  |  Size: 742 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="24" height="24"><g class="nc-icon-wrapper" fill="#444444"><path data-color="color-2" fill="#444444" d="M13,11h10.949C23.466,5.181,18.819,0.534,13,0.051V11z"/> <path fill="#444444" d="M12.414,13l-8.155,8.155C6.351,22.926,9.051,24,12,24c6.279,0,11.438-4.851,11.949-11H12.414z"/> <path fill="#444444" d="M11,11.586V0.051C4.851,0.562,0,5.721,0,12c0,2.949,1.074,5.649,2.845,7.741L11,11.586z"/></g></svg>

After

Width:  |  Height:  |  Size: 524 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="24" height="24"><g class="nc-icon-wrapper" fill="#444444"><path fill="#444444" d="M18.768,1.36C18.578,1.132,18.297,1,18,1H6C5.703,1,5.422,1.132,5.232,1.36l-5,6 c-0.294,0.353-0.31,0.861-0.039,1.231l11,15C11.382,23.848,11.682,24,12,24s0.618-0.152,0.807-0.409l11-15 c0.271-0.371,0.256-0.878-0.039-1.231L18.768,1.36z M19,9H5V7h14V9z"/></g></svg>

After

Width:  |  Height:  |  Size: 467 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 16 16" width="16" height="16"><g class="nc-icon-wrapper" fill="#444444"><path d="M8,15A7,7,0,0,1,3.333,2.783l1.334,1.49a5,5,0,1,0,6.666,0l1.333-1.49A7,7,0,0,1,8,15Z" fill="#444444"/> <rect x="7" width="2" height="7" fill="#444444" data-color="color-2"/></g></svg>

After

Width:  |  Height:  |  Size: 375 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 16 16" width="16" height="16"><g class="nc-icon-wrapper" fill="#444444"><path fill="#444444" d="M16,3.6L15.2,2C8.3,4,4.8,8.4,4.8,8.4L1.6,6L0,7.6L4.8,14C8.5,7.1,16,3.6,16,3.6z"/></g></svg>

After

Width:  |  Height:  |  Size: 299 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="24" height="24"><g class="nc-icon-wrapper" fill="#444444"><rect x="22" y="11" fill="#444444" width="2" height="6"/> <path data-color="color-2" fill="#444444" d="M13.241,15.73C12.847,15.91,12.43,16,12,16s-0.847-0.09-1.24-0.269L4,12.658V18 c0,2.626,4.024,4,8,4s8-1.374,8-4v-5.341L13.241,15.73z"/> <path fill="#444444" d="M23.414,7.09l-11-5c-0.263-0.119-0.564-0.119-0.827,0l-11,5C0.229,7.252,0,7.607,0,8s0.229,0.748,0.586,0.91 l11,5C11.718,13.97,11.859,14,12,14s0.282-0.03,0.414-0.09l11-5C23.771,8.748,24,8.393,24,8S23.771,7.252,23.414,7.09z"/></g></svg>

After

Width:  |  Height:  |  Size: 677 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
<g class="nc-icon-wrapper" fill="#444444">
<path d="M20 24c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm-8-8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 16c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm24-16c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm-8 16c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm8-8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm-8-8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm-8-8c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4z"></path>
</g>
</svg>

After

Width:  |  Height:  |  Size: 639 B

View File

@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g class="nc-icon-wrapper" fill="#444444">
<path d="M20 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 276 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="24" height="24"><g class="nc-icon-wrapper" fill="#444444"><polygon fill="#444444" points="17,1.382 13,3.382 13,22.618 17,20.618 "/> <polygon data-color="color-2" fill="#444444" points="11,3.382 7,1.382 7,20.618 11,22.618 "/> <path fill="#444444" d="M5,1.434L0.485,4.143C0.185,4.323,0,4.648,0,5v19l5-3.234V1.434z"/> <path data-color="color-2" fill="#444444" d="M23.515,4.143L19,1.434v19.332L24,24V5C24,4.648,23.815,4.323,23.515,4.143z"/></g></svg>

After

Width:  |  Height:  |  Size: 572 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 12 12" width="12" height="12"><g class="nc-icon-wrapper" fill="#444444"><path d="M11,9H1a1,1,0,0,0,0,2H11a1,1,0,0,0,0-2Z" fill="#444444"/> <path d="M11,1H1A1,1,0,0,0,1,3H11a1,1,0,0,0,0-2Z" fill="#444444"/> <path d="M11,5H1A1,1,0,0,0,1,7H11a1,1,0,0,0,0-2Z" fill="#444444" data-color="color-2"/></g></svg>

After

Width:  |  Height:  |  Size: 415 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 12 12" width="12" height="12"><g class="nc-icon-wrapper" fill="#444444"><polygon points="6 5.882 2.148 2.03 0.074 4.104 6 10.03 11.926 4.104 9.852 2.03 6 5.882" fill="#444444"/></g></svg>

After

Width:  |  Height:  |  Size: 299 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 12 12" width="12" height="12"><g class="nc-icon-wrapper" fill="#444444"><polygon points="7.92 0 1.92 6 7.92 12 10.02 9.9 6.12 6 10.02 2.1 7.92 0" fill="#444444"></polygon></g></svg>

After

Width:  |  Height:  |  Size: 293 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 12 12" width="12" height="12"><g class="nc-icon-wrapper" fill="#444444"><polygon points="1.98 2.1 5.88 6 1.98 9.9 4.08 12 10.08 6 4.08 0 1.98 2.1" fill="#444444"/></g></svg>

After

Width:  |  Height:  |  Size: 285 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 16 16" width="16" height="16"><g class="nc-icon-wrapper" fill="#444444"><path fill="#444444" d="M8,2c0.6,0,1.1,0.2,1.5,0.7l0.7,0.7l1.5-1.3L11,1.3C10.2,0.5,9.1,0,8,0C5.8,0,4,1.8,4,4v1.5 C2.8,6.6,2,8.2,2,10c0,3.3,2.7,6,6,6s6-2.7,6-6s-2.7-6-6-6C7.3,4,6.6,4.1,6,4.4V4C6,2.9,6.9,2,8,2z M8,7c1.1,0,2,0.9,2,2 c0,0.7-0.4,1.4-1,1.7V13H7v-2.3c-0.6-0.3-1-1-1-1.7C6,7.9,6.9,7,8,7z"/></g></svg>

After

Width:  |  Height:  |  Size: 493 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="24" height="24"><g class="nc-icon-wrapper" fill="#444444"><path fill="#444444" d="M20.4,6.1c-1.1-0.5-2.2-0.8-3.4-0.8c-1.6,0-3,0.5-4.3,0.9c-0.8,0.3-1.6,0.5-2.2,0.5c-0.4,0-0.6-0.1-0.7-0.3 c0-0.1,0.1-0.6,0.2-0.9c0.3-0.9,0.6-2-0.2-3.1c-0.5-0.6-1.3-1-2.2-1c-0.9,0-1.7,0.3-2.5,0.8C1.9,4.4,0,8.1,0,12c0,6.6,5.4,12,12,12 c5.3,0,10.1-3.6,11.6-8.8C23.7,14.6,25.1,8.4,20.4,6.1z M3,12c0-1.1,0.9-2,2-2s2,0.9,2,2s-0.9,2-2,2S3,13.1,3,12z M7.5,19 c-1.1,0-2-0.9-2-2s0.9-2,2-2s2,0.9,2,2S8.6,19,7.5,19z M13,21c-1.1,0-2-0.9-2-2s0.9-2,2-2s2,0.9,2,2S14.1,21,13,21z M17,15 c-1.7,0-3-1.3-3-3s1.3-3,3-3s3,1.3,3,3S18.7,15,17,15z"/></g></svg>

After

Width:  |  Height:  |  Size: 741 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 16 16" width="16" height="16"><g class="nc-icon-wrapper" fill="#444444"><path data-color="color-2" fill="#444444" d="M10,8H8v2H6V8H4V6h2V4h2v2h2V8z"/> <path fill="#444444" d="M7,14c-3.86,0-7-3.14-7-7s3.14-7,7-7s7,3.14,7,7S10.86,14,7,14z M7,2C4.243,2,2,4.243,2,7s2.243,5,5,5 s5-2.243,5-5S9.757,2,7,2z"/> <path data-color="color-2" fill="#444444" d="M15.707,14.293L13.314,11.9c-0.411,0.529-0.885,1.003-1.414,1.414l2.393,2.393 C14.488,15.902,14.744,16,15,16s0.512-0.098,0.707-0.293C16.098,15.316,16.098,14.684,15.707,14.293z"/> </g></svg>

After

Width:  |  Height:  |  Size: 647 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 16 16" width="16" height="16"><g class="nc-icon-wrapper" fill="#444444"><path fill="#444444" d="M13.9,0.5C13.7,0.2,13.4,0,13,0H3C2.6,0,2.3,0.2,2.1,0.5C0,4.5,0,4.7,0,5c0,1.1,0.9,2,2,2v8c0,0.6,0.4,1,1,1 h10c0.6,0,1-0.4,1-1V7c1.1,0,2-0.9,2-2C16,4.7,16,4.5,13.9,0.5z M10,14v-4H6v4H4V6.7C4.3,6.9,4.6,7,5,7c0.6,0,1.1-0.3,1.5-0.7 C6.9,6.7,7.4,7,8,7s1.1-0.3,1.5-0.7C9.9,6.7,10.4,7,11,7c0.4,0,0.7-0.1,1-0.3V14H10z"></path></g></svg>

After

Width:  |  Height:  |  Size: 535 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="24" height="24"><g class="nc-icon-wrapper" fill="#444444"><path d="M23.58.424A1,1,0,0,0,22.819.13C8.791.862,3.609,13.358,3.559,13.484a1,1,0,0,0,.22,1.08l5.657,5.657a1,1,0,0,0,1.085.218c.125-.051,12.554-5.291,13.348-19.253A1,1,0,0,0,23.58.424Zm-8.166,10.99a2,2,0,1,1,0-2.828A2,2,0,0,1,15.414,11.414Z" fill="#444444"/> <path data-color="color-2" d="M1.113,18.844a2.844,2.844,0,1,1,4.022,4.022C4.024,23.977,0,24,0,24S0,19.954,1.113,18.844Z" fill="#444444"/> <path id="color-2" d="M10.357,2.341A8.911,8.911,0,0,0,2.522,4.825a9.084,9.084,0,0,0-1.384,1.8,1,1,0,0,0,.155,1.215l1.989,1.99A26.623,26.623,0,0,1,10.357,2.341Z" fill="#444444"/> <path id="color-3" d="M21.659,13.643a8.911,8.911,0,0,1-2.484,7.835,9.084,9.084,0,0,1-1.8,1.384,1,1,0,0,1-1.215-.155l-1.99-1.989A26.623,26.623,0,0,0,21.659,13.643Z" fill="#444444"/></g></svg>

After

Width:  |  Height:  |  Size: 949 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 16 16" width="16" height="16"><g class="nc-icon-wrapper" fill="#444444"><path fill="#444444" d="M8,0C3.6,0,0,3.6,0,8c0,4.4,3.6,8,8,8s8-3.6,8-8C16,3.6,12.4,0,8,0z M8,10c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2 s2,0.9,2,2C10,9.1,9.1,10,8,10z M8,2c0.9,0,1.8,0.2,2.6,0.6L9.044,4.156c-0.761-0.207-1.327-0.207-2.089,0L5.4,2.6 C6.2,2.2,7.1,2,8,2z M2,8c0-0.9,0.2-1.8,0.6-2.6l1.556,1.556c-0.207,0.761-0.207,1.327,0,2.089L2.6,10.6C2.2,9.8,2,8.9,2,8z M8,14 c-0.9,0-1.8-0.2-2.6-0.6l1.556-1.556c0.761,0.207,1.327,0.207,2.089,0L10.6,13.4C9.8,13.8,8.9,14,8,14z M13.4,10.6l-1.556-1.556 c0.207-0.761,0.207-1.327,0-2.089L13.4,5.4C13.8,6.2,14,7.1,14,8C14,8.9,13.8,9.8,13.4,10.6z"/></g></svg>

After

Width:  |  Height:  |  Size: 776 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 24 24" width="24" height="24"><g class="nc-icon-wrapper" fill="#444444"><path fill="#444444" d="M6.5,11h11c3,0,5.5-2.5,5.5-5.5S20.5,0,17.5,0h-11C3.5,0,1,2.5,1,5.5S3.5,11,6.5,11z M6.5,2 C8.4,2,10,3.6,10,5.5S8.4,9,6.5,9S3,7.4,3,5.5S4.6,2,6.5,2z"></path> <path data-color="color-2" fill="#444444" d="M17.5,13h-11c-3,0-5.5,2.5-5.5,5.5S3.5,24,6.5,24h11c3,0,5.5-2.5,5.5-5.5S20.5,13,17.5,13z M17.5,22c-1.9,0-3.5-1.6-3.5-3.5s1.6-3.5,3.5-3.5s3.5,1.6,3.5,3.5S19.4,22,17.5,22z"></path></g></svg>

After

Width:  |  Height:  |  Size: 596 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 16 16" width="16" height="16"><g class="nc-icon-wrapper" fill="#444444"><path fill="#444444" d="M11,12H1c-0.553,0-1-0.447-1-1V1c0-0.552,0.447-1,1-1h10c0.553,0,1,0.448,1,1v10C12,11.553,11.553,12,11,12z "></path> <path data-color="color-2" fill="#444444" d="M15,16H4v-2h10V4h2v11C16,15.553,15.553,16,15,16z"></path></g></svg>

After

Width:  |  Height:  |  Size: 435 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

View File

@@ -0,0 +1,15 @@
module.exports = function (api) {
api.cache(true);
return {
presets: ["babel-preset-expo"],
plugins: [
[
"module-resolver",
{
extensions: [".tsx", ".ts", ".js", ".json"],
},
],
"react-native-reanimated/plugin",
],
};
};

View File

@@ -0,0 +1,57 @@
import React from "react";
import { StyleSheet } from "react-native";
import PropTypes from 'prop-types';
import { Button } from "galio-framework";
import argonTheme from "../constants/Theme";
class ArButton extends React.Component {
render() {
const { small, shadowless, children, color, style, fontSize, ...props } = this.props;
const colorStyle = color && argonTheme.COLORS[color.toUpperCase()];
const buttonStyles = [
small && styles.smallButton,
color && { backgroundColor: colorStyle },
!shadowless && styles.shadow,
{...style}
];
return (
<Button
style={buttonStyles}
shadowless
textStyle={{ fontSize: fontSize || 12, fontWeight: '700' }}
{...props}
>
{children}
</Button>
);
}
}
ArButton.propTypes = {
small: PropTypes.bool,
shadowless: PropTypes.bool,
color: PropTypes.oneOfType([
PropTypes.string,
PropTypes.oneOf(['default', 'primary', 'secondary', 'info', 'error', 'success', 'warning'])
])
}
const styles = StyleSheet.create({
smallButton: {
width: 75,
height: 28
},
shadow: {
shadowColor: 'black',
shadowOffset: { width: 0, height: 4 },
shadowRadius: 4,
shadowOpacity: 0.1,
elevation: 2,
},
});
export default ArButton;

View File

@@ -0,0 +1,141 @@
import React from "react";
import { useNavigation } from '@react-navigation/native';
import PropTypes from "prop-types";
import {
StyleSheet,
Image,
TouchableWithoutFeedback
} from "react-native";
import { Block, Text, theme } from "galio-framework";
import { argonTheme } from "../constants";
const Card = ({
item,
horizontal,
full,
style,
ctaColor,
imageStyle,
ctaRight
}) => {
const navigation = useNavigation();
const imageStyles = [
full ? styles.fullImage : styles.horizontalImage,
imageStyle
];
const cardContainer = [styles.card, styles.shadow, style];
const imgContainer = [
styles.imageContainer,
horizontal ? styles.horizontalStyles : styles.verticalStyles,
styles.shadow
];
return (
<Block row={horizontal} card flex style={cardContainer}>
<TouchableWithoutFeedback
onPress={() => navigation.navigate("Product", { product: item })}
>
<Block flex style={imgContainer}>
<Image source={{ uri: item.image }} style={imageStyles} />
</Block>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback
onPress={() => navigation.navigate("Product", { product: item })}
>
<Block flex space="between" style={styles.cardDescription}>
<Block flex>
<Text
style={{ fontFamily: 'open-sans-regular' }}
size={14}
style={styles.cardTitle}
color={argonTheme.COLORS.TEXT}
>
{item.title}
</Text>
{item.body ? (
<Block flex left>
<Text style={{ fontFamily: 'open-sans-regular' }} size={12} color={argonTheme.COLORS.TEXT}>
{item.body}
</Text>
</Block>
) : (
<Block />
)}
</Block>
<Block right={ctaRight ? true : false}>
<Text
style={{ fontFamily: 'open-sans-bold' }}
size={12}
muted={!ctaColor}
color={ctaColor || argonTheme.COLORS.ACTIVE}
bold
>
{item.cta}
</Text>
</Block>
</Block>
</TouchableWithoutFeedback>
</Block>
);
};
Card.propTypes = {
item: PropTypes.object,
horizontal: PropTypes.bool,
full: PropTypes.bool,
ctaColor: PropTypes.string,
imageStyle: PropTypes.any,
ctaRight: PropTypes.bool
};
const styles = StyleSheet.create({
card: {
backgroundColor: theme.COLORS.WHITE,
marginVertical: theme.SIZES.BASE,
borderWidth: 0,
minHeight: 114,
marginBottom: 4,
},
cardTitle: {
// flex: 1,
// flexWrap: "wrap",
paddingBottom: 6
},
cardDescription: {
padding: theme.SIZES.BASE / 2
},
imageContainer: {
borderRadius: 3,
elevation: 1,
overflow: "hidden"
},
image: {
// borderRadius: 3,
},
horizontalImage: {
height: 122,
width: "auto"
},
horizontalStyles: {
borderTopRightRadius: 0,
borderBottomRightRadius: 0
},
verticalStyles: {
borderBottomRightRadius: 0,
borderBottomLeftRadius: 0
},
fullImage: {
height: 215
},
shadow: {
shadowColor: "#8898AA",
shadowOffset: { width: 0, height: 1 },
shadowRadius: 6,
shadowOpacity: 0.1,
elevation: 2
}
});
export default Card;

View File

@@ -0,0 +1,143 @@
import React from "react";
import { StyleSheet, TouchableOpacity, Linking } from "react-native";
import { Block, Text, theme } from "galio-framework";
import Icon from "./Icon";
import argonTheme from "../constants/Theme";
class DrawerItem extends React.Component {
renderIcon = () => {
const { title, focused } = this.props;
switch (title) {
case "Home":
return (
<Icon
name="shop"
family="ArgonExtra"
size={14}
color={focused ? "white" : argonTheme.COLORS.PRIMARY}
/>
);
case "Elements":
return (
<Icon
name="map-big"
family="ArgonExtra"
size={14}
color={focused ? "white" : argonTheme.COLORS.ERROR}
/>
);
case "Articles":
return (
<Icon
name="spaceship"
family="ArgonExtra"
size={14}
color={focused ? "white" : argonTheme.COLORS.PRIMARY}
/>
);
case "Profile":
return (
<Icon
name="chart-pie-35"
family="ArgonExtra"
size={14}
color={focused ? "white" : argonTheme.COLORS.WARNING}
/>
);
case "Account":
return (
<Icon
name="calendar-date"
family="ArgonExtra"
size={14}
color={focused ? "white" : argonTheme.COLORS.INFO}
/>
);
case "Settings":
return (
<Icon
name="calendar-date"
family="ArgonExtra"
size={14}
color={focused ? "white" : argonTheme.COLORS.DEFAULT}
/>
);
case "Getting Started":
return (
<Icon
name="spaceship"
family="ArgonExtra"
size={14}
color={focused ? "white" : "rgba(0,0,0,0.5)"}
/>
);
case "Log out":
return <Icon />;
default:
return null;
}
};
render() {
const { focused, title, navigation, navigateTo } = this.props;
const containerStyles = [
styles.defaultStyle,
focused ? [styles.activeStyle, styles.shadow] : null,
];
return (
<TouchableOpacity
style={{ height: 60 }}
onPress={() =>
title == "Getting Started"
? Linking.openURL(
"https://demos.creative-tim.com/argon-pro-react-native/docs/"
).catch((err) => console.error("An error occurred", err))
: navigation.navigate(navigateTo)
}
>
<Block flex row style={containerStyles}>
<Block middle flex={0.1} style={{ marginRight: 5 }}>
{this.renderIcon()}
</Block>
<Block row center flex={0.9}>
<Text
style={{ fontFamily: "open-sans-regular" }}
size={15}
bold={focused ? true : false}
color={focused ? "white" : "rgba(0,0,0,0.5)"}
>
{title}
</Text>
</Block>
</Block>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
defaultStyle: {
paddingVertical: 16,
paddingHorizontal: 16,
marginBottom: 2,
},
activeStyle: {
backgroundColor: argonTheme.COLORS.ACTIVE,
borderRadius: 4,
},
shadow: {
shadowColor: theme.COLORS.BLACK,
shadowOffset: {
width: 0,
height: 2,
},
shadowRadius: 8,
shadowOpacity: 0.1,
},
});
export default DrawerItem;

View File

@@ -0,0 +1,255 @@
import React from 'react';
import { TouchableOpacity, StyleSheet, Platform, Dimensions, Keyboard } from 'react-native';
import { Button, Block, NavBar, Text, theme } from 'galio-framework';
import { CommonActions } from '@react-navigation/native';
import Icon from './Icon';
import Input from './Input';
import Tabs from './Tabs';
import argonTheme from '../constants/Theme';
const { height, width } = Dimensions.get('window');
const iPhoneX = () => Platform.OS === 'ios' && (height === 812 || width === 812 || height === 896 || width === 896);
const BellButton = ({isWhite, style, navigation}) => (
<TouchableOpacity style={[styles.button, style]} onPress={() => navigation.navigate('Notifications')}>
<Icon
family="ArgonExtra"
size={16}
name="bell"
color={argonTheme.COLORS[isWhite ? 'WHITE' : 'ICON']}
/>
<Block middle style={styles.notify} />
</TouchableOpacity>
);
const BasketButton = ({isWhite, style, navigation}) => (
<TouchableOpacity style={[styles.button, style]} onPress={() => navigation.navigate('Cart')}>
<Icon
family="ArgonExtra"
size={16}
name="basket"
color={argonTheme.COLORS[isWhite ? 'WHITE' : 'ICON']}
/>
</TouchableOpacity>
);
const SearchButton = ({isWhite, style, navigation}) => (
<TouchableOpacity style={[styles.button, style]} onPress={() => navigation.navigate('Search')}>
<Icon
size={16}
family="Galio"
name="search-zoom-in"
color={theme.COLORS[isWhite ? 'WHITE' : 'ICON']}
/>
</TouchableOpacity>
);
class Header extends React.Component {
handleLeftPress = () => {
const { back, navigation, scene } = this.props;
return (back ? navigation.dispatch(CommonActions.goBack()) : navigation.openDrawer());
}
renderRight = () => {
const { white, title, navigation } = this.props;
// const { routeName } = navigation.state;
if (title === 'Title') {
return [
<BellButton key='chat-title' navigation={navigation} isWhite={white} />,
<BasketButton key='basket-title' navigation={navigation} isWhite={white} />
]
}
switch (title) {
case 'Home':
case 'Deals':
case 'Categories':
case 'Category':
case 'Profile':
case 'Product':
case 'Search':
case 'Settings':
return ([
<BellButton key='chat-categories' navigation={navigation} isWhite={white}/>,
<BasketButton key='basket-categories' navigation={navigation} isWhite={white}/>
]);
default:
break;
}
}
renderSearch = () => {
const { navigation } = this.props;
return (
<Input
right
color="black"
style={styles.search}
placeholder="What are you looking for?"
placeholderTextColor={'#8898AA'}
onFocus={() => {Keyboard.dismiss(); navigation.navigate('Search');}}
iconContent={<Icon size={16} color={theme.COLORS.MUTED} name="search-zoom-in" family="ArgonExtra" />}
/>
);
}
renderOptions = () => {
const { navigation, optionLeft, optionRight } = this.props;
return (
<Block row style={styles.options}>
<Button shadowless style={[styles.tab, styles.divider]} onPress={() => navigation.navigate('Beauty')}>
<Block row middle>
<Icon name="diamond" family="ArgonExtra" style={{ paddingRight: 8 }} color={argonTheme.COLORS.ICON} />
<Text style={{ fontFamily: 'open-sans-regular' }} size={16} style={styles.tabTitle}>{optionLeft || 'Beauty'}</Text>
</Block>
</Button>
<Button shadowless style={styles.tab} onPress={() => navigation.navigate('Fashion')}>
<Block row middle>
<Icon size={16} name="bag-17" family="ArgonExtra" style={{ paddingRight: 8 }} color={argonTheme.COLORS.ICON}/>
<Text style={{ fontFamily: 'open-sans-regular' }} size={16} style={styles.tabTitle}>{optionRight || 'Fashion'}</Text>
</Block>
</Button>
</Block>
);
}
renderTabs = () => {
const { tabs, tabIndex, navigation } = this.props;
const defaultTab = tabs && tabs[0] && tabs[0].id;
if (!tabs) return null;
return (
<Tabs
data={tabs || []}
initialIndex={tabIndex || defaultTab}
onChange={id => navigation.setParams({ tabId: id })} />
)
}
renderHeader = () => {
const { search, options, tabs } = this.props;
if (search || tabs || options) {
return (
<Block center>
{search ? this.renderSearch() : null}
{options ? this.renderOptions() : null}
{tabs ? this.renderTabs() : null}
</Block>
);
}
}
render() {
const { back, title, white, transparent, bgColor, iconColor, titleColor, navigation, ...props } = this.props;
// const { routeName } = navigation.state;
const noShadow = ['Search', 'Categories', 'Deals', 'Pro', 'Profile'].includes(title);
const headerStyles = [
!noShadow ? styles.shadow : null,
transparent ? { backgroundColor: 'rgba(0,0,0,0)' } : null,
];
const navbarStyles = [
styles.navbar,
bgColor && { backgroundColor: bgColor }
];
return (
<Block style={headerStyles}>
<NavBar
back={false}
title={title}
style={navbarStyles}
transparent={transparent}
right={this.renderRight()}
rightStyle={{ alignItems: 'center' }}
onLeftPress={this.handleLeftPress}
left={
<Icon
name={back ? 'chevron-left' : "menu"} family="entypo"
// name={back ? 'nav-left' : "menu-8"} family="ArgonExtra"
size={back ? 20 : 20} onPress={this.handleLeftPress}
color={iconColor || (white ? argonTheme.COLORS.WHITE : argonTheme.COLORS.ICON)}
style={{ marginTop: 2 }}
/>
}
leftStyle={{ paddingVertical: 12, flex: 0.2 }}
titleStyle={[
styles.title,
{ color: argonTheme.COLORS[white ? 'WHITE' : 'HEADER'] },
titleColor && { color: titleColor }
]}
{...props}
/>
{this.renderHeader()}
</Block>
);
}
}
const styles = StyleSheet.create({
button: {
padding: 12,
position: 'relative',
},
title: {
width: '100%',
fontSize: 16,
fontWeight: 'bold',
},
navbar: {
paddingVertical: 0,
paddingBottom: theme.SIZES.BASE * 1.5,
paddingTop: iPhoneX ? theme.SIZES.BASE * 4 : theme.SIZES.BASE,
zIndex: 5,
},
shadow: {
backgroundColor: theme.COLORS.WHITE,
shadowColor: 'black',
shadowOffset: { width: 0, height: 2 },
shadowRadius: 6,
shadowOpacity: 0.2,
elevation: 3,
},
notify: {
backgroundColor: argonTheme.COLORS.LABEL,
borderRadius: 4,
height: theme.SIZES.BASE / 2,
width: theme.SIZES.BASE / 2,
position: 'absolute',
top: 9,
right: 12,
},
header: {
backgroundColor: theme.COLORS.WHITE,
},
divider: {
borderRightWidth: 0.3,
borderRightColor: theme.COLORS.ICON,
},
search: {
height: 48,
width: width - 32,
marginHorizontal: 16,
borderWidth: 1,
borderRadius: 3,
borderColor: argonTheme.COLORS.BORDER
},
options: {
marginBottom: 24,
marginTop: 10,
elevation: 4,
},
tab: {
backgroundColor: theme.COLORS.TRANSPARENT,
width: width * 0.35,
borderRadius: 0,
borderWidth: 0,
height: 24,
elevation: 0,
},
tabTitle: {
lineHeight: 19,
fontWeight: '400',
color: argonTheme.COLORS.HEADER
},
});
export default Header;

View File

@@ -0,0 +1,34 @@
import React from 'react';
import * as Font from 'expo-font';
import { createIconSetFromIcoMoon } from '@expo/vector-icons';
import { Icon } from 'galio-framework';
import argonConfig from '../assets/config/argon.json';
const ArgonExtra = require('../assets/font/argon.ttf');
const IconArgonExtra = createIconSetFromIcoMoon(argonConfig, 'ArgonExtra');
class IconExtra extends React.Component {
state = {
fontLoaded: false,
}
async componentDidMount() {
await Font.loadAsync({ ArgonExtra: ArgonExtra });
this.setState({ fontLoaded: true });
}
render() {
const { name, family, ...rest } = this.props;
if (name && family && this.state.fontLoaded) {
if (family === 'ArgonExtra') {
return <IconArgonExtra name={name} family={family} {...rest} />;
}
return <Icon name={name} family={family} {...rest} />;
}
return null;
}
}
export default IconExtra;

View File

@@ -0,0 +1,76 @@
import React from "react";
import { StyleSheet } from "react-native";
import PropTypes from 'prop-types';
import { Input } from "galio-framework";
import Icon from './Icon';
import { argonTheme } from "../constants";
class ArInput extends React.Component {
render() {
const { shadowless, success, error } = this.props;
const inputStyles = [
styles.input,
!shadowless && styles.shadow,
success && styles.success,
error && styles.error,
{...this.props.style}
];
return (
<Input
placeholder="write something here"
placeholderTextColor={argonTheme.COLORS.MUTED}
style={inputStyles}
color={argonTheme.COLORS.HEADER}
iconContent={
<Icon
size={14}
color={argonTheme.COLORS.ICON}
name="link"
family="AntDesign"
/>
}
{...this.props}
/>
);
}
}
ArInput.defaultProps = {
shadowless: false,
success: false,
error: false
};
ArInput.propTypes = {
shadowless: PropTypes.bool,
success: PropTypes.bool,
error: PropTypes.bool
}
const styles = StyleSheet.create({
input: {
borderRadius: 4,
borderColor: argonTheme.COLORS.BORDER,
height: 44,
backgroundColor: '#FFFFFF'
},
success: {
borderColor: argonTheme.COLORS.INPUT_SUCCESS,
},
error: {
borderColor: argonTheme.COLORS.INPUT_ERROR,
},
shadow: {
shadowColor: argonTheme.COLORS.BLACK,
shadowOffset: { width: 0, height: 0.5 },
shadowRadius: 1,
shadowOpacity: 0.13,
elevation: 2,
}
});
export default ArInput;

View File

@@ -0,0 +1,157 @@
import React from "react";
import { StyleSheet, TouchableWithoutFeedback } from "react-native";
import PropTypes from "prop-types";
import { Block, Text } from "galio-framework";
import Icon from "./Icon";
import { argonTheme } from "../constants";
export default class Notification extends React.Component {
render() {
const {
body,
color,
iconColor,
iconFamily,
iconName,
iconSize,
onPress,
style,
system,
time,
title,
transparent
} = this.props;
const iconContainer = [
styles.iconContainer,
{ backgroundColor: color || argonTheme.COLORS.PRIMARY },
system && { width: 34, height: 34 },
!system && styles.iconShadow
];
const container = [
styles.card,
!transparent && { backgroundColor: argonTheme.COLORS.WHITE },
!transparent && styles.cardShadow,
system && { height: 78 },
style
];
return (
<Block style={container} middle>
<TouchableWithoutFeedback onPress={onPress}>
<Block row style={{ width: "95%" }}>
<Block top flex={system ? 0.12 : 0.2} middle>
<Block middle style={iconContainer}>
<Icon
name={iconName}
family={iconFamily}
size={iconSize || system ? 16 : 22}
color={
iconColor || system ? argonTheme.COLORS.DEFAULT : argonTheme.COLORS.WHITE
}
/>
</Block>
</Block>
<Block flex style={{ paddingRight: 3, paddingLeft: 12 }}>
{system && (
<Block row space="between" style={{ height: 18 }}>
<Text color={argonTheme.COLORS.MUTED} style={{ fontFamily: 'open-sans-bold' }} size={13}>{title}</Text>
<Block row style={{ marginTop: 3 }}>
<Icon
family="material-community"
name="clock"
size={12}
color={argonTheme.COLORS.MUTED}
/>
<Text
color={argonTheme.COLORS.MUTED}
style={{
fontFamily: "open-sans-regular",
marginLeft: 3,
marginTop: -3
}}
size={12}
>
{time}
</Text>
</Block>
</Block>
)}
<Text
color={argonTheme.COLORS.TEXT}
size={system ? 13 : 14}
style={{ fontFamily: system ? "open-sans-bold" : "open-sans-regular" }}
>
{body}
</Text>
</Block>
{!system && (
<Block row flex={0.2} style={{ marginTop: 3 }}>
<Icon
family="material-community"
name="clock"
size={12}
color={argonTheme.COLORS.MUTED}
/>
<Text
color={argonTheme.COLORS.MUTED}
style={{
fontFamily: "open-sans-regular",
marginLeft: 3,
marginTop: -2
}}
size={12}
>
{time}
</Text>
</Block>
)}
</Block>
</TouchableWithoutFeedback>
</Block>
);
}
}
Notification.propTypes = {
body: PropTypes.string,
color: PropTypes.string,
iconColor: PropTypes.string,
iconFamily: PropTypes.string,
iconName: PropTypes.string,
iconSize: PropTypes.number,
onPress: PropTypes.func,
style: PropTypes.object,
system: PropTypes.bool,
time: PropTypes.string,
title: PropTypes.string,
transparent: PropTypes.bool,
};
const styles = StyleSheet.create({
iconContainer: {
width: 46,
height: 46,
borderRadius: 23,
marginTop: 2
},
iconShadow: {
shadowColor: "black",
shadowOffset: { width: 0, height: 4 },
shadowRadius: 4,
shadowOpacity: 0.1,
elevation: 2
},
card: {
zIndex: 2,
height: 127,
borderRadius: 6
},
cardShadow: {
shadowColor: argonTheme.COLORS.BLACK,
shadowOffset: { width: 0, height: 2 },
shadowRadius: 4,
shadowOpacity: 0.1,
elevation: 2
}
});

View File

@@ -0,0 +1,85 @@
import React from 'react';
import { StyleSheet } from 'react-native';
import PropTypes from 'prop-types';
import ModalDropdown from 'react-native-modal-dropdown';
import { Block, Text } from 'galio-framework';
import Icon from './Icon';
import { argonTheme } from '../constants';
class DropDown extends React.Component {
state = {
value: 1,
}
handleOnSelect = (index, value) => {
const { onSelect } = this.props;
this.setState({ value: value });
onSelect && onSelect(index, value);
}
render() {
const { onSelect, iconName, iconFamily, iconSize, iconColor, color, textStyle, style, ...props } = this.props;
const modalStyles = [
styles.qty,
color && { backgroundColor: color },
style
];
const textStyles = [
styles.text,
textStyle
];
return (
<ModalDropdown
style={modalStyles}
onSelect={this.handleOnSelect}
dropdownStyle={styles.dropdown}
dropdownTextStyle={{paddingLeft:16, fontSize:12}}
{...props}>
<Block flex row middle space="between">
<Text size={12} style={textStyles}>{this.state.value}</Text>
<Icon name={iconName || "nav-down"} family={iconFamily || "ArgonExtra"} size={iconSize || 10} color={iconColor || argonTheme.COLORS.WHITE} />
</Block>
</ModalDropdown>
)
}
}
DropDown.propTypes = {
onSelect: PropTypes.func,
iconName: PropTypes.string,
iconFamily: PropTypes.string,
iconSize: PropTypes.number,
color: PropTypes.string,
textStyle: PropTypes.any,
};
const styles = StyleSheet.create({
qty: {
width: 100,
backgroundColor: argonTheme.COLORS.DEFAULT,
paddingHorizontal: 16,
paddingTop: 10,
paddingBottom:9.5,
borderRadius: 4,
shadowColor: "rgba(0, 0, 0, 0.1)",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 4,
shadowOpacity: 1,
},
text: {
color: argonTheme.COLORS.WHITE,
fontWeight: '600'
},
dropdown: {
marginTop: 8,
marginLeft: -16,
width: 100,
},
});
export default DropDown;

View File

@@ -0,0 +1,24 @@
import React from 'react';
import { Switch, Platform } from 'react-native';
import argonTheme from '../constants/Theme';
class MkSwitch extends React.Component {
render() {
const { value, ...props } = this.props;
const thumbColor = Platform.OS === 'ios' ? null :
Platform.OS === 'android' && value ? argonTheme.COLORS.SWITCH_ON : argonTheme.COLORS.SWITCH_OFF;
return (
<Switch
value={value}
thumbColor={thumbColor}
ios_backgroundColor={argonTheme.COLORS.SWITCH_OFF}
trackColor={{ false: argonTheme.COLORS.SWITCH_ON, true: argonTheme.COLORS.SWITCH_ON }}
{...props}
/>
);
}
}
export default MkSwitch;

View File

@@ -0,0 +1,162 @@
import React from 'react';
import { StyleSheet, Dimensions, FlatList, Animated } from 'react-native';
import { Block, theme } from 'galio-framework';
const { width } = Dimensions.get('screen');
import argonTheme from '../constants/Theme';
const defaultMenu = [
{ id: 'music', title: 'Music', },
{ id: 'beauty', title: 'Beauty', },
{ id: 'fashion', title: 'Fashion', },
{ id: 'motocycles', title: 'Motocycles', },
];
export default class Tabs extends React.Component {
static defaultProps = {
data: defaultMenu,
initialIndex: null,
}
state = {
active: null,
}
componentDidMount() {
const { initialIndex } = this.props;
initialIndex && this.selectMenu(initialIndex);
}
animatedValue = new Animated.Value(1);
animate() {
this.animatedValue.setValue(0);
Animated.timing(this.animatedValue, {
toValue: 1,
duration: 300,
useNativeDriver: false, // color not supported
}).start()
}
menuRef = React.createRef();
onScrollToIndexFailed = () => {
this.menuRef.current.scrollToIndex({
index: 0,
viewPosition: 0.5
});
}
selectMenu = (id) => {
this.setState({ active: id });
this.menuRef.current.scrollToIndex({
index: this.props.data.findIndex(item => item.id === id),
viewPosition: 0.5
});
this.animate();
this.props.onChange && this.props.onChange(id);
}
renderItem = (item) => {
const isActive = this.state.active === item.id;
const textColor = this.animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [argonTheme.COLORS.TEXT, isActive ? argonTheme.COLORS.WHITE : argonTheme.COLORS.TEXT],
extrapolate: 'clamp',
});
const containerStyles = [
styles.titleContainer,
!isActive && { backgroundColor: argonTheme.COLORS.SECONDARY },
isActive && styles.containerShadow
];
return (
<Block style={containerStyles}>
<Animated.Text
style={[
styles.menuTitle,
{ color: textColor },
{ fontFamily: 'open-sans-bold' },
]}
onPress={() => this.selectMenu(item.id)}>
{item.title}
</Animated.Text>
</Block>
)
}
renderMenu = () => {
const { data, ...props } = this.props;
return (
<FlatList
{...props}
data={data}
horizontal={true}
ref={this.menuRef}
extraData={this.state}
keyExtractor={(item) => item.id}
showsHorizontalScrollIndicator={false}
onScrollToIndexFailed={this.onScrollToIndexFailed}
renderItem={({ item }) => this.renderItem(item)}
contentContainerStyle={styles.menu}
/>
)
}
render() {
return (
<Block style={styles.container}>
{this.renderMenu()}
</Block>
)
}
}
const styles = StyleSheet.create({
container: {
width: width,
backgroundColor: theme.COLORS.WHITE,
zIndex: 2,
},
shadow: {
shadowColor: theme.COLORS.BLACK,
shadowOffset: { width: 0, height: 2 },
shadowRadius: 8,
shadowOpacity: 0.2,
elevation: 4,
},
menu: {
paddingHorizontal: theme.SIZES.BASE * 2.5,
paddingTop: 8,
paddingBottom: 16,
},
titleContainer: {
alignItems: 'center',
backgroundColor: argonTheme.COLORS.ACTIVE,
borderRadius: 4,
marginRight: 9,
paddingHorizontal: 10,
paddingVertical: 3,
},
containerShadow: {
shadowColor: 'black',
shadowOffset: { width: 0, height: 2 },
shadowRadius: 4,
shadowOpacity: 0.1,
elevation: 1,
},
menuTitle: {
fontWeight: '600',
fontSize: 14,
// lineHeight: 28,
paddingVertical: 8,
paddingHorizontal: 12,
color: argonTheme.COLORS.MUTED
},
});

View File

@@ -0,0 +1,21 @@
import Button from './Button';
import Card from './Card';
import DrawerItem from './DrawerItem';
import Icon from './Icon';
import Header from './Header';
import Input from './Input';
import Switch from './Switch';
import Select from './Select';
import Notification from './Notification';
export {
Button,
Card,
DrawerItem,
Icon,
Input,
Header,
Switch,
Select,
Notification
};

View File

@@ -0,0 +1,63 @@
// local imgs
const Onboarding = require("../assets/imgs/bg.png");
const Logo = require("../assets/logo.jpg"); // 价值前沿 Logo
const LogoOnboarding = require("../assets/logo.jpg"); // 价值前沿 Logo
const ProfileBackground = require("../assets/imgs/profile-screen-bg.png");
const RegisterBackground = require("../assets/imgs/register-bg.png");
const Pro = require("../assets/imgs/getPro-bg.png");
const ArgonLogo = require("../assets/logo.jpg"); // 价值前沿 Logo
const iOSLogo = require("../assets/imgs/ios.png");
const androidLogo = require("../assets/imgs/android.png");
const ProfilePicture = require("../assets/imgs/profile-img.jpg")
// internet imgs
const ProfileChat = 'https://images.unsplash.com/photo-1500522144261-ea64433bbe27?fit=crop&w=1051&q=80'
const Viewed = [
'https://images.unsplash.com/photo-1501601983405-7c7cabaa1581?fit=crop&w=240&q=80',
'https://images.unsplash.com/photo-1543747579-795b9c2c3ada?fit=crop&w=240&q=80',
'https://images.unsplash.com/photo-1551798507-629020c81463?fit=crop&w=240&q=80',
'https://images.unsplash.com/photo-1470225620780-dba8ba36b745?fit=crop&w=240&q=80',
'https://images.unsplash.com/photo-1503642551022-c011aafb3c88?fit=crop&w=240&q=80',
'https://images.unsplash.com/photo-1482686115713-0fbcaced6e28?fit=crop&w=240&q=80',
];
const Beauty = [
'https://images.unsplash.com/photo-1501601983405-7c7cabaa1581?fit=crop&w=240&q=80'
];
const Music = {
'Artists': 'https://images.unsplash.com/photo-1466150036782-869a824aeb25?fit=crop&w=1350&q=80',
'Concerts': 'https://images.unsplash.com/photo-1464375117522-1311d6a5b81f?fit=crop&w=1050&q=80',
'DJs': 'https://images.unsplash.com/photo-1485120750507-a3bf477acd63?fit=crop&w=1050&q=80',
'Hands': 'https://images.unsplash.com/photo-1556229162-5c63ed9c4efb?fit=crop&w=1534&q=80',
'Body': 'https://images.unsplash.com/photo-1556229010-6c3f2c9ca5f8?fit=crop&w=634&q=80',
'Face': 'https://images.unsplash.com/photo-1487412912498-0447578fcca8?fit=crop&w=1350&q=80',
'Trends': 'https://images.unsplash.com/photo-1524835005923-56700046e4a8?fit=crop&w=1052&q=80',
'Clothes': 'https://images.unsplash.com/photo-1487222477894-8943e31ef7b2?fit=crop&w=726&q=80',
'Accessory': 'https://images.unsplash.com/photo-1542779632-539b861ee8f9?fit=crop&w=634&q=80',
'Fashion': 'https://images.unsplash.com/photo-1479064555552-3ef4979f8908?fit=crop&w=1350&q=80',
'Garage_sale': 'https://images.unsplash.com/photo-1484502249930-e1da807099a5?fit=crop&w=1267&q=80',
'Wedding_dress': 'https://images.unsplash.com/photo-1519657337289-077653f724ed?fit=crop&w=1350&q=80'
}
const Products = {
'View article': 'https://images.unsplash.com/photo-1501601983405-7c7cabaa1581?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=840&q=840',
};
export default {
Onboarding,
Logo,
LogoOnboarding,
ProfileBackground,
ProfilePicture,
RegisterBackground,
Viewed,
Products,
Pro,
ArgonLogo,
iOSLogo,
androidLogo,
Beauty,
Music,
ProfileChat
};

View File

@@ -0,0 +1,35 @@
export default {
COLORS: {
DEFAULT: '#172B4D',
PRIMARY: '#5E72E4',
SECONDARY: '#F7FAFC',
LABEL: '#FE2472',
INFO: '#11CDEF',
ERROR: '#F5365C',
SUCCESS: '#2DCE89',
WARNING: '#FB6340',
TEXT: '#32325D',
MUTED: '#8898AA',
INPUT: '#DCDCDC',
INPUT_SUCCESS: '#7BDEB2',
INPUT_ERROR: '#FCB3A4',
ACTIVE: '#5E72E4', //same as primary
BUTTON_COLOR: '#9C26B0', //wtf
PLACEHOLDER: '#9FA5AA',
SWITCH_ON: '#5E72E4',
SWITCH_OFF: '#D4D9DD',
GRADIENT_START: '#6B24AA',
GRADIENT_END: '#AC2688',
PRICE_COLOR: '#EAD5FB',
BORDER_COLOR: '#E7E7E7',
BLOCK: '#E7E7E7',
ICON: '#172B4D',
HEADER: '#525F7F',
BORDER: '#CAD1D7',
WHITE: '#FFFFFF',
BLACK: '#000000',
TWITTER: '#1DA1F2',
FACEBOOK: '#3B5999',
DRIBBBLE: '#EA4C89'
}
};

View File

@@ -0,0 +1,29 @@
export default [
{
title: 'Ice cream is made with carrageenan …',
image: 'https://images.unsplash.com/photo-1516559828984-fb3b99548b21?ixlib=rb-1.2.1&auto=format&fit=crop&w=2100&q=80',
cta: 'View article',
horizontal: true
},
{
title: 'Is makeup one of your daily esse …',
image: 'https://images.unsplash.com/photo-1519368358672-25b03afee3bf?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2004&q=80',
cta: 'View article'
},
{
title: 'Coffee is more than just a drink: Its …',
image: 'https://images.unsplash.com/photo-1500522144261-ea64433bbe27?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2102&q=80',
cta: 'View article'
},
{
title: 'Fashion is a popular style, especially in …',
image: 'https://images.unsplash.com/photo-1487222477894-8943e31ef7b2?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1326&q=80',
cta: 'View article'
},
{
title: 'Argon is a great free UI packag …',
image: 'https://images.unsplash.com/photo-1482686115713-0fbcaced6e28?fit=crop&w=1947&q=80',
cta: 'View article',
horizontal: true
},
];

View File

@@ -0,0 +1,86 @@
export default {
products: [
{
id: 1,
title: 'Discover What\'s New In Beauty And Rec ...',
image: 'https://images.unsplash.com/photo-1500839941678-aae14dbfae9a?fit=crop&w=1120&q=80',
price: 180,
stock: true,
qty: 1,
horizontal: true,
},
{
id: 2,
title: 'Carry the charm of New Orleans with you ...',
image: 'https://images.unsplash.com/photo-1517857399767-a9dc28f5a734?fit=crop&w=1050&q=80',
price: 230,
stock: true,
qty: 1,
},
{
id: 3,
title: "Blue Nile is the world\'s leading diamond je ...",
image: 'https://images.unsplash.com/photo-1532947974358-a218d18d8d14?fit=crop&w=1050&q=80',
price: 90,
stock: true,
qty: 1,
},
{
id: 4,
title: 'The perfect diamond engagement ring ...',
image: 'https://images.unsplash.com/photo-1522312346375-d1a52e2b99b3?fit=crop&w=640&q=80',
price: 300,
stock: true,
qty: 1,
horizontal: true,
},
{
id: 5,
title: 'Make the most of what you wear.',
image: 'https://images.unsplash.com/photo-1490367532201-b9bc1dc483f6?fit=crop&w=840&q=80',
price: 97,
stock: true,
qty: 1,
full: true,
},
],
suggestions: [
{
title: "We'll start with the basics and go...",
// image: 'https://source.unsplash.com/pIs_JZT49lo/840x840',
image: 'https://images.unsplash.com/photo-1529504426707-d1d7a0dc458a?crop=entropy&w=840&h=840&fit=crop',
price: 180,
horizontal: true,
},
{
title: 'Harley-Davidson Motorcycle has a lot of...',
// image: 'https://source.unsplash.com/4ab-uGbwnGE/840x840',
image: 'https://images.unsplash.com/photo-1524591652733-73fa1ae7b5ee?crop=entropy&w=840&h=840&fit=crop',
price: 220,
},
{
title: "Whether youre tearing up the track...",
// image: 'https://source.unsplash.com/dyjCKPEba8A/840x840',
image: 'https://images.unsplash.com/photo-1539149398640-bdc7531102dd?crop=entropy&w=840&h=840&fit=crop',
price: 40,
},
{
title: 'Personal style is in the details of the...',
// image: 'https://source.unsplash.com/_oX1UvvHrOY/840x840',
image: 'https://images.unsplash.com/photo-1512749491228-caef5a7831d7?crop=entropy&w=840&h=840&fit=crop',
price: 188,
horizontal: true,
},
{
title: 'Whats so special about Le Mans, you ask?',
image: 'https://images.unsplash.com/photo-1535970793482-07de93762dc4?crop=entropy&w=840&h=840&fit=crop',
price: 180,
},
{
title: 'The BMW 6 Series Gran Turismo, Gran...',
// image: 'https://source.unsplash.com/X8siGp-Ie00/840x840',
image: 'https://images.unsplash.com/photo-1536364127590-1594e3161294?crop=entropy&w=840&h=840&fit=crop',
price: 180,
},
]
}

View File

@@ -0,0 +1,453 @@
export default {
hands: {
images: [
{
title: "Tisson Watch",
description:
"Discover all Tissot® novelties with watches for men and women on the Official Tissot Website.",
image:
"https://images.unsplash.com/photo-1522312346375-d1a52e2b99b3?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Apple Watch",
description:
"Apple Watch Series 4 features its largest display yet, a re-engineered digital crown, cellular to make calls.",
image:
"https://images.unsplash.com/photo-1530518119128-ca0bd1a0643b?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Fossil Watch",
description:
"We have the latest styles & trends of Fossil watches, wallets, bags and accessories. FREE Shipping & Returns.",
image:
"https://images.unsplash.com/photo-1539874754764-5a96559165b0?crop=entropy&fit=crop&w=840&q=80"
}
],
suggestions: [
{
title: "Looking for Men's watches ?",
price: 298,
// image: 'https://source.unsplash.com/YHbcum51JB0/840x840',
image:
"https://images.unsplash.com/photo-1490367532201-b9bc1dc483f6?crop=entropy&w=840&h=840&fit=crop"
},
{
title: "Adjust your watch to your outfit.",
price: 712,
// image: 'https://source.unsplash.com/Ws4wd-vJ9M0/840x840',
image:
"https://images.unsplash.com/photo-1491336477066-31156b5e4f35?crop=entropy&w=840&h=840&fit=crop"
}
]
},
face: {
images: [
{
title: "Brushes",
description:
"12 Makeup Brushes You Actually Need and Exactly How to Use Them. Foundation Brush. Use it to smooth.",
image:
"https://images.unsplash.com/photo-1522338242992-e1a54906a8da?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Pink Lipstick",
description:
"Lipstick is a cosmetic product containing pigments, waxes, and emollients that apply color, and protection to the lips.",
image:
"https://images.unsplash.com/photo-1498842812179-c81beecf902c?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Skin Care",
description:
"Get all the information you need on skin care routines, how-tos and anti-aging to find the best solutions for your skin.",
image:
"https://images.unsplash.com/photo-1525286116112-b59af11adad1?crop=entropy&fit=crop&w=840&q=80"
}
],
suggestions: [
{
title: "Curious Blossom Skin Care Kit.",
price: 29,
// image: 'https://source.unsplash.com/I7BSOoPa5hM/840x840',
image:
"https://images.unsplash.com/photo-1536303006682-2ee36ba49592?crop=entropy&w=840&h=840&fit=crop"
},
{
title: "Buy the best skin care products.",
price: 12,
// image: 'https://source.unsplash.com/1g4YwpKr3ow/840x840',
image:
"https://images.unsplash.com/photo-1501719539451-126fddec9024?crop=entropy&w=840&h=840&fit=crop"
}
]
},
accessory: {
images: [
{
title: "Mens Accessories",
description:
"Explore Urban Outfitters collection of men's accessories, featuring the season's newest arrivals. You'll find everything.",
image:
"https://images.unsplash.com/photo-1509112756314-34a0badb29d4?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Bow Ties",
description:
"With the largest selection of bow ties, you'll find exactly what you're looking for. Free shipping and returns...",
image:
"https://images.unsplash.com/photo-1495681796091-d84e65e2ad51?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "A Mens Kit",
description:
"Versatile accessories for men to pull your look together. Complete the look with the best in men's accessories.",
image:
"https://images.unsplash.com/photo-1479064555552-3ef4979f8908?crop=entropy&fit=crop&w=840&q=80"
}
],
suggestions: [
{
title: "Looking good has never been so easy.",
price: 29,
// image: 'https://source.unsplash.com/ZLLhx5Yg0Mc/840x840',
image:
"https://images.unsplash.com/photo-1485373650022-3ed53f62b8f3?crop=entropy&w=840&h=840&fit=crop"
},
{
title: "Make the most of what you wear.",
price: 12,
// image: 'https://source.unsplash.com/YHbcum51JB0/840x840',
image:
"https://images.unsplash.com/photo-1490367532201-b9bc1dc483f6?crop=entropy&w=840&h=840&fit=crop"
}
]
},
body: {
images: [
{
title: "Eau de Parfum",
description:
"Discover our range of eau de parfum and eau de toilette inc Dior, Marc Jacobs and YSL collections.",
image:
"https://images.unsplash.com/photo-1512777576244-b846ac3d816f?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Valentino",
description:
"Valentino Eau de Parfum by Valentino is a floral aldehyde fragrance for women. Valentino Eau de Parfum is a new.",
image:
"https://images.unsplash.com/photo-1512303500391-74e5b8c3c07f?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Skin Care",
description:
"Shop skincare products. Find top-rated products from leading skincare brands to help target specific skin concerns.",
// image: 'https://source.unsplash.com/oha7AANDiL8/840x840',
image:
"https://images.unsplash.com/photo-1526758097130-bab247274f58?crop=entropy&fit=crop&w=840&q=80"
}
],
suggestions: [
{
title: "Rose Skin Care A leading clinical...",
price: 29,
// image: 'https://source.unsplash.com/e9geJhWBC5I/840x840',
image:
"https://images.unsplash.com/photo-1517391882955-e1b20cafee7f?crop=entropy&w=840&h=840&fit=crop"
},
{
title: "Give your skincare routine a boost...",
price: 12,
// image: 'https://source.unsplash.com/Xuks25qlxeg/840x840',
image:
"https://images.unsplash.com/photo-1512303452027-750531d7cb7f?crop=entropy&w=840&h=840&fit=crop"
}
]
},
clothes: {
images: [
{
title: "Dream Car",
description:
"Delve into the fascinating world of BMW. Read inspiring stories and interviews, watch exciting videos.",
image:
"https://images.unsplash.com/photo-1518987048-93e29699e79a?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Smart Mobility",
description:
"The idea of Tuber originated at the BMW Group 2018 rad°hub gathering in Rotterdam.",
image:
"https://images.unsplash.com/photo-1529225596519-1262d0bfc242?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Need for Speed",
description:
"The current version of the ultimate racing game experience puts the player behind the wheel.",
image:
"https://images.unsplash.com/photo-1517153295259-74eb0b416cee?crop=entropy&fit=crop&w=840&q=80"
}
],
suggestions: [
{
title: "The gaming version of an action movie...",
price: 29,
image:
"https://images.unsplash.com/photo-1535970793482-07de93762dc4?crop=entropy&w=840&h=840&fit=crop"
},
{
title: "Whats so special about Le Mans?",
price: 12,
image:
"https://images.unsplash.com/photo-1536364127590-1594e3161294?crop=entropy&w=840&h=840&fit=crop"
}
]
},
trends: {
images: [
{
title: "Ford Mustang",
description:
"The 2019 Mustang classic performance car just got better. Learn about the most advanced Mustang ever.",
image:
"https://images.unsplash.com/photo-1533106418989-88406c7cc8ca?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Muscle Car",
description:
"The 2019 Mustang is designed to custom-fit the way you drive, down to the last detail.",
image:
"https://images.unsplash.com/photo-1496437792604-55ca7c5c3f6f?crop=entropy&fit=crop&w=840&q=80"
},
{
title: "Customised View",
description:
"Optional on the EcoBoost® Premium and GT Premium, this 12-inch all-digital LCD cluster lets you personalise.",
image:
"https://images.unsplash.com/photo-1506361590224-e2586b4ad877?crop=entropy&fit=crop&w=840&q=80"
}
],
suggestions: [
{
title: "Whether youre tearing up the track...",
price: 29,
image:
"https://images.unsplash.com/photo-1539149398640-bdc7531102dd?crop=entropy&w=840&h=840&fit=crop"
},
{
title: "Personal style is in the details...",
price: 12,
image:
"https://images.unsplash.com/photo-1512749491228-caef5a7831d7?crop=entropy&w=840&h=840&fit=crop"
}
]
},
artists: {
images: [
{
title: "Painting Studio",
description:
"You need a creative space ready for your art? We got that covered.",
image:
"https://images.unsplash.com/photo-1501084817091-a4f3d1d19e07?fit=crop&w=2700&q=80"
},
{
title: "Art Gallery",
description:
"Don't forget to visit one of the coolest art galleries in town.",
image:
"https://images.unsplash.com/photo-1500628550463-c8881a54d4d4?fit=crop&w=2698&q=80"
},
{
title: "Video Services",
description:
"Some of the best music video services someone could have for the lowest prices.",
image:
"https://images.unsplash.com/photo-1496680392913-a0417ec1a0ad?fit=crop&w=2700&q=80"
}
],
suggestions: [
{
title: "Music studio for real...",
price: 1800,
image:
"https://images.unsplash.com/photo-1511379938547-c1f69419868d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2700&q=80"
},
{
title: "Music equipment to borrow...",
price: 300,
image:
"https://images.unsplash.com/photo-1477233534935-f5e6fe7c1159?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2700&q=80"
}
]
},
concerts: {
images: [
{
title: "Metal Concert",
description:
"Ready for the hardest metal concert you've ever seen? Check out this Progressive Metal concert!",
image:
"https://images.unsplash.com/photo-1470229722913-7c0e2dbbafd3?fit=crop&w=2700&q=80"
},
{
title: "Classical Music Concert",
description:
"Cello, viola, bassoons and awesome calm sound vibrations. Welcome to one of the most expected classical concerts in Europe.",
image:
"https://images.unsplash.com/photo-1458639817867-2c9d4c5dcad4?fit=crop&w=2700&q=80"
},
{
title: "Beethoven Tribute Concert",
description:
"Ludwig van Beethoven was a German composer and pianist. One of the greatest to ever step on Earth.",
image:
"https://images.unsplash.com/photo-1532089006065-de61ca171e56?fit=crop&w=2700&q=80"
}
],
suggestions: [
{
title: "A night out with your friends...",
price: 500,
image:
"https://images.unsplash.com/photo-1438557068880-c5f474830377?fit=crop&w=2706&q=80"
},
{
title: "One cool festival for...",
price: 470,
image:
"https://images.unsplash.com/photo-1469488865564-c2de10f69f96?fit=crop&w=2700&q=80"
}
]
},
DJs: {
images: [
{
title: 'Tech-House Party',
description: 'Get ready for an awesome party in the backyard of one of the greatest Tech-House DJs in the world.',
image: 'https://images.unsplash.com/photo-1542851041-0a2a651561a3?fit=crop&w=2706&q=80',
},
{
title: 'Dubstep Party',
description: 'We\'re sure you\'re going to enjoy this party full of fast drums and crazy rhythms.',
image: 'https://images.unsplash.com/photo-1530521877972-491c628bbb31?fit=crop&w=2614&q=80',
},
{
title: 'Hip-Hop Party',
description: 'Fat 808s, hype music and a whole different Urban vibe. These Hip-Hop DJs are going to spin the best songs you\'ve ever listened to.',
image: 'https://images.unsplash.com/photo-1544616326-a041e9e3b348?fit=crop&w=3889&q=80',
},
],
suggestions: [
{
title: 'Ableton Push 2',
price: 500,
image: 'https://images.unsplash.com/photo-1523297313810-5c8718fee854?fit=crop&w=2700&q=80',
},
{
title: 'Pocket Operator Office',
price: 89,
image: 'https://images.unsplash.com/photo-1553010214-b15a4029d601?fit=crop&w=2900&q=80',
},
]
},
fashion: {
images: [
{
title: 'Jackets',
description: 'Best fashionable denim jackets you could find on the internet.',
image: 'https://images.unsplash.com/photo-1523979858672-687c4d4621a0?fit=crop&w=1333&q=80',
},
{
title: 'Shirts',
description: 'We all like looking good while enjoying our coffee.',
image: 'https://images.unsplash.com/photo-1559526323-cb2f2fe2591b?fit=crop&w=1350&q=80',
},
{
title: 'Dresses',
description: 'Be the queen you want to be.',
image: 'https://images.unsplash.com/photo-1530883374727-29c498f224c0?fit=crop&w=634&q=80',
},
],
suggestions: [
{
title: "Rose Skin Care A leading clinical...",
price: 29,
image:
"https://images.unsplash.com/photo-1517391882955-e1b20cafee7f?crop=entropy&w=840&h=840&fit=crop"
},
{
title: "Give your skincare routine a boost...",
price: 12,
image:
"https://images.unsplash.com/photo-1512303452027-750531d7cb7f?crop=entropy&w=840&h=840&fit=crop"
}
]
},
garagesale: {
images: [
{
title: 'General clothes',
description: 'The opening of this new local store came with a great impact on our community.',
image: 'https://images.unsplash.com/photo-1490481651871-ab68de25d43d?fit=crop&w=1350&q=80',
},
{
title: 'Jeans',
description: 'Not really certain about kind of jeans do you want?',
image: 'https://images.unsplash.com/photo-1540221652346-e5dd6b50f3e7?fit=crop&w=1349&q=80',
},
{
title: 'Scarfs',
description: 'Any colour, any material, any brand. We got them all.',
image: 'https://images.unsplash.com/photo-1465199549974-7d82de6e2830?fit=crop&w=1189&q=80',
},
],
suggestions: [
{
title: "Rose Skin Care A leading clinical...",
price: 29,
image:
"https://images.unsplash.com/photo-1517391882955-e1b20cafee7f?crop=entropy&w=840&h=840&fit=crop"
},
{
title: "Give your skincare routine a boost...",
price: 12,
image:
"https://images.unsplash.com/photo-1512303452027-750531d7cb7f?crop=entropy&w=840&h=840&fit=crop"
}
]
},
weddingdress: {
images: [
{
title: 'Designer dress',
description: 'Best dresses from the most popular designers.',
image: 'https://images.unsplash.com/photo-1546804784-896d0dca3805?fit=crop&w=1350&q=80',
},
{
title: 'Wedding services',
description: 'We could help you out with your wedding planning, give us a try!',
image: 'https://images.unsplash.com/photo-1546193430-c2d207739ed7?fit=crop&w=689&q=80',
},
{
title: 'Wedding preparations',
description: 'Count on us for the best wedding preparations of this year.',
image: 'https://images.unsplash.com/photo-1541250848049-b4f7141dca3f?fit=crop&w=634&q=80',
},
],
suggestions: [
{
title: "Rose Skin Care A leading clinical...",
price: 29,
image:
"https://images.unsplash.com/photo-1517391882955-e1b20cafee7f?crop=entropy&w=840&h=840&fit=crop"
},
{
title: "Give your skincare routine a boost...",
price: 12,
image:
"https://images.unsplash.com/photo-1512303452027-750531d7cb7f?crop=entropy&w=840&h=840&fit=crop"
}
]
},
};

View File

@@ -0,0 +1,119 @@
export default {
shoes: [
{
title: "Nike Air Max",
body: "Air Max shoes are the best line of shoes created by Nike.",
image: 'https://images.unsplash.com/photo-1511556670410-f6989d6b0766?fit=crop&w=1234&q=80',
cta: "View article",
horizontal: true,
},
{
title: 'Blue Adidas',
cta: "View article",
image: 'https://images.unsplash.com/photo-1520256788229-d4640c632e4b?fit=crop&w=1350&q=80',
},
{
title: 'Perfect Shoes',
cta: "View article",
image: 'https://images.unsplash.com/photo-1525092029632-cb75fe5dd776?fit=crop&w=1350&q=80',
},
{
title: 'Fashion Shoes',
body: "Fashion is a popular aesthetic expression in a certain time and context.",
cta: "View article",
image: 'https://images.unsplash.com/photo-1523191665038-d75548b1a52a?fit=crop&w=1350&q=80',
},
{
title: 'Orange Sneakers',
cta: "View article",
image: 'https://images.unsplash.com/photo-1521774971864-62e842046145?fit=crop&w=1350&q=80',
},
],
beauty: [
{
title: 'Makeup Kit',
body: "Best Makeup kits available online today!",
image: 'https://images.unsplash.com/photo-1527633412983-d80af308e660?fit=crop&w=634&q=80',
cta: "View article",
},
{
title: 'Lipstick Kit',
image: 'https://images.unsplash.com/photo-1530863138121-03aea5f46fd4?fit=crop&w=1350&q=80',
cta: "View article",
},
{
title: 'Premium Brushes',
image: 'https://images.unsplash.com/photo-1519368358672-25b03afee3bf?fit=crop&w=1002&q=80',
cta: "View article",
},
{
title: 'Fashion Colors',
body: "What's going on this summer?",
image: 'https://images.unsplash.com/photo-1515688594390-b649af70d282?fit=crop&w=995&q=80',
cta: "View article",
},
{
title: 'Pink Glitter',
image: 'https://images.unsplash.com/photo-1526336686748-bd7bb2f1df84?fit=crop&w=1350&q=80',
cta: "View article",
},
],
fashion: [
{
title: 'Colorful Hearts',
body: "Best gift for your special someone. Show them some love!",
image: 'https://images.unsplash.com/photo-1541329164087-0283eda68eda?fit=crop&w=634&q=80',
cta: "View article",
},
{
title: 'Get purple inspiration',
image: 'https://images.unsplash.com/photo-1551895889-f1469e75acaa?fit=crop&w=1189&q=80',
cta: "View article",
},
{
title: 'Favorite high heels',
image: 'https://images.unsplash.com/photo-1491897554428-130a60dd4757?fit=crop&w=1400&q=80',
cta: "View article",
},
{
title: 'Pastel Hearts Sunglasses',
body: "Everybody needs a special pair of sunglasses",
image: 'https://images.unsplash.com/photo-1530832805884-45f17d57a3d8?fit=crop&w=634&q=80',
cta: "View article",
},
{
title: 'Awesome destination',
image: 'https://images.unsplash.com/photo-1513149739851-50f01dfcbd9a?fit=crop&w=1350&q=80',
cta: "View article",
},
],
places: [
{
title: 'A literary journal published by the Black Earth.',
body: "Find out more about these articles.",
image: 'https://images.unsplash.com/photo-1551814038-046d8e76f44f?fit=crop&w=1489&q=80',
cta: "View article",
},
{
title: 'By submitting, you guarantee.',
image: 'https://images.unsplash.com/photo-1487029413235-e3f7a0e8e140?fit=crop&w=1050&q=80',
cta: "View article",
},
{
title: 'All About Lights is located in Boie.',
image: 'https://images.unsplash.com/photo-1516437124483-bb0f86708932?fit=crop&w=800&q=80',
cta: "View article",
},
{
title: 'Meet our about play staff: click on any.',
body: "Find out more about our staff by reading this article.",
image: 'https://images.unsplash.com/photo-1502048962539-e47cf2fcc9ce?fit=crop&w=1053&q=80',
cta: "View article",
},
{
title: 'Whether it comes from the Sun.',
image: 'https://images.unsplash.com/photo-1485001564903-56e6a54d46ef?fit=crop&w=1050&q=80',
cta: "View article",
},
],
};

View File

@@ -0,0 +1,19 @@
import argonTheme from './Theme';
import articles from './articles';
import Images from './Images';
import tabs from './tabs';
import categories from './categories';
import deals from './deals';
import utils from './utils';
import cart from './cart';
export {
articles,
argonTheme,
Images,
tabs,
categories,
deals,
utils,
cart
};

View File

@@ -0,0 +1,14 @@
export default tabs = {
beauty: [
{ id: 'music', title: 'Music' },
{ id: 'beauty', title: 'Beauty' },
{ id: 'fashion', title: 'Fashion' },
{ id: 'clothes', title: 'Clothes'}
],
fashion: [
{ id: 'shoes', title: 'Shoes', },
{ id: 'beauty', title: 'Beauty', },
{ id: 'fashion', title: 'Fashion', },
{ id: 'places', title: 'Places', }
],
}

View File

@@ -0,0 +1,6 @@
import { Platform, StatusBar } from 'react-native';
import { theme } from 'galio-framework';
export const StatusHeight = StatusBar.currentHeight;
export const HeaderHeight = (theme.SIZES.BASE * 3.5 + (StatusHeight || 0));
export const iPhoneX = () => Platform.OS === 'ios' && (height === 812 || width === 812);

View File

@@ -0,0 +1,5 @@
import { registerRootComponent } from "expo";
import App from "./App";
registerRootComponent(App);

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1,255 @@
import React from "react";
import {
ScrollView,
StyleSheet,
Dimensions,
Image,
TouchableOpacity,
Linking,
} from "react-native";
import { Block, Text, theme } from "galio-framework";
import { useSafeArea } from "react-native-safe-area-context";
import { Box, HStack, VStack, Icon, Pressable, Spinner } from "native-base";
import { Ionicons } from "@expo/vector-icons";
import { LinearGradient } from "expo-linear-gradient";
import Images from "../constants/Images";
import { DrawerItem as DrawerCustomItem } from "../components/index";
import { useAuth } from "../src/contexts/AuthContext";
const { width } = Dimensions.get("screen");
// 金色主题色
const GOLD_PRIMARY = '#D4AF37';
// 用户卡片组件
const UserCard = ({ navigation }) => {
const { user, isLoggedIn, isLoading, subscription, logout } = useAuth();
const handleLoginPress = () => {
navigation.closeDrawer();
// 使用 getParent 获取根导航器来导航到 Login
navigation.getParent()?.navigate("Login");
};
const handleLogoutPress = async () => {
await logout();
};
// 获取订阅显示文本
const getSubscriptionText = () => {
if (!subscription || !subscription.is_active) {
return "免费用户";
}
const typeMap = { pro: "Pro 会员", max: "Max 会员" };
return typeMap[subscription.type] || "免费用户";
};
if (isLoading) {
return (
<Box px={4} py={4} mb={2}>
<HStack alignItems="center" space={3}>
<Spinner size="sm" color="primary.500" />
<Text color="#8898AA" style={{ fontFamily: "open-sans-regular" }}>
加载中...
</Text>
</HStack>
</Box>
);
}
if (!isLoggedIn) {
return (
<Pressable onPress={handleLoginPress}>
<Box
mx={3}
mb={3}
p={4}
bg="rgba(124, 58, 237, 0.1)"
borderWidth={1}
borderColor="rgba(124, 58, 237, 0.3)"
borderRadius={12}
>
<HStack alignItems="center" space={3}>
<Box
w={10}
h={10}
bg="rgba(124, 58, 237, 0.2)"
borderRadius={20}
alignItems="center"
justifyContent="center"
>
<Icon as={Ionicons} name="person-outline" size="md" color="#7C3AED" />
</Box>
<VStack flex={1}>
<Text
color="#333"
style={{ fontFamily: "open-sans-bold", fontSize: 14 }}
>
登录/注册
</Text>
<Text
color="#8898AA"
style={{ fontFamily: "open-sans-regular", fontSize: 12 }}
>
登录解锁更多功能
</Text>
</VStack>
<Icon as={Ionicons} name="chevron-forward" size="sm" color="#8898AA" />
</HStack>
</Box>
</Pressable>
);
}
// 已登录状态
return (
<Box mx={3} mb={3} p={4} bg="#F8F9FE" borderRadius={12}>
<HStack alignItems="center" space={3}>
<Box
w={10}
h={10}
bg="#7C3AED"
borderRadius={20}
alignItems="center"
justifyContent="center"
>
<Text style={{ color: "white", fontFamily: "open-sans-bold", fontSize: 16 }}>
{(user?.username || user?.nickname || "U").charAt(0).toUpperCase()}
</Text>
</Box>
<VStack flex={1}>
<Text
color="#333"
style={{ fontFamily: "open-sans-bold", fontSize: 14 }}
>
{user?.nickname || user?.username || "用户"}
</Text>
<HStack alignItems="center" space={1}>
<Box
px={1.5}
py={0.5}
bg={subscription?.is_active ? "rgba(16, 185, 129, 0.1)" : "rgba(100, 116, 139, 0.1)"}
borderRadius={4}
>
<Text
style={{
fontFamily: "open-sans-regular",
fontSize: 10,
color: subscription?.is_active ? "#10B981" : "#64748B",
}}
>
{getSubscriptionText()}
</Text>
</Box>
</HStack>
</VStack>
<Pressable onPress={handleLogoutPress}>
<Icon as={Ionicons} name="log-out-outline" size="sm" color="#F43F5E" />
</Pressable>
</HStack>
</Box>
);
};
function CustomDrawerContent({
drawerPosition,
navigation,
profile,
focused,
state,
...rest
}) {
const insets = useSafeArea();
const screens = [
{ title: "事件中心", navigateTo: "EventsDrawer" },
{ title: "市场热点", navigateTo: "MarketDrawer" },
{ title: "Home", navigateTo: "HomeDrawer" },
{ title: "Profile", navigateTo: "ProfileDrawer" },
{ title: "Account", navigateTo: "AccountDrawer" },
{ title: "Elements", navigateTo: "ElementsDrawer" },
{ title: "Articles", navigateTo: "ArticlesDrawer" },
{ title: "Settings", navigateTo: "SettingsDrawer" },
];
return (
<Block
style={styles.container}
forceInset={{ top: "always", horizontal: "never" }}
>
{/* 品牌头部 - 黑金主题 */}
<Box bg="#000" px={4} py={5} style={{ paddingTop: insets.top + 16 }}>
<HStack alignItems="center" space={3}>
<Image
source={Images.Logo}
style={{ width: 40, height: 40, borderRadius: 10 }}
resizeMode="contain"
/>
<VStack>
<Text style={{ color: GOLD_PRIMARY, fontFamily: "open-sans-bold", fontSize: 18 }}>
价值前沿
</Text>
<Text style={{ color: "rgba(212, 175, 55, 0.6)", fontFamily: "open-sans-regular", fontSize: 11 }}>
VALUE FRONTIER
</Text>
</VStack>
</HStack>
</Box>
<Block flex style={{ paddingLeft: 8, paddingRight: 14 }}>
<ScrollView style={{ flex: 1 }} showsVerticalScrollIndicator={false}>
{/* 用户卡片 */}
<Box mt={3}>
<UserCard navigation={navigation} />
</Box>
{screens.map((item, index) => {
return (
<DrawerCustomItem
title={item?.title}
key={index}
navigation={navigation}
focused={state.index === index ? true : false}
navigateTo={item?.navigateTo}
/>
);
})}
<Block
flex
style={{ marginTop: 24, marginVertical: 8, paddingHorizontal: 8 }}
>
<Block
style={{
borderColor: "rgba(0,0,0,0.2)",
width: "100%",
borderWidth: StyleSheet.hairlineWidth,
}}
/>
<Text
color="#8898AA"
style={{
marginTop: 16,
marginLeft: 8,
fontFamily: "open-sans-regular",
}}
>
DOCUMENTATION
</Text>
</Block>
<DrawerCustomItem title="Getting Started" navigation={navigation} />
</ScrollView>
</Block>
</Block>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
header: {
paddingHorizontal: 28,
paddingBottom: theme.SIZES.BASE,
paddingTop: theme.SIZES.BASE * 3,
justifyContent: "center",
},
});
export default CustomDrawerContent;

View File

@@ -0,0 +1,670 @@
import { Animated, Dimensions, Easing } from "react-native";
// header for screens
import { Header, Icon } from "../components";
import { argonTheme, tabs } from "../constants";
import AboutScreen from "../screens/About";
import AgreementScreen from "../screens/Agreement";
import Articles from "../screens/Articles";
import Beauty from "../screens/Beauty";
import Cart from "../screens/Cart";
import Category from "../screens/Category";
import Chat from "../screens/Chat";
// drawer
import CustomDrawerContent from "./Menu";
import Elements from "../screens/Elements";
import Fashion from "../screens/Fashion";
import Gallery from "../screens/Gallery";
// screens
import Home from "../screens/Home";
import NotificationsScreen from "../screens/Notifications";
// Notifications
import PersonalNotifications from "../screens/PersonalNotifications";
import PrivacyScreen from "../screens/Privacy";
// import Onboarding from "../screens/Onboarding";
import Pro from "../screens/Pro";
import Product from "../screens/Product";
import Profile from "../screens/Profile";
import React from "react";
import Register from "../screens/Register";
import Search from "../screens/Search";
// settings
import SettingsScreen from "../screens/Settings";
import SystemNotifications from "../screens/SystemNotifications";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { createDrawerNavigator } from "@react-navigation/drawer";
import { createStackNavigator } from "@react-navigation/stack";
// 事件中心页面
import { EventList, EventDetail } from "../src/screens/Events";
// 市场热点页面
import { MarketHot, SectorDetail, EventCalendar, StockDetail, TodayStats } from "../src/screens/Market";
// 认证页面
import { LoginScreen } from "../src/screens/Auth";
const { width } = Dimensions.get("screen");
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const Tab = createBottomTabNavigator();
function NotificationsStack(props) {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color }) => {
let iconName;
if (route.name === "Personal") {
iconName = "user";
} else if (route.name === "System") {
iconName = "database";
}
// You can return any component that you like here!
return (
<Icon
name={iconName}
family="entypo"
size={22}
color={color}
style={{ marginTop: 10 }}
/>
);
},
})}
tabBarOptions={{
activeTintColor: argonTheme.COLORS.PRIMARY,
inactiveTintColor: "gray",
labelStyle: {
fontFamily: "open-sans-regular",
},
}}
>
<Tab.Screen name="Personal" component={PersonalNotifications} />
<Tab.Screen name="System" component={SystemNotifications} />
</Tab.Navigator>
);
}
function ElementsStack(props) {
return (
<Stack.Navigator
screenOptions={{
mode: "card",
headerShown: "screen",
}}
>
<Stack.Screen
name="Elements"
component={Elements}
options={{
header: ({ navigation, scene }) => (
<Header title="Elements" navigation={navigation} scene={scene} />
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
</Stack.Navigator>
);
}
function SettingsStack(props) {
return (
<Stack.Navigator
screenOptions={{
mode: "card",
headerShown: "screen",
}}
>
<Stack.Screen
name="Settings"
component={SettingsScreen}
options={{
header: ({ navigation, scene }) => (
<Header title="Settings" scene={scene} navigation={navigation} />
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Agreement"
component={AgreementScreen}
options={{
header: ({ navigation, scene }) => (
<Header
back
title="Agreement"
scene={scene}
navigation={navigation}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Privacy"
component={PrivacyScreen}
options={{
header: ({ navigation, scene }) => (
<Header
back
title="Privacy"
scene={scene}
navigation={navigation}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="About"
component={AboutScreen}
options={{
header: ({ navigation, scene }) => (
<Header back title="关于我们" scene={scene} navigation={navigation} />
),
cardStyle: { backgroundColor: "#0F172A" },
}}
/>
<Stack.Screen
name="NotificationsSettings"
component={NotificationsScreen}
options={{
header: ({ navigation, scene }) => (
<Header
back
title="Notifications"
scene={scene}
navigation={navigation}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Cart"
component={Cart}
options={{
header: ({ navigation, scene }) => (
<Header
back
title="Shopping Cart"
scene={scene}
navigation={navigation}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Notifications"
component={NotificationsStack}
options={{
header: ({ navigation, scene }) => (
<Header
back
title="Notifications"
scene={scene}
navigation={navigation}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
</Stack.Navigator>
);
}
function ArticlesStack(props) {
return (
<Stack.Navigator
screenOptions={{
mode: "card",
headerShown: "screen",
}}
>
<Stack.Screen
name="Articles"
component={Articles}
options={{
header: ({ navigation, scene }) => (
<Header title="Articles" navigation={navigation} scene={scene} />
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
</Stack.Navigator>
);
}
// 事件中心导航栈
function EventsStack(props) {
return (
<Stack.Navigator
screenOptions={{
mode: "card",
headerShown: false, // 隐藏默认header使用自定义
}}
>
<Stack.Screen
name="EventList"
component={EventList}
options={{
cardStyle: { backgroundColor: "#0F172A" },
}}
/>
<Stack.Screen
name="EventDetail"
component={EventDetail}
options={{
cardStyle: { backgroundColor: "#0F172A" },
}}
/>
</Stack.Navigator>
);
}
// 市场热点导航栈
function MarketStack(props) {
return (
<Stack.Navigator
screenOptions={{
mode: "card",
headerShown: false, // 使用自定义header
}}
>
<Stack.Screen
name="MarketHot"
component={MarketHot}
options={{
cardStyle: { backgroundColor: "#0F172A" },
}}
/>
<Stack.Screen
name="SectorDetail"
component={SectorDetail}
options={({ route }) => ({
header: ({ navigation, scene }) => (
<Header
title={route.params?.sectorName || "板块详情"}
back
navigation={navigation}
scene={scene}
/>
),
headerShown: true,
cardStyle: { backgroundColor: "#0F172A" },
})}
/>
<Stack.Screen
name="EventCalendar"
component={EventCalendar}
options={{
cardStyle: { backgroundColor: "#0F172A" },
}}
/>
<Stack.Screen
name="StockDetail"
component={StockDetail}
options={{
cardStyle: { backgroundColor: "#0F172A" },
}}
/>
<Stack.Screen
name="TodayStats"
component={TodayStats}
options={{
cardStyle: { backgroundColor: "#0F172A" },
}}
/>
</Stack.Navigator>
);
}
function ProfileStack(props) {
return (
<Stack.Navigator
initialRouteName="Profile"
screenOptions={{
mode: "card",
headerShown: "screen",
}}
>
<Stack.Screen
name="Profile"
component={Profile}
options={{
header: ({ navigation, scene }) => (
<Header
transparent
white
title="Profile"
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#FFFFFF" },
headerTransparent: true,
}}
/>
<Stack.Screen
name="Cart"
component={Cart}
options={{
header: ({ navigation, scene }) => (
<Header
back
title="Shopping Cart"
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#FFFFFF" },
}}
/>
<Stack.Screen
name="Notifications"
component={NotificationsStack}
options={{
header: ({ navigation, scene }) => (
<Header
back
title="Notifications"
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#FFFFFF" },
}}
/>
</Stack.Navigator>
);
}
function HomeStack(props) {
return (
<Stack.Navigator
screenOptions={{
mode: "card",
headerShown: "screen",
}}
>
<Stack.Screen
name="Home"
component={Home}
options={{
header: ({ navigation, scene }) => (
<Header
title="Home"
search
options
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Beauty"
component={Beauty}
options={{
header: ({ navigation, scene }) => (
<Header
title="Beauty"
back
tabs={tabs.beauty}
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Category"
component={Category}
options={{
header: ({ navigation, scene }) => {
const { params } = scene.descriptor;
const title = (params && params.headerTitle) || "Category";
return (
<Header
title={title}
back
navigation={navigation}
scene={scene}
/>
);
},
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Fashion"
component={Fashion}
options={{
header: ({ navigation, scene }) => (
<Header
title="Fashion"
back
tabs={tabs.fashion}
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Product"
component={Product}
options={{
header: ({ navigation, scene }) => (
<Header
title=""
back
white
transparent
navigation={navigation}
scene={scene}
/>
),
headerTransparent: true,
}}
/>
<Stack.Screen
name="Gallery"
component={Gallery}
options={{
header: ({ navigation, scene }) => (
<Header
back
transparent
white
title=""
navigation={navigation}
scene={scene}
/>
),
headerTransparent: true,
}}
/>
<Stack.Screen
name="Chat"
component={Chat}
options={{
header: ({ navigation, scene }) => (
<Header
title="Rachel Brown"
back
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Search"
component={Search}
options={{
header: ({ navigation, scene }) => (
<Header title="Search" back navigation={navigation} scene={scene} />
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Cart"
component={Cart}
options={{
header: ({ navigation, scene }) => (
<Header
title="Shopping Cart"
back
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
<Stack.Screen
name="Notifications"
component={NotificationsStack}
options={{
header: ({ navigation, scene }) => (
<Header
title="Notifications"
back
navigation={navigation}
scene={scene}
/>
),
cardStyle: { backgroundColor: "#F8F9FE" },
}}
/>
</Stack.Navigator>
);
}
function AppStack(props) {
return (
<Drawer.Navigator
style={{ flex: 1 }}
drawerContent={(props) => <CustomDrawerContent {...props} />}
drawerStyle={{
backgroundColor: "white",
width: width * 0.8,
}}
screenOptions={{
activeTintcolor: "white",
inactiveTintColor: "#000",
activeBackgroundColor: "transparent",
itemStyle: {
width: width * 0.75,
backgroundColor: "transparent",
paddingVertical: 16,
paddingHorizonal: 12,
justifyContent: "center",
alignContent: "center",
alignItems: "center",
overflow: "hidden",
},
labelStyle: {
fontSize: 18,
marginLeft: 12,
fontWeight: "normal",
},
}}
initialRouteName="EventsDrawer"
>
<Drawer.Screen
name="EventsDrawer"
component={EventsStack}
options={{
headerShown: false,
}}
/>
<Drawer.Screen
name="MarketDrawer"
component={MarketStack}
options={{
headerShown: false,
}}
/>
<Drawer.Screen
name="HomeDrawer"
component={HomeStack}
options={{
headerShown: false,
}}
/>
<Drawer.Screen
name="ProfileDrawer"
component={ProfileStack}
options={{
headerShown: false,
}}
/>
<Drawer.Screen
name="AccountDrawer"
component={Register}
options={{
headerShown: false,
}}
/>
<Drawer.Screen
name="ElementsDrawer"
component={ElementsStack}
options={{
headerShown: false,
}}
/>
<Drawer.Screen
name="ArticlesDrawer"
component={ArticlesStack}
options={{
headerShown: false,
}}
/>
<Drawer.Screen
name="SettingsDrawer"
component={SettingsStack}
options={{
headerShown: false,
}}
/>
</Drawer.Navigator>
);
}
export default function OnboardingStack(props) {
return (
<Stack.Navigator
screenOptions={{
mode: "card",
headerShown: false,
}}
>
<Stack.Screen
name="Onboarding"
component={Pro}
option={{
headerTransparent: true,
}}
/>
<Stack.Screen name="App" component={AppStack} />
<Stack.Screen
name="Login"
component={LoginScreen}
options={{
presentation: "modal",
headerShown: false,
}}
/>
</Stack.Navigator>
);
}

View File

@@ -0,0 +1,72 @@
{
"name": "valuefrontier-app",
"version": "1.0.0",
"description": "价值前沿 - 智能投资决策平台",
"main": "index.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject"
},
"repository": {
"type": "git",
"url": "git+https://github.com/creativetimofficial/argon-pro-react-native.git"
},
"dependencies": {
"@react-native-async-storage/async-storage": "1.23.1",
"@react-native-masked-view/masked-view": "0.3.1",
"@react-navigation/bottom-tabs": "^6.3.1",
"@react-navigation/drawer": "6.4.1",
"@react-navigation/native": "^6.0.10",
"@react-navigation/stack": "^6.2.1",
"@reduxjs/toolkit": "^2.2.0",
"babel-plugin-module-resolver": "^5.0.0",
"expo": "~51.0.28",
"expo-asset": "~10.0.10",
"expo-blur": "~13.0.3",
"expo-font": "~12.0.10",
"expo-linear-gradient": "~13.0.2",
"expo-modules-core": "~1.12.24",
"expo-splash-screen": "~0.27.5",
"galio-framework": "^0.8.0",
"native-base": "^3.4.28",
"prop-types": "^15.7.2",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.74.5",
"react-native-gesture-handler": "~2.16.1",
"react-native-modal-dropdown": "1.0.2",
"react-native-reanimated": "~3.10.1",
"react-native-safe-area-context": "4.10.5",
"react-native-screens": "3.31.1",
"react-native-svg": "15.2.0",
"react-redux": "^9.1.0"
},
"devDependencies": {
"babel-preset-expo": "~11.0.0"
},
"keywords": [
"argon react native",
"argon design system",
"argon app react native",
"argon iOS",
"react native iOS",
"creative tim",
"argon Android",
"react native ui kit",
"react native expo",
"freebie",
"react native argon design",
"react native galio",
"galio argon pro",
"galio react native free app",
"argon expo react native",
"react native ui template"
],
"author": "Creative Tim <hello@creative-tim.com> (https://www.creative-tim.com/)",
"bugs": {
"url": "https://github.com/creativetimofficial/ct-argon-pro-react-native/issues"
},
"homepage": "https://demos.creative-tim.com/argon-pro-react-native"
}

View File

@@ -0,0 +1,163 @@
/**
* 关于页面 - 价值前沿
*/
import React from "react";
import { ScrollView, StyleSheet, Image, Dimensions } from "react-native";
import { Box, VStack, HStack, Text, Center, Icon } from "native-base";
import { LinearGradient } from "expo-linear-gradient";
import { Ionicons } from "@expo/vector-icons";
const { width } = Dimensions.get("window");
// 金色主题
const GOLD_PRIMARY = '#D4AF37';
const GOLD_GRADIENT = ['#D4AF37', '#F5D77A', '#D4AF37'];
const FeatureItem = ({ icon, title, description }) => (
<HStack
bg="rgba(212, 175, 55, 0.08)"
borderWidth={1}
borderColor="rgba(212, 175, 55, 0.15)"
rounded="xl"
p={4}
space={3}
alignItems="center"
mb={3}
>
<Box
bg="rgba(212, 175, 55, 0.15)"
rounded="lg"
p={2}
>
<Icon as={Ionicons} name={icon} size="md" color={GOLD_PRIMARY} />
</Box>
<VStack flex={1}>
<Text fontSize="sm" fontWeight="bold" color="white">
{title}
</Text>
<Text fontSize="xs" color="gray.400">
{description}
</Text>
</VStack>
</HStack>
);
export default function About() {
return (
<Box flex={1} bg="#0F172A">
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.container}
>
{/* Logo 区域 */}
<Center mb={6}>
<Box
bg="rgba(212, 175, 55, 0.1)"
borderWidth={1}
borderColor="rgba(212, 175, 55, 0.2)"
rounded="2xl"
p={4}
mb={4}
>
<Image
source={require("../assets/logo.jpg")}
style={{ width: 80, height: 80 }}
resizeMode="contain"
/>
</Box>
<Text fontSize="2xl" fontWeight="bold" color={GOLD_PRIMARY}>
价值前沿
</Text>
<Text fontSize="sm" color="rgba(212, 175, 55, 0.7)" mt={1}>
VALUE FRONTIER
</Text>
<Text fontSize="xs" color="gray.500" mt={2}>
Version 1.0.0
</Text>
</Center>
{/* 介绍文字 */}
<Box
bg="rgba(30, 41, 59, 0.6)"
borderWidth={1}
borderColor="rgba(255, 255, 255, 0.08)"
rounded="2xl"
p={4}
mb={6}
>
<Text fontSize="sm" color="gray.300" lineHeight="xl" textAlign="center">
价值前沿是一款专注于A股市场的智能投资决策平台
通过实时追踪市场事件分析板块热点
帮助投资者发现市场机会做出更明智的投资决策
</Text>
</Box>
{/* 核心功能 */}
<Text fontSize="md" fontWeight="bold" color="white" mb={3}>
核心功能
</Text>
<FeatureItem
icon="flash"
title="事件中心"
description="实时追踪市场重大事件,分析事件影响力和相关股票表现"
/>
<FeatureItem
icon="flame"
title="市场热点"
description="智能分析板块热度,发现市场主线和投资机会"
/>
<FeatureItem
icon="analytics"
title="数据分析"
description="提供专业的行情数据和技术指标分析工具"
/>
<FeatureItem
icon="notifications"
title="智能提醒"
description="关键事件和异动股票的实时推送通知"
/>
{/* 联系信息 */}
<Box mt={6}>
<Text fontSize="md" fontWeight="bold" color="white" mb={3}>
联系我们
</Text>
<Box
bg="rgba(30, 41, 59, 0.6)"
borderWidth={1}
borderColor="rgba(255, 255, 255, 0.08)"
rounded="2xl"
p={4}
>
<HStack alignItems="center" space={2} mb={2}>
<Icon as={Ionicons} name="globe-outline" size="sm" color="gray.400" />
<Text fontSize="sm" color="gray.300">www.valuefrontier.cn</Text>
</HStack>
<HStack alignItems="center" space={2}>
<Icon as={Ionicons} name="mail-outline" size="sm" color="gray.400" />
<Text fontSize="sm" color="gray.300">support@valuefrontier.cn</Text>
</HStack>
</Box>
</Box>
{/* 版权信息 */}
<Center mt={8} mb={4}>
<Text fontSize="xs" color="gray.600">
Copyright 2024 Value Frontier
</Text>
<Text fontSize="xs" color="gray.600">
All rights reserved.
</Text>
</Center>
</ScrollView>
</Box>
);
}
const styles = StyleSheet.create({
container: {
padding: 20,
},
});

View File

@@ -0,0 +1,60 @@
import React from "react";
import { ScrollView, StyleSheet } from "react-native";
import { Block, Text, theme } from "galio-framework";
import argonTheme from "../constants/Theme";
export default class Agreement extends React.Component {
render() {
return (
<Block flex style={{ position: "relative" }}>
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.agreements}
overScrollMode="always"
>
<Text style={{ fontFamily: 'open-sans-bold' }} size={16} color={argonTheme.COLORS.TEXT}>
It all started in the early 1970s, when, floundering a bit in her
post-college life, she landed a gig at WBFO, a radio station in
Buffalo. There she would call subjects and interview them for the
program she hosted, This Is Radio. She moved to Philadelphia in
1975 to host Fresh Air, the brainchild of a colleague from WBFO.
</Text>
<Text
style={{ fontFamily: 'open-sans-regular' }}
size={16}
color={argonTheme.COLORS.TEXT}
style={{ paddingTop: 9 }}
>
Ms. Gross brings a combination of empathy and rigorous preparation
to the job. I read, watch or listen to as much of the persons work
as possible, so I have an understanding of what makes them, or their
story, important, she said. I try to clarify in my own mind why
this person matters, and why its worthy of our listeners time.
</Text>
<Text
style={{ fontFamily: 'open-sans-regular' }}
size={16}
color={argonTheme.COLORS.TEXT}
style={{ paddingTop: 9 }}
>
One thing she does not allow of her interview subjects, however, is
input on the edit. When the interview is over, you dont have a
chance to call back and say, Well I like my answer to this, I dont
like my answer to that, can you edit that out, she said. (As
someone who has been interviewed by Ms. Gross, I would like to say
that I wish I hadnt insisted that her cats hate her. That said, I
never asked for my comment to be removed from that particular
episode of Fresh Air.)
</Text>
</ScrollView>
</Block>
);
}
}
const styles = StyleSheet.create({
agreements: {
padding: theme.SIZES.BASE
}
});

View File

@@ -0,0 +1,254 @@
import React from "react";
import {
ScrollView,
StyleSheet,
Image,
TouchableWithoutFeedback,
ImageBackground,
Dimensions
} from "react-native";
//galio
import { Block, Text, theme } from "galio-framework";
//argon
import { articles, Images, argonTheme } from "../constants/";
import { Card, Button } from "../components/";
const { width } = Dimensions.get("screen");
const thumbMeasure = (width - 48 - 32) / 3;
const cardWidth = width - theme.SIZES.BASE * 2;
const categories = [
{
title: "Music Album",
description:
"Rock music is a genre of popular music. It developed during and after the 1960s in the United Kingdom.",
image:
"https://images.unsplash.com/photo-1470225620780-dba8ba36b745?fit=crop&w=840&q=80",
price: "$125"
},
{
title: "Events",
description:
"Rock music is a genre of popular music. It developed during and after the 1960s in the United Kingdom.",
image:
"https://images.unsplash.com/photo-1543747579-795b9c2c3ada?fit=crop&w=840&q=80",
price: "$35"
}
];
class Articles extends React.Component {
renderProduct = (item, index) => {
const { navigation } = this.props;
return (
<TouchableWithoutFeedback
style={{ zIndex: 3 }}
key={`product-${item.title}`}
onPress={() => navigation.navigate("Pro", { product: item })}
>
<Block center style={styles.productItem}>
<Image
resizeMode="cover"
style={styles.productImage}
source={{ uri: item.image }}
/>
<Block center style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Text
center
size={16}
color="#525F7F"
style={styles.productPrice}
>
{item.price}
</Text>
<Text style={{ fontFamily: 'open-sans-regular' }} center size={34} color={argonTheme.COLORS.TEXT}>
{item.title}
</Text>
<Text
center
size={16}
color={argonTheme.COLORS.MUTED}
style={styles.productDescription}
>
{item.description}
</Text>
</Block>
</Block>
</TouchableWithoutFeedback>
);
};
renderCards = () => {
return (
<Block flex style={styles.group}>
<Text size={16} style={styles.title}>
Cards
</Text>
<Block flex>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Card item={articles[0]} horizontal />
<Block flex row>
<Card
item={articles[1]}
style={{ marginRight: theme.SIZES.BASE }}
/>
<Card item={articles[2]} />
</Block>
<Card item={articles[4]} full />
<Block flex card shadow style={styles.category}>
<ImageBackground
source={{ uri: Images.Products["View article"] }}
style={[
styles.imageBlock,
{ width: width - theme.SIZES.BASE * 2, height: 252 }
]}
imageStyle={{
width: width - theme.SIZES.BASE * 2,
height: 252
}}
>
<Block style={styles.categoryTitle}>
<Text style={{ fontFamily: 'open-sans-bold' }} size={18} color={theme.COLORS.WHITE}>
View article
</Text>
</Block>
</ImageBackground>
</Block>
</Block>
<Block flex style={{ marginTop: theme.SIZES.BASE / 2 }}>
<ScrollView
horizontal={true}
pagingEnabled={true}
decelerationRate={0}
scrollEventThrottle={16}
snapToAlignment="center"
showsHorizontalScrollIndicator={false}
snapToInterval={cardWidth + theme.SIZES.BASE * 0.375}
contentContainerStyle={{
paddingHorizontal: theme.SIZES.BASE / 2
}}
>
{categories &&
categories.map((item, index) =>
this.renderProduct(item, index)
)}
</ScrollView>
</Block>
</Block>
</Block>
);
};
renderAlbum = () => {
const { navigation } = this.props;
return (
<Block
flex
style={[styles.group, { paddingBottom: theme.SIZES.BASE * 5 }]}
>
<Block style={{ marginHorizontal: theme.SIZES.BASE * 2 }}>
<Block row space="between">
<Text bold size={16} color="#525F7F" style={{ marginTop: 3 }}>
Album
</Text>
<Button
small
color="transparent"
textStyle={{ color: "#5E72E4", fontSize: 14 }}
>
View All
</Button>
</Block>
<Block
row
space="between"
style={{ marginTop: theme.SIZES.BASE, flexWrap: "wrap" }}
>
{Images.Viewed.map((img, index) => (
<Block key={`viewed-${img}`} style={styles.shadow}>
<Image
resizeMode="cover"
source={{ uri: img }}
style={styles.albumThumb}
/>
</Block>
))}
</Block>
</Block>
</Block>
);
};
render() {
return (
<Block flex center>
<ScrollView showsVerticalScrollIndicator={false}>
{this.renderCards()}
{this.renderAlbum()}
</ScrollView>
</Block>
);
}
}
const styles = StyleSheet.create({
title: {
paddingBottom: theme.SIZES.BASE,
paddingHorizontal: theme.SIZES.BASE * 2,
marginTop: 22,
color: argonTheme.COLORS.HEADER,
fontFamily: 'open-sans-bold'
},
group: {
paddingTop: theme.SIZES.BASE
},
albumThumb: {
borderRadius: 4,
marginVertical: 4,
alignSelf: "center",
width: thumbMeasure,
height: thumbMeasure
},
category: {
backgroundColor: theme.COLORS.WHITE,
marginVertical: theme.SIZES.BASE / 2,
borderWidth: 0
},
categoryTitle: {
height: "100%",
paddingHorizontal: theme.SIZES.BASE,
backgroundColor: "rgba(0, 0, 0, 0.5)",
justifyContent: "center",
alignItems: "center"
},
imageBlock: {
overflow: "hidden",
borderRadius: 4
},
productItem: {
width: cardWidth - theme.SIZES.BASE * 2,
marginHorizontal: theme.SIZES.BASE,
shadowColor: "black",
shadowOffset: { width: 0, height: 7 },
shadowRadius: 10,
shadowOpacity: 0.2
},
productImage: {
width: cardWidth - theme.SIZES.BASE,
height: cardWidth - theme.SIZES.BASE,
borderRadius: 3
},
productPrice: {
paddingTop: theme.SIZES.BASE,
paddingBottom: theme.SIZES.BASE / 2,
fontFamily: 'open-sans-bold'
},
productDescription: {
paddingTop: theme.SIZES.BASE,
fontFamily: 'open-sans-regular'
// paddingBottom: theme.SIZES.BASE * 2,
}
});
export default Articles;

View File

@@ -0,0 +1,123 @@
import React from "react";
import {
StyleSheet,
Dimensions,
ImageBackground,
ScrollView,
TouchableWithoutFeedback
} from "react-native";
import { Block, Text, theme } from "galio-framework";
import Images from "../constants/Images";
const { width } = Dimensions.get("screen");
const menuCategories = {
music: [
{ id: "artists", title: "Artists", image: Images.Music["Artists"] },
{ id: "concerts", title: "Concerts", image: Images.Music["Concerts"] },
{ id: "DJs", title: "DJs", image: Images.Music["DJs"] }
],
beauty: [
{ id: "hands", title: "Hands", image: Images.Music["Hands"] },
{ id: "body", title: "Body", image: Images.Music["Body"] },
{ id: "face", title: "Face", image: Images.Music["Face"] }
],
fashion: [
{ id: "trends", title: "Trends", image: Images.Music["Trends"] },
{ id: "clothes", title: "Clothes", image: Images.Music["Clothes"] },
{ id: "accessory", title: "Accessory", image: Images.Music["Accessory"] }
],
clothes: [
{ id: "fashion", title: "Fashion", image: Images.Music["Fashion"] },
{ id: "garagesale", title: "Garage Sale", image: Images.Music["Garage_sale"] },
{ id: "weddingdress", title: "Wedding Dress", image: Images.Music["Wedding_dress"] }
]
};
export default class Categories extends React.Component {
renderCategories = () => {
const { navigation, route } = this.props;
// const tabId = navigation.getParam("tabId");
// const categories = tabId ? menuCategories[tabId] : menuCategories.beauty;
const tabId = route.params?.tabId;
const categories = tabId ? menuCategories[tabId] : menuCategories.beauty;
return (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.categoryList}
>
<Block flex>
{categories.map(category => (
<TouchableWithoutFeedback
key={`category-${category.id}`}
onPress={() => navigation.navigate("Category", { ...category })}
>
<Block flex card style={[styles.category, styles.shadow]}>
<ImageBackground
source={{ uri: category.image }}
style={[
styles.imageBlock,
{ width: width - theme.SIZES.BASE * 2, height: 252 }
]}
imageStyle={{
width: width - theme.SIZES.BASE * 2,
height: 252
}}
>
<Block style={styles.categoryTitle}>
<Text style={{ fontFamily: 'open-sans-bold' }} size={18} color={theme.COLORS.WHITE}>
{category.title}
</Text>
</Block>
</ImageBackground>
</Block>
</TouchableWithoutFeedback>
))}
</Block>
</ScrollView>
);
};
render() {
return (
<Block flex center style={styles.categories}>
{this.renderCategories()}
</Block>
);
}
}
const styles = StyleSheet.create({
categories: {
width
},
categoryList: {
justifyContent: "center",
paddingTop: theme.SIZES.BASE * 1.5
},
category: {
backgroundColor: theme.COLORS.WHITE,
marginHorizontal: theme.SIZES.BASE,
marginVertical: theme.SIZES.BASE / 2,
borderWidth: 0
},
categoryTitle: {
height: "100%",
paddingHorizontal: theme.SIZES.BASE,
backgroundColor: "rgba(0, 0, 0, 0.5)",
justifyContent: "center",
alignItems: "center"
},
imageBlock: {
overflow: "hidden",
borderRadius: 4
},
shadow: {
shadowColor: theme.COLORS.BLACK,
shadowOffset: { width: 0, height: 2 },
shadowRadius: 3,
shadowOpacity: 0.1,
elevation: 2
}
});

View File

@@ -0,0 +1,394 @@
import React from "react";
import {
StyleSheet,
Dimensions,
Image,
FlatList,
TouchableWithoutFeedback
} from "react-native";
import { Block, Text, theme } from "galio-framework";
// butoane text mai gros ca la register screen
import { Card, Select, Button } from "../components/";
import { argonTheme } from "../constants/";
import { cart } from "../constants";
const { width } = Dimensions.get("screen");
export default class Cart extends React.Component {
state = {
cart: cart.products
};
handleQuantity = (id, qty) => {
const { cart } = this.state;
const updatedCart = cart.map(product => {
if (product.id === id) product.qty = qty;
return product;
});
this.setState({ cart: updatedCart });
};
handleDelete = id => {
const { cart } = this.state;
const updatedCart = cart.filter(product => product.id !== id);
this.setState({ cart: updatedCart });
};
handleAdd = item => {
const { cart } = this.state;
cart.push({
...item,
id: cart.length + 1,
stock: true,
qty: 1
});
this.setState({ cart });
};
renderProduct = ({ item }) => {
const { navigation } = this.props;
return (
<Block>
<Block card shadow style={styles.product}>
<Block flex row>
<TouchableWithoutFeedback
onPress={() => navigation.navigate("Product", { product: item })}
>
<Block style={styles.imageHorizontal}>
<Image
source={{ uri: item.image }}
style={{
height: theme.SIZES.BASE * 5,
marginTop: -theme.SIZES.BASE,
borderRadius: 3
}}
/>
</Block>
</TouchableWithoutFeedback>
<Block flex style={styles.productDescription}>
<TouchableWithoutFeedback
onPress={() =>
navigation.navigate("Product", { product: item })
}
>
<Text size={14} style={styles.productTitle} color={argonTheme.COLORS.TEXT}>
{item.title}
</Text>
</TouchableWithoutFeedback>
<Block flex row space="between">
<Block bottom>
<Text
style={{ fontFamily: 'open-sans-regular' }}
size={theme.SIZES.BASE * 0.75}
color={argonTheme.COLORS[item.stock ? "SUCCESS" : "ERROR"]}
>
{item.stock ? "In Stock" : "Out of Stock"}
</Text>
</Block>
<Block bottom>
<Text
style={{ fontFamily: 'open-sans-regular' }}
size={theme.SIZES.BASE * 0.75}
color={argonTheme.COLORS.ACTIVE}
>
${item.price * item.qty}
</Text>
</Block>
</Block>
</Block>
</Block>
<Block flex row space="between" style={styles.options}>
<Block style={{marginTop: 8}}>
<Select
defaultIndex={1}
disabled={!item.stock}
options={[1, 2, 3, 4, 5]}
onSelect={(index, value) => this.handleQuantity(item.id, value)}
/>
</Block>
<Button
center
shadowless
color="default"
textStyle={styles.optionsButtonText}
style={styles.optionsButton}
onPress={() => this.handleDelete(item.id)}
>
DELETE
</Button>
<Button
center
shadowless
color="default"
textStyle={styles.optionsButtonText}
style={styles.optionsButton}
onPress={() => console.log("save for later")}
>
SAVE FOR LATER
</Button>
</Block>
</Block>
</Block>
);
};
renderHorizontalProduct = ({ item }) => {
const buttonStyles = {
...styles.optionsButton,
marginTop: 5
};
return (
<Block style={{ marginRight: theme.SIZES.BASE }}>
<Card
item={item}
imageStyle={{ width: "auto", height: 94 }}
style={{ width: width / 2.88 }}
/>
<Button
center
shadowless
color="active"
style={buttonStyles}
textStyle={[styles.optionsButtonText, { color: "white" }]}
onPress={() => this.handleAdd(item)}
>
ADD TO CART
</Button>
</Block>
);
};
renderHorizontalProducts = () => {
return (
<Block style={{ marginHorizontal: theme.SIZES.BASE }}>
<Text bold size={theme.SIZES.BASE} style={styles.similarTitle} color={argonTheme.COLORS.TEXT}>
Customers who shopped for items in your cart also shopped for:
</Text>
<FlatList
data={cart.suggestions}
horizontal={true}
showsHorizontalScrollIndicator={false}
keyExtractor={(item, index) => `${index}-${item.title}`}
renderItem={this.renderHorizontalProduct}
/>
</Block>
);
};
renderHeader = () => {
const { navigation } = this.props;
const { cart } = this.state;
const productsQty = cart.length;
const total =
cart &&
cart.reduce((prev, product) => prev + product.price * product.qty, 0);
return (
<Block flex style={styles.header}>
<Block style={{ marginBottom: theme.SIZES.BASE * 2 }}>
<Text style={{ fontFamily: 'open-sans-regular' }} color={argonTheme.COLORS.TEXT}>
Cart subtotal ({productsQty} items):{" "}
<Text style={{ fontFamily: 'open-sans-bold' }} color={argonTheme.COLORS.ERROR}>
${total}
</Text>
</Text>
</Block>
<Block center>
<Button
flex
center
style={styles.checkout}
color="active"
onPress={() => navigation.navigate("Account")}
fontSize={14}
>
PROCEED TO CHECKOUT
</Button>
</Block>
</Block>
);
};
renderFooter = () => {
const { navigation } = this.props;
return (
<Block flex style={styles.footer}>
{this.renderHorizontalProducts()}
<Block style={{ marginHorizontal: theme.SIZES.BASE }}>
</Block>
<Block center style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Button
flex
center
style={styles.checkout}
color="active"
onPress={() => navigation.navigate("Account")}
fontSize={14}
>
PROCEED TO CHECKOUT
</Button>
</Block>
</Block>
);
};
renderEmpty() {
return <Text style={{ fontFamily: 'open-sans-regular' }} color={argonTheme.COLORS.ERROR}>The cart is empty</Text>;
}
renderCheckoutButton() {
const { navigation } = this.props;
return (
<Block center>
<Button
flex
center
style={styles.checkout}
color="active"
onPress={() => navigation.navigate("Account")}
fontSize={14}
>
PROCEED TO CHECKOUT
</Button>
</Block>
);
}
render() {
return (
<Block flex center style={styles.cart}>
<FlatList
data={this.state.cart}
renderItem={this.renderProduct}
showsVerticalScrollIndicator={false}
keyExtractor={(item, index) => `${index}-${item.title}`}
ListEmptyComponent={this.renderEmpty()}
ListHeaderComponent={this.renderHeader()}
ListFooterComponent={this.renderFooter()}
/>
</Block>
);
}
}
const styles = StyleSheet.create({
cart: {
width: width
},
header: {
marginTop: theme.SIZES.BASE,
marginHorizontal: theme.SIZES.BASE
},
footer: {
marginBottom: theme.SIZES.BASE * 2
},
divider: {
height: 1,
backgroundColor: argonTheme.COLORS.INPUT,
marginVertical: theme.SIZES.BASE
},
checkoutWrapper: {
paddingTop: theme.SIZES.BASE * 2,
margin: theme.SIZES.BASE,
borderStyle: "solid",
borderTopWidth: 1,
borderTopColor: argonTheme.COLORS.INPUT
},
products: {
minHeight: "100%"
},
product: {
width: width * 0.9,
borderWidth: 0,
marginVertical: theme.SIZES.BASE,
marginHorizontal: theme.SIZES.BASE,
backgroundColor: theme.COLORS.WHITE,
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: theme.SIZES.BASE / 4,
shadowOpacity: 0.1
},
productTitle: {
fontFamily: 'open-sans-regular',
flex: 1,
flexWrap: "wrap",
paddingBottom: 6
},
productDescription: {
padding: theme.SIZES.BASE / 2
},
imageHorizontal: {
width: theme.SIZES.BASE * 6.25,
margin: theme.SIZES.BASE / 2
},
options: {
padding: theme.SIZES.BASE / 2
},
qty: {
display: "flex",
justifyContent: "center",
alignContent: "center",
width: theme.SIZES.BASE * 6.25,
backgroundColor: argonTheme.COLORS.INPUT,
paddingHorizontal: theme.SIZES.BASE,
paddingVertical: 10,
borderRadius: 3,
shadowColor: "rgba(0, 0, 0, 0.1)",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 4,
shadowOpacity: 1
},
optionsButtonText: {
fontFamily: 'open-sans-bold',
fontSize: theme.SIZES.BASE * 0.75,
color: theme.COLORS.WHITE,
fontWeight: "normal",
fontStyle: "normal",
letterSpacing: -0.29
},
optionsButton: {
width: "auto",
height: 34,
paddingHorizontal: theme.SIZES.BASE,
paddingVertical: 10,
borderRadius: 3,
shadowColor: "rgba(0, 0, 0, 0.1)",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 4,
shadowOpacity: 1
},
checkout: {
height: theme.SIZES.BASE * 3,
width: width - theme.SIZES.BASE * 4,
shadowColor: "black",
shadowOffset: { width: 0, height: 4 },
shadowRadius: 8,
shadowOpacity: 0.2
},
similarTitle: {
lineHeight: 26,
marginBottom: theme.SIZES.BASE,
paddingHorizontal: theme.SIZES.BASE
},
productVertical: {
height: theme.SIZES.BASE * 10.75,
width: theme.SIZES.BASE * 8.125,
overflow: "hidden",
borderWidth: 0,
borderRadius: 4,
marginBottom: theme.SIZES.BASE,
backgroundColor: theme.COLORS.WHITE,
shadowColor: "rgba(0, 0, 0, 0.1)",
shadowOffset: {
width: 0,
height: 2
},
shadowRadius: theme.SIZES.BASE / 4,
shadowOpacity: 1
}
});

View File

@@ -0,0 +1,159 @@
import React from "react";
import {
Image,
StyleSheet,
ScrollView,
Dimensions,
TouchableWithoutFeedback
} from "react-native";
import { Block, Text, theme } from "galio-framework";
import { Card } from "../components/";
import categories from "../constants/categories";
import { argonTheme } from "../constants";
const { width } = Dimensions.get("window");
const cardWidth = width - theme.SIZES.BASE * 2;
export default class Category extends React.Component {
renderSuggestions = () => {
const { navigation, route } = this.props;
// const { params } = navigation && navigation.state;
// const category = categories[params.id];
// const suggestions = category && category.suggestions;
const category = categories[route.params?.id];
const suggestions = category && category.suggestions;
if (!suggestions) return null;
return (
<React.Fragment>
<Card item={suggestions[0]} style={{ marginRight: theme.SIZES.BASE }} />
<Card item={suggestions[1]} />
</React.Fragment>
);
};
renderCard = (item, index) => {
const { navigation } = this.props;
return (
<TouchableWithoutFeedback
key={`Card-${item.title}`}
onPress={() => navigation.navigate("Product", { product: item })}
>
<Block flex style={styles.Card}>
<Image
resizeMode="cover"
style={styles.image}
source={{ uri: item.image }}
/>
<Block center style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Text
center
size={16}
color="#525F7F"
style={styles.price}
>
$125
</Text>
<Text style={{ fontFamily: 'open-sans-regular' }} center size={34} color={argonTheme.COLORS.TEXT}>
{item.title}
</Text>
<Text
center
size={16}
color={argonTheme.COLORS.MUTED}
style={styles.description}
>
{item.description}
</Text>
</Block>
</Block>
</TouchableWithoutFeedback>
);
};
render() {
const { navigation, route } = this.props;
// const { params } = navigation && navigation.state;
// const category = categories[params.id];
const category = categories[route.params?.id];
return (
<Block flex>
<ScrollView
scrollEventThrottle={16}
showsVerticalScrollIndicator={false}
>
<Block flex={3}>
<ScrollView
horizontal={true}
pagingEnabled={true}
decelerationRate={0}
scrollEventThrottle={16}
snapToAlignment="center"
showsHorizontalScrollIndicator={false}
snapToInterval={cardWidth + theme.SIZES.BASE * 0.375}
contentContainerStyle={{ paddingRight: theme.SIZES.BASE }}
>
{category &&
category.images.map((item, index) =>
this.renderCard(item, index)
)}
</ScrollView>
</Block>
<Block flex row style={{ marginHorizontal: theme.SIZES.BASE }}>
{this.renderSuggestions()}
</Block>
</ScrollView>
</Block>
);
}
}
const styles = StyleSheet.create({
Card: {
width: cardWidth - theme.SIZES.BASE * 2,
marginHorizontal: theme.SIZES.BASE,
marginTop: theme.SIZES.BASE * 2,
shadowColor: "black",
shadowOffset: { width: 0, height: 7 },
shadowRadius: 10,
shadowOpacity: 0.2
},
image: {
width: cardWidth - theme.SIZES.BASE,
height: cardWidth - theme.SIZES.BASE,
borderRadius: 3
},
imageVertical: {
overflow: "hidden",
borderTopRightRadius: 4,
borderTopLeftRadius: 4
},
price: {
fontFamily: 'open-sans-bold',
paddingTop: theme.SIZES.BASE,
paddingBottom: theme.SIZES.BASE / 2
},
description: {
fontFamily: 'open-sans-regular',
paddingTop: theme.SIZES.BASE,
paddingBottom: theme.SIZES.BASE * 2
},
suggestion: {
backgroundColor: theme.COLORS.WHITE,
marginBottom: theme.SIZES.BASE,
borderWidth: 0,
marginLeft: theme.SIZES.BASE / 2,
marginRight: theme.SIZES.BASE / 2
},
suggestionTitle: {
flex: 1,
flexWrap: "wrap",
paddingBottom: 6
},
suggestionDescription: {
padding: theme.SIZES.BASE / 2
}
});

View File

@@ -0,0 +1,269 @@
import React from "react";
import {
View,
Image,
StyleSheet,
FlatList,
KeyboardAvoidingView
} from "react-native";
import { Input, Block, Text, theme } from "galio-framework";
import { Icon } from "../components/";
import Images from "../constants/Images";
import argonTheme from "../constants/Theme";
const messages = [
{
id: 1,
avatar: Images.ProfileChat,
message: `Hey there! How are you today? Can we me et and talk? Thanks!`,
time: `10:31 PM`
},
{
id: 2,
message: `Sure, just let me finish something and Ill call you.`,
time: `10:34 PM`
},
{
id: 3,
avatar: Images.ProfileChat,
message: `OK. Cool! See you!`,
time: `10:35 PM`
},
{
id: 4,
message: `Bye bye`,
time: `10:36 PM`
}
];
export default class Chat extends React.Component {
state = {
messages: messages,
height: 0
};
messagesScroll = React.createRef();
itemLayout = (data, index) => ({
length: this.state.messages.length - 1,
offset: 32 * index,
index
});
handleScroll = () => {
// const totalIndex = this.state.messages.length - 1;
// const insetBottom = this.state.messages.length * (theme.SIZES.BASE * 6.5) + 64; // total messages x message height
setTimeout(() => {
this.messagesScroll.current.scrollToOffset({ offset: this.state.height });
}, 1);
};
onContentSizeChange = (width, height) => {
this.setState({
height
});
};
componentDidMount() {
// this.handleScroll();
}
renderMessage = msg => {
if (msg.avatar) {
return (
<Block key={msg.id}>
<Block row space={null}>
<Image
source={{ uri: msg.avatar }}
style={[styles.avatar, styles.shadow]}
/>
<Block style={styles.messageCardWrapper}>
<Block style={[styles.messageCard, styles.shadow]}>
<Text style={{ fontFamily: 'open-sans-regular' }} color={argonTheme.COLORS.TEXT}>{msg.message}</Text>
</Block>
<Block right>
<Text style={styles.time}>{msg.time}</Text>
</Block>
</Block>
</Block>
</Block>
);
}
return (
<Block key={msg.id} right>
<Block row>
<Block style={styles.messageCardWrapper}>
<Block style={[styles.messageCardPersonal, styles.shadow]}>
<Text style={{ fontFamily: 'open-sans-regular' }} color={argonTheme.COLORS.WHITE}>{msg.message}</Text>
</Block>
<Block right>
<Text style={[styles.time, { marginRight: 8 }]}>{msg.time}</Text>
</Block>
</Block>
<Image
source={Images.ProfilePicture }
style={[styles.avatar, styles.shadow]}
/>
</Block>
</Block>
);
};
renderMessages = () => {
const insetBottom =
this.state.messages.length * (theme.SIZES.BASE * 6.5) + 64; // total messages x message height
return (
<FlatList
ref={this.messagesScroll}
data={this.state.messages}
keyExtractor={item => `${item.id}`}
showsVerticalScrollIndicator={false}
getItemLayout={this.itemLayout}
contentContainerStyle={[styles.messagesWrapper]}
renderItem={({ item }) => this.renderMessage(item)}
onContentSizeChange={this.onContentSizeChange}
/>
);
};
handleMessageChange = (type, text) => {
this.setState({ message: text });
};
handleMessage = () => {
const { messages, message } = this.state;
const date = new Date();
messages.push({
id: messages.length + 1,
message: message,
time: date.toLocaleString("en-US", { hour: "2-digit", minute: "numeric" })
});
this.setState({ messages, message: "" });
this.handleScroll();
};
messageForm = () => {
const { navigation } = this.props;
return (
<View style={styles.messageFormContainer}>
<Block>
<Input
borderless
color="#9fa5aa"
multiline
blurOnSubmit
style={styles.input}
placeholder="Message"
autoCapitalize="none"
returnKeyType="send"
textContentType="none"
placeholderTextColor="#9fa5aa"
defaultValue={this.state.message}
onSubmitEditing={this.handleMessage}
onChangeText={text => this.handleMessageChange("message", text)}
iconContent={
<Icon
size={14}
name="camera"
family="font-awesome"
color={argonTheme.COLORS.ICON}
style={{ marginRight: 12, marginTop: 5 }}
/>
}
/>
</Block>
</View>
);
};
render() {
return (
<Block flex space="between" style={styles.container}>
<KeyboardAvoidingView
enabled
behavior="padding"
style={{ flex: 1 }}
keyboardVerticalOffset={theme.SIZES.BASE * 5}
>
{this.renderMessages()}
{this.messageForm()}
</KeyboardAvoidingView>
</Block>
);
}
}
const styles = StyleSheet.create({
container: {},
messageFormContainer: {
height: 96,
paddingHorizontal: 16,
paddingTop: 16,
paddingBottom: 32
},
input: {
// width: width * 0.93,
height: theme.SIZES.BASE * 3,
backgroundColor: theme.COLORS.WHITE,
shadowColor: theme.COLORS.BLACK,
shadowOffset: { width: 0, height: 0.7 },
shadowRadius: 3,
shadowOpacity: 0.07,
elevation: 2,
},
iconButton: {
width: 40,
height: 40,
backgroundColor: "transparent"
},
messagesWrapper: {
flexGrow: 1,
top: 0,
paddingLeft: 8,
paddingRight: 8,
paddingVertical: 16,
paddingBottom: 56
},
messageCardWrapper: {
maxWidth: "85%",
marginLeft: 8,
marginBottom: 32
},
messageCard: {
paddingHorizontal: 8,
paddingVertical: 16,
borderRadius: 6,
backgroundColor: theme.COLORS.WHITE
},
messageCardPersonal: {
paddingHorizontal: 8,
paddingVertical: 16,
borderRadius: 6,
marginRight: 8,
backgroundColor: argonTheme.COLORS.PRIMARY
},
shadow: {
shadowColor: "rgba(0, 0, 0, 0.1)",
shadowOffset: { width: 0, height: 1 },
shadowRadius: 3,
shadowOpacity: 1
},
time: {
fontFamily: 'open-sans-regular',
fontSize: 11,
opacity: 0.5,
marginTop: 8
},
avatar: {
height: 40,
width: 40,
borderRadius: 20,
marginBottom: theme.SIZES.BASE
}
});

View File

@@ -0,0 +1,490 @@
import React from "react";
import {
ScrollView,
StyleSheet,
Dimensions,
TouchableOpacity
} from "react-native";
// Galio components
import { Block, Text, Button as GaButton, theme } from "galio-framework";
// Argon themed components
import { argonTheme, tabs } from "../constants/";
import { Button, Select, Icon, Input, Header, Switch } from "../components/";
const { width } = Dimensions.get("screen");
class Elements extends React.Component {
state = {
"switch-1": true,
"switch-2": false
};
toggleSwitch = switchId =>
this.setState({ [switchId]: !this.state[switchId] });
renderButtons = () => {
return (
<Block flex>
<Text size={16} style={styles.title}>
Buttons
</Text>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Block center>
<Button textStyle={{ fontFamily: 'open-sans-bold' }} color="default" style={styles.button}>
DEFAULT
</Button>
</Block>
<Block center>
<Button
color="secondary"
textStyle={{ fontFamily: 'open-sans-bold', color: "black" }}
style={styles.button}
>
SECONDARY
</Button>
</Block>
<Block center>
<Button textStyle={{ fontFamily: 'open-sans-bold' }} style={styles.button}>PRIMARY</Button>
</Block>
<Block center>
<Button textStyle={{ fontFamily: 'open-sans-bold' }} color="info" style={styles.button}>
INFO
</Button>
</Block>
<Block center>
<Button textStyle={{ fontFamily: 'open-sans-bold' }} color="success" style={styles.button}>
SUCCESS
</Button>
</Block>
<Block center>
<Button textStyle={{ fontFamily: 'open-sans-bold' }} color="warning" style={styles.button}>
WARNING
</Button>
</Block>
<Block center>
<Button textStyle={{ fontFamily: 'open-sans-bold' }} color="error" style={styles.button}>
ERROR
</Button>
</Block>
<Block row space="evenly">
<Block flex left style={{marginTop: 8}}>
<Select
defaultIndex={1}
options={["01", "02", "03", "04", "05"]}
/>
</Block>
<Block flex center>
<Button textStyle={{ fontFamily: 'open-sans-bold', fontSize: 12 }} small center color="default" style={styles.optionsButton}>
DELETE
</Button>
</Block>
<Block flex={1.25} right>
<Button textStyle={{ fontFamily: 'open-sans-bold', fontSize: 12 }} center color="default" style={styles.optionsButton}>
SAVE FOR LATER
</Button>
</Block>
</Block>
</Block>
</Block>
);
};
renderText = () => {
return (
<Block flex style={styles.group}>
<Text size={16} style={styles.title}>
Typography
</Text>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Text
h1
style={{ fontFamily: 'open-sans-regular', marginBottom: theme.SIZES.BASE / 2 }}
color={argonTheme.COLORS.DEFAULT}
>
Heading 1
</Text>
<Text
h2
style={{ fontFamily: 'open-sans-regular', marginBottom: theme.SIZES.BASE / 2 }}
color={argonTheme.COLORS.DEFAULT}
>
Heading 2
</Text>
<Text
h3
style={{ fontFamily: 'open-sans-regular', marginBottom: theme.SIZES.BASE / 2 }}
color={argonTheme.COLORS.DEFAULT}
>
Heading 3
</Text>
<Text
h4
style={{ fontFamily: 'open-sans-regular', marginBottom: theme.SIZES.BASE / 2 }}
color={argonTheme.COLORS.DEFAULT}
>
Heading 4
</Text>
<Text
h5
style={{ fontFamily: 'open-sans-regular', marginBottom: theme.SIZES.BASE / 2 }}
color={argonTheme.COLORS.DEFAULT}
>
Heading 5
</Text>
<Text
p
style={{ fontFamily: 'open-sans-regular', marginBottom: theme.SIZES.BASE / 2 }}
color={argonTheme.COLORS.DEFAULT}
>
Paragraph
</Text>
<Text style={{ fontFamily: 'open-sans-regular' }} muted>This is a muted paragraph.</Text>
</Block>
</Block>
);
};
renderInputs = () => {
return (
<Block flex style={styles.group}>
<Text size={16} style={styles.title}>
Inputs
</Text>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Input right placeholder="Regular" iconContent={<Block />} />
</Block>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Input
right
placeholder="Regular Custom"
style={{
borderColor: argonTheme.COLORS.INFO,
borderRadius: 4,
backgroundColor: "#fff"
}}
iconContent={<Block />}
/>
</Block>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Input
placeholder="Icon left"
iconContent={
<Icon
size={11}
style={{ marginRight: 10 }}
color={argonTheme.COLORS.ICON}
name="search-zoom-in"
family="ArgonExtra"
/>
}
/>
</Block>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Input
right
placeholder="Icon Right"
iconContent={
<Icon
size={11}
color={argonTheme.COLORS.ICON}
name="search-zoom-in"
family="ArgonExtra"
/>
}
/>
</Block>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Input
success
right
placeholder="Success"
iconContent={
<Block
middle
style={{
width: 20,
height: 20,
borderRadius: 10,
backgroundColor: argonTheme.COLORS.INPUT_SUCCESS
}}
>
<Icon
size={11}
color={argonTheme.COLORS.ICON}
name="g-check"
family="ArgonExtra"
/>
</Block>
}
/>
</Block>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Input
error
right
placeholder="Error Input"
iconContent={
<Block
middle
style={{
width: 20,
height: 20,
borderRadius: 10,
backgroundColor: argonTheme.COLORS.INPUT_ERROR
}}
>
<Icon
size={11}
color={argonTheme.COLORS.ICON}
name="support"
family="ArgonExtra"
/>
</Block>
}
/>
</Block>
</Block>
);
};
renderSwitches = () => {
return (
<Block flex style={styles.group}>
<Text size={16} style={styles.title}>
Switches
</Text>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Block
row
middle
space="between"
style={{ marginBottom: theme.SIZES.BASE }}
>
<Text style={{ fontFamily: 'open-sans-regular' }} size={14} color={argonTheme.COLORS.TEXT}>Switch is ON</Text>
<Switch
value={this.state["switch-1"]}
onValueChange={() => this.toggleSwitch("switch-1")}
/>
</Block>
<Block row middle space="between">
<Text style={{ fontFamily: 'open-sans-regular' }} size={14} color={argonTheme.COLORS.TEXT}>Switch is OFF</Text>
<Switch
value={this.state["switch-2"]}
onValueChange={() => this.toggleSwitch("switch-2")}
/>
</Block>
</Block>
</Block>
);
};
renderTableCell = () => {
const { navigation } = this.props;
return (
<Block flex style={styles.group}>
<Text size={16} style={styles.title}>
Table Cell
</Text>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Block style={styles.rows}>
<TouchableOpacity onPress={() => navigation.navigate("Pro")}>
<Block row middle space="between" style={{ paddingTop: 7 }}>
<Text style={{ fontFamily: 'open-sans-regular' }} size={14} color={argonTheme.COLORS.TEXT}>Manage Options</Text>
<Icon
name="chevron-right"
family="entypo"
style={{ paddingRight: 5 }}
/>
</Block>
</TouchableOpacity>
</Block>
</Block>
</Block>
);
};
renderSocial = () => {
return (
<Block flex style={styles.group}>
<Text size={16} style={styles.title}>
Social
</Text>
<Block style={{ paddingHorizontal: theme.SIZES.BASE }}>
<Block row center space="between">
<Block flex middle right>
<GaButton
round
onlyIcon
shadowless
icon="facebook"
iconFamily="Font-Awesome"
iconColor={theme.COLORS.WHITE}
iconSize={theme.SIZES.BASE * 1.625}
color={argonTheme.COLORS.FACEBOOK}
style={[styles.social, styles.shadow]}
/>
</Block>
<Block flex middle center>
<GaButton
round
onlyIcon
shadowless
icon="twitter"
iconFamily="Font-Awesome"
iconColor={theme.COLORS.WHITE}
iconSize={theme.SIZES.BASE * 1.625}
color={argonTheme.COLORS.TWITTER}
style={[styles.social, styles.shadow]}
/>
</Block>
<Block flex middle left>
<GaButton
round
onlyIcon
shadowless
icon="dribbble"
iconFamily="Font-Awesome"
iconColor={theme.COLORS.WHITE}
iconSize={theme.SIZES.BASE * 1.625}
color={argonTheme.COLORS.DRIBBBLE}
style={[styles.social, styles.shadow]}
/>
</Block>
</Block>
</Block>
</Block>
);
};
renderNavigation = () => {
return (
<Block flex style={styles.group}>
<Text size={16} style={styles.title}>
Navigation
</Text>
<Block>
<Block style={{ marginBottom: theme.SIZES.BASE }}>
<Header back title="Title" navigation={this.props.navigation} />
</Block>
<Block style={{ marginBottom: theme.SIZES.BASE }}>
<Header
white
back
title="Title"
navigation={this.props.navigation}
bgColor={argonTheme.COLORS.ACTIVE}
titleColor="white"
iconColor="white"
/>
</Block>
<Block style={{ marginBottom: theme.SIZES.BASE }}>
<Header search title="Title" navigation={this.props.navigation} />
</Block>
<Block style={{ marginBottom: theme.SIZES.BASE }}>
<Header
tabs={tabs.categories}
search
title="Title"
navigation={this.props.navigation}
/>
</Block>
<Block style={{ marginBottom: theme.SIZES.BASE }}>
<Header
options
search
title="Title"
optionLeft="Option 1"
optionRight="Option 2"
navigation={this.props.navigation}
/>
</Block>
</Block>
</Block>
);
};
render() {
return (
<Block flex center>
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={{ paddingBottom: 30, width }}
>
{this.renderButtons()}
{this.renderText()}
{this.renderInputs()}
{this.renderSocial()}
{this.renderSwitches()}
{this.renderNavigation()}
{this.renderTableCell()}
</ScrollView>
</Block>
);
}
}
const styles = StyleSheet.create({
title: {
fontFamily: 'open-sans-bold',
paddingBottom: theme.SIZES.BASE,
paddingHorizontal: theme.SIZES.BASE * 2,
marginTop: 44,
color: argonTheme.COLORS.HEADER
},
group: {
paddingTop: theme.SIZES.BASE * 2
},
shadow: {
shadowColor: "black",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 4,
shadowOpacity: 0.2,
elevation: 2
},
button: {
marginBottom: theme.SIZES.BASE,
width: width - theme.SIZES.BASE * 2
},
optionsButton: {
width: "auto",
height: 34,
paddingHorizontal: theme.SIZES.BASE,
paddingVertical: 10
},
input: {
borderBottomWidth: 1
},
inputDefault: {
borderBottomColor: argonTheme.COLORS.PLACEHOLDER
},
inputTheme: {
borderBottomColor: argonTheme.COLORS.PRIMARY
},
inputTheme: {
borderBottomColor: argonTheme.COLORS.PRIMARY
},
inputInfo: {
borderBottomColor: argonTheme.COLORS.INFO
},
inputSuccess: {
borderBottomColor: argonTheme.COLORS.SUCCESS
},
inputWarning: {
borderBottomColor: argonTheme.COLORS.WARNING
},
inputDanger: {
borderBottomColor: argonTheme.COLORS.ERROR
},
social: {
width: theme.SIZES.BASE * 3.5,
height: theme.SIZES.BASE * 3.5,
borderRadius: theme.SIZES.BASE * 1.75,
justifyContent: "center"
}
});
export default Elements;

View File

@@ -0,0 +1,58 @@
import React from "react";
import { StyleSheet, Dimensions, ScrollView } from "react-native";
import { Block, theme } from "galio-framework";
import { Card } from "../components/";
import deals from "../constants/deals";
const { width } = Dimensions.get("screen");
// import products from '../constants/products';
export default class Deals extends React.Component {
renderProducts = () => {
const { navigation, route } = this.props;
// const tabId = navigation.getParam("tabId");
// const products = tabId ? deals[tabId] : deals.shoes;
const tabId = route.params?.tabId;
const products = tabId ? deals[tabId] : deals.beauty;
return (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.products}
>
<Block flex>
<Card item={products[0]} horizontal />
<Block flex row>
<Card
item={products[1]}
style={{ marginRight: theme.SIZES.BASE }}
/>
<Card item={products[2]} />
</Block>
<Card item={products[3]} horizontal />
<Card item={products[4]} full />
</Block>
</ScrollView>
);
};
render() {
return (
<Block flex center style={styles.deals}>
{this.renderProducts()}
</Block>
);
}
}
const styles = StyleSheet.create({
deals: {
width
},
products: {
width: width - theme.SIZES.BASE * 2,
paddingVertical: theme.SIZES.BASE
}
});

View File

@@ -0,0 +1,111 @@
import React from "react";
import {
StyleSheet,
Dimensions,
ScrollView,
Image,
Animated,
Platform
} from "react-native";
import { Block, theme } from "galio-framework";
import { HeaderHeight } from "../constants/utils";
const { width } = Dimensions.get("window");
export default class Gallery extends React.Component {
scrollX = new Animated.Value(0);
renderGallery = () => {
const { navigation, route } = this.props;
const { images, index } = route.params;
return (
<ScrollView
horizontal={true}
pagingEnabled={true}
decelerationRate={0}
scrollEventThrottle={16}
showsHorizontalScrollIndicator={false}
onScroll={Animated.event([
{ nativeEvent: { contentOffset: { x: this.scrollX } } }
], {useNativeDriver: false})}
>
{images.map((image, key) => (
<Image
key={`gallery-image-${key}`}
resizeMode="contain"
source={{ uri: image }}
style={{ width, height: width }}
/>
))}
</ScrollView>
);
};
renderProgress = () => {
const { navigation, route } = this.props;
const { images, index } = route.params;
const position = Animated.divide(this.scrollX, width);
return (
<Block row>
{images.map((_, i) => {
const opacity = position.interpolate({
inputRange: [i - 1, i, i + 1],
outputRange: [0.5, 1, 0.5],
extrapolate: "clamp"
});
const width = position.interpolate({
inputRange: [i - 1, i, i + 1],
outputRange: [8, 18, 8],
extrapolate: "clamp"
});
return (
<Animated.View key={i} style={[styles.dots, { opacity, width }]} />
);
})}
</Block>
);
};
render() {
return (
<Block flex style={styles.gallery}>
<Block flex middle style={{ position: "relative" }}>
<Block style={styles.galleryImage}>{this.renderGallery()}</Block>
<Block center style={styles.dotsContainer}>
{this.renderProgress()}
</Block>
</Block>
</Block>
);
}
}
const styles = StyleSheet.create({
gallery: {
backgroundColor: theme.COLORS.BLACK,
marginTop: Platform.OS === "android" ? -HeaderHeight : 0
},
galleryImage: {
width: width,
height: "auto"
},
dots: {
height: 8,
margin: 8,
borderRadius: 4,
backgroundColor: "white"
},
dotsContainer: {
position: "absolute",
bottom: theme.SIZES.BASE * 3,
left: 0,
right: 0
}
});

View File

@@ -0,0 +1,52 @@
import React from "react";
import { StyleSheet, Dimensions, ScrollView } from "react-native";
import { Block, theme, Text } from "galio-framework";
import { Card } from "../components";
import articles from "../constants/articles";
const { width } = Dimensions.get("screen");
class Home extends React.Component {
renderArticles = () => {
return (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.articles}
>
<Block flex>
<Card item={articles[0]} horizontal />
<Block flex row>
<Card
item={articles[1]}
style={{ marginRight: theme.SIZES.BASE }}
/>
<Card item={articles[2]} />
</Block>
<Card item={articles[3]} horizontal />
<Card item={articles[4]} full />
</Block>
</ScrollView>
);
};
render() {
return (
<Block flex center style={styles.home}>
{this.renderArticles()}
</Block>
);
}
}
const styles = StyleSheet.create({
home: {
width: width
},
articles: {
width: width - theme.SIZES.BASE * 2,
paddingVertical: theme.SIZES.BASE,
paddingHorizontal: 2
}
});
export default Home;

View File

@@ -0,0 +1,66 @@
import React from "react";
import { StyleSheet, FlatList } from "react-native";
import { Block, Text, theme } from "galio-framework";
import { Switch } from "../components";
import argonTheme from "../constants/Theme";
export default class Notifications extends React.Component {
state = {};
toggleSwitch = switchNumber =>
this.setState({ [switchNumber]: !this.state[switchNumber] });
renderItem = ({ item }) => (
<Block row middle space="between" style={styles.rows}>
<Text style={{ fontFamily: 'open-sans-regular' }} size={theme.SIZES.FONT} color="#525F7F" size={15}>{item.title}</Text>
<Switch
onValueChange={() => this.toggleSwitch(item.id)}
value={this.state[item.id]}
/>
</Block>
);
render() {
const notifications = [
{ title: "Someone mentions me", id: "mentions" },
{ title: "Anyone follows me", id: "follows" },
{ title: "Someone comments me", id: "comments" },
{ title: "A seller follows me", id: "seller" }
];
return (
<Block flex style={styles.notification}>
<FlatList
data={notifications}
keyExtractor={(item, index) => item.id}
renderItem={this.renderItem}
ListHeaderComponent={
<Block style={styles.title}>
<Text style={{ fontFamily: 'open-sans-bold', paddingBottom: 5 }} center size={16} color={argonTheme.COLORS.TEXT}>
Recommended Settings
</Text>
<Text style={{ fontFamily: 'open-sans-regular' }} center size={12} color={argonTheme.COLORS.TEXT}>
These are the most important settings
</Text>
</Block>
}
/>
</Block>
);
}
}
const styles = StyleSheet.create({
notification: {
paddingVertical: theme.SIZES.BASE / 3
},
title: {
paddingTop: theme.SIZES.BASE / 2,
paddingBottom: theme.SIZES.BASE * 1.5
},
rows: {
paddingHorizontal: theme.SIZES.BASE,
marginBottom: theme.SIZES.BASE * 1.25
}
});

View File

@@ -0,0 +1,114 @@
import React from "react";
import {
ImageBackground,
Image,
StyleSheet,
StatusBar,
Dimensions,
SafeAreaView
} from "react-native";
import { Block, Button, Text, theme } from "galio-framework";
const { height, width } = Dimensions.get("screen");
import argonTheme from "../constants/Theme";
import Images from "../constants/Images";
class Onboarding extends React.Component {
render() {
const { navigation } = this.props;
return (
<SafeAreaView style={styles.container}>
<StatusBar hidden />
<Block flex center>
<ImageBackground
source={Images.Onboarding}
style={{ height, width, zIndex: 1 }}
/>
</Block>
<Block center>
<Image source={Images.LogoOnboarding} style={styles.logo} />
</Block>
<Block flex space="between" style={styles.padded}>
<Block flex space="around" style={{ zIndex: 2 }}>
<Block style={styles.title}>
<Block>
<Text color="white" size={60}>
Design
</Text>
</Block>
<Block row>
<Text color="white" size={60}>
System
</Text>
<Block middle style={styles.pro}>
<Text size={16} color="white">
PRO
</Text>
</Block>
</Block>
<Block style={styles.subTitle}>
<Text color="white" size={16}>
Fully coded React Native components.
</Text>
</Block>
</Block>
<Block center>
<Button
style={styles.button}
color={argonTheme.COLORS.SECONDARY}
onPress={() => navigation.navigate("Home")}
textStyle={{ color: argonTheme.COLORS.BLACK }}
>
Get Started
</Button>
</Block>
</Block>
</Block>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: theme.COLORS.BLACK,
flex: 1,
},
padded: {
paddingHorizontal: theme.SIZES.BASE * 2,
position: "relative",
bottom: theme.SIZES.BASE,
zIndex: 2
},
button: {
width: width - theme.SIZES.BASE * 4,
height: theme.SIZES.BASE * 3,
shadowRadius: 0,
shadowOpacity: 0
},
logo: {
width: 200,
height: 60,
zIndex: 2,
position: "relative",
marginTop: "-50%"
},
title: {
marginTop: "-5%"
},
subTitle: {
marginTop: 20
},
pro: {
backgroundColor: argonTheme.COLORS.INFO,
paddingHorizontal: 8,
marginLeft: 3,
borderRadius: 4,
height: 22,
marginTop: 15
},
});
export default Onboarding;

View File

@@ -0,0 +1,54 @@
import React from "react";
import { ScrollView, Alert } from "react-native";
import { Block } from "galio-framework";
import { Notification } from "../components";
import { argonTheme } from "../constants";
export default class PersonalNotifications extends React.Component {
render() {
return (
<Block middle flex>
<Block flex style={{ width: "90%" }}>
<ScrollView showsVerticalScrollIndicator={false}>
<Notification
time="15:30"
body="About your order #45C23B Wifey made the best Father's Day meal ever. So thankful so happy."
iconName="ship"
iconFamily="font-awesome"
style={{ marginTop: 15 }}
onPress={() => Alert.alert('Yes, you can use the notifications as buttons so you could send your customers to anything you want.')}
/>
<Notification
time="12:10"
body="Customize our products. Now you can make the best and perfect clothes just for you."
iconName="ship"
iconFamily="font-awesome"
color={argonTheme.COLORS.INFO}
style={{ marginTop: 15 }}
onPress={() => Alert.alert('Yes, you can use the notifications as buttons so you could send your customers to anything you want.')}
/>
<Notification
time="11:30"
body="Breaking News! We have new methods to payment. Learn how to pay off debt fast using the stack method."
iconName="ship"
iconFamily="font-awesome"
color={argonTheme.COLORS.WARNING}
style={{ marginTop: 15 }}
onPress={() => Alert.alert('Yes, you can use the notifications as buttons so you could send your customers to anything you want.')}
/>
<Notification
time="04:23"
body="Congratulations! Someone just ordered a pair of Yamaha HS8 speakers through your app! Hurry up and ship them!"
iconName="ship"
iconFamily="font-awesome"
color={argonTheme.COLORS.SUCCESS}
style={{ marginTop: 15 }}
onPress={() => Alert.alert('Yes, you can use the notifications as buttons so you could send your customers to anything you want.')}
/>
<Block style={{ marginBottom: 20 }} />
</ScrollView>
</Block>
</Block>
);
}
}

View File

@@ -0,0 +1,126 @@
import React from "react";
import { ScrollView, StyleSheet } from "react-native";
import { LinearGradient } from "expo-linear-gradient";
import { Block, Button, Text, theme } from "galio-framework";
import argonTheme from "../constants/Theme";
export default class Privacy extends React.Component {
render() {
return (
<Block flex>
<ScrollView
overScrollMode="always"
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.privacy}
>
<Text style={{ fontFamily: 'open-sans-bold' }} size={16} color={argonTheme.COLORS.TEXT}>
In recent months, Facebook, Google, IBM, Microsoft and others have
aggressively lobbied officials in the Trump administration and
elsewhere to start outlining a federal privacy law, according to
administration officials and the companies. The law would have a
dual purpose, they said: It would overrule the California law and
instead put into place a kinder set of rules that would give the
companies wide leeway over how personal digital information was
handled.
</Text>
<Text
style={{ fontFamily: 'open-sans-regular' }}
size={16}
color={argonTheme.COLORS.TEXT}
style={{ paddingTop: 9 }}
>
We are committed to being part of the process and a constructive
part of the process, said Dean Garfield, president of a leading
tech industry lobbying group, the Information Technology Industry
Council, which is working on proposals for the federal law. The
best way is to work toward developing our own blueprint.
</Text>
<Text
style={{ fontFamily: 'open-sans-regular' }}
size={16}
color={argonTheme.COLORS.TEXT}
style={{ paddingTop: 9 }}
>
The efforts could set up a big fight with consumer and privacy
groups, especially as companies like Facebook face scrutiny for
mishandling users personal data. Many of the internet companies
depend on the collection and analysis of such data to help them
target the online ads that generate the bulk of their revenue.
</Text>
<Text
style={{ fontFamily: 'open-sans-regular' }}
size={16}
color={argonTheme.COLORS.TEXT}
style={{ paddingTop: 9 }}
>
At a board meeting for the Information Technology Industry Council
in May, Joel Kaplan, Facebooks top lobbyist, warned that an early
proposal for privacy in California posed a threat to the industry
and that the trade group needed to make the issue of privacy a
priority, according to two people briefed on the meeting, who were
not authorized to speak publicly.
</Text>
</ScrollView>
<Block flex row space="between" style={styles.buttonsWrapper}>
<Button
color={argonTheme.COLORS.PRIMARY}
style={styles.privacyButton}
>
<Text style={{ fontFamily: 'open-sans-bold' }} size={16} color={argonTheme.COLORS.WHITE}>
ACCEPT
</Text>
</Button>
<Button
color={argonTheme.COLORS.SECONDARY}
textStyle={{ color: theme.COLORS.MUTED }}
style={styles.privacyButton}
>
<Text style={{ fontFamily: 'open-sans-bold' }} size={16} color={argonTheme.COLORS.MUTED}>
DECLINE
</Text>
</Button>
</Block>
<LinearGradient
colors={["rgba(255,255,255,0)", "rgba(255,255,255,1)"]}
style={styles.gradient}
/>
</Block>
);
}
}
const styles = StyleSheet.create({
privacy: {
padding: theme.SIZES.BASE,
paddingBottom: theme.SIZES.BASE * 5
},
buttonsWrapper: {
zIndex: 2,
position: "absolute",
left: 0,
right: 0,
bottom: 0,
paddingHorizontal: theme.SIZES.BASE,
paddingVertical: theme.SIZES.BASE * 1.75
},
privacyButton: {
width: "48%",
height: theme.SIZES.BASE * 3,
alignItems: "center",
shadowColor: "rgba(0, 0, 0, 0.2)",
shadowOffset: { width: 0, height: 4 },
shadowRadius: 8,
shadowOpacity: 1
},
gradient: {
zIndex: 1,
position: "absolute",
bottom: 0,
left: 0,
right: 0,
height: "30%"
}
});

View File

@@ -0,0 +1,172 @@
/**
* 价值前沿 - 启动页
* 黑金主题设计
*/
import React from "react";
import {
View,
Image,
StyleSheet,
StatusBar,
Dimensions,
Platform,
Pressable,
} from "react-native";
import { Box, VStack, HStack, Text, Center } from "native-base";
import { LinearGradient } from "expo-linear-gradient";
import { useSafeAreaInsets } from "react-native-safe-area-context";
const { height, width } = Dimensions.get("screen");
// 金色渐变
const GOLD_GRADIENT = ['#D4AF37', '#F5D77A', '#D4AF37'];
const GOLD_DARK = '#B8962E';
const GOLD_LIGHT = '#F5D77A';
const GOLD_PRIMARY = '#D4AF37';
const Pro = ({ navigation }) => {
const insets = useSafeAreaInsets();
return (
<Box flex={1} bg="#000000">
<StatusBar barStyle="light-content" backgroundColor="#000000" />
{/* 背景装饰 */}
<Box position="absolute" top={0} left={0} right={0} bottom={0}>
{/* 顶部金色光晕 */}
<LinearGradient
colors={['rgba(212, 175, 55, 0.15)', 'rgba(212, 175, 55, 0.05)', 'transparent']}
start={{ x: 0.5, y: 0 }}
end={{ x: 0.5, y: 0.5 }}
style={StyleSheet.absoluteFill}
/>
{/* 底部深色渐变 */}
<LinearGradient
colors={['transparent', 'rgba(0, 0, 0, 0.8)', '#000000']}
start={{ x: 0.5, y: 0.5 }}
end={{ x: 0.5, y: 1 }}
style={StyleSheet.absoluteFill}
/>
</Box>
{/* 主内容 */}
<VStack flex={1} justifyContent="space-between" style={{ paddingTop: insets.top }}>
{/* 上部空间 */}
<Box flex={1} />
{/* Logo 区域 */}
<Center flex={2}>
<Box
bg="rgba(212, 175, 55, 0.08)"
borderWidth={1}
borderColor="rgba(212, 175, 55, 0.2)"
rounded="3xl"
p={6}
style={styles.logoContainer}
>
<Image
source={require("../assets/logo.jpg")}
style={styles.logo}
resizeMode="contain"
/>
</Box>
{/* 品牌名称 */}
<VStack alignItems="center" mt={8} space={2}>
<Text
fontSize="4xl"
fontWeight="bold"
letterSpacing="xl"
style={styles.brandText}
>
价值前沿
</Text>
<Text
fontSize="md"
letterSpacing="lg"
color="rgba(212, 175, 55, 0.7)"
>
VALUE FRONTIER
</Text>
</VStack>
</Center>
{/* 特性描述 */}
<Center flex={1} px={8}>
<Text
fontSize="md"
color="rgba(255, 255, 255, 0.6)"
textAlign="center"
lineHeight="xl"
>
智能投资决策平台{"\n"}
发现市场热点把握投资机会
</Text>
</Center>
{/* 底部按钮区域 */}
<VStack space={4} px={6} style={{ paddingBottom: insets.bottom + 30 }}>
{/* 开始使用按钮 */}
<Pressable onPress={() => navigation.navigate("App")}>
{({ isPressed }) => (
<LinearGradient
colors={isPressed ? [GOLD_DARK, GOLD_PRIMARY] : GOLD_GRADIENT}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
style={[
styles.primaryButton,
{ opacity: isPressed ? 0.9 : 1, transform: [{ scale: isPressed ? 0.98 : 1 }] }
]}
>
<Text fontSize="lg" fontWeight="bold" color="#000000">
开始使用
</Text>
</LinearGradient>
)}
</Pressable>
{/* 版本信息 */}
<Center>
<Text fontSize="xs" color="rgba(255, 255, 255, 0.3)">
Version 1.0.0
</Text>
</Center>
</VStack>
</VStack>
</Box>
);
};
const styles = StyleSheet.create({
logoContainer: {
shadowColor: '#D4AF37',
shadowOffset: { width: 0, height: 0 },
shadowOpacity: 0.3,
shadowRadius: 30,
elevation: 10,
},
logo: {
width: 160,
height: 160,
},
brandText: {
color: '#D4AF37',
textShadowColor: 'rgba(212, 175, 55, 0.5)',
textShadowOffset: { width: 0, height: 0 },
textShadowRadius: 20,
},
primaryButton: {
height: 56,
borderRadius: 16,
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#D4AF37',
shadowOffset: { width: 0, height: 4 },
shadowOpacity: 0.4,
shadowRadius: 12,
elevation: 8,
},
});
export default Pro;

View File

@@ -0,0 +1,380 @@
import React from "react";
import {
StyleSheet,
Dimensions,
ScrollView,
TouchableHighlight,
TouchableWithoutFeedback,
Image,
Animated,
Platform
} from "react-native";
import { Block, Text, Button, theme } from "galio-framework";
import { Icon } from "../components";
import argonTheme from "../constants/Theme";
import Images from "../constants/Images";
import { iPhoneX, HeaderHeight } from "../constants/utils";
const { height, width } = Dimensions.get("window");
export default class Product extends React.Component {
state = {
selectedSize: null
};
scrollX = new Animated.Value(0);
renderGallery = () => {
const { navigation, route } = this.props;
// const { params } = navigation && navigation.state;
// const product = params.product;
const product = route.params?.product;
const productImages = [
product.image,
product.image,
product.image,
product.image
];
return (
<ScrollView
horizontal={true}
pagingEnabled={true}
decelerationRate={0}
scrollEventThrottle={16}
showsHorizontalScrollIndicator={false}
onScroll={Animated.event([{ nativeEvent: { contentOffset: { x: this.scrollX }}}],
{useNativeDriver: false}
)}
>
{productImages.map((image, index) => (
<TouchableWithoutFeedback
key={`product-image-${index}`}
onPress={() =>
navigation.navigate("Gallery", { images: productImages, index })
}
>
<Image
resizeMode="cover"
source={{ uri: image }}
style={{ width, height: iPhoneX ? width + 32 : width }}
/>
</TouchableWithoutFeedback>
))}
</ScrollView>
);
};
renderProgress = () => {
const { navigation, route } = this.props;
// const { params } = navigation && navigation.state;
// const product = params.product;
const product = route.params?.product;
const productImages = [
product.image,
product.image,
product.image,
product.image
];
const position = Animated.divide(this.scrollX, width);
return (
<Block row>
{productImages.map((_, i) => {
const opacity = position.interpolate({
inputRange: [i - 1, i, i + 1],
outputRange: [0.5, 1, 0.5],
extrapolate: "clamp"
});
const width = position.interpolate({
inputRange: [i - 1, i, i + 1],
outputRange: [8, 18, 8],
extrapolate: "clamp"
});
return (
<Animated.View key={i} style={[styles.dots, { opacity, width }]} />
);
})}
</Block>
);
};
renderSize = label => {
const active = this.state.selectedSize === label;
return (
<TouchableHighlight
style={styles.sizeButton}
underlayColor={argonTheme.COLORS.PRICE_COLOR}
onPress={() => this.setState({ selectedSize: label })}
>
<Text style={{ fontFamily: 'open-sans-regular' }} color={active ? theme.COLORS.PRIMARY : argonTheme.COLORS.TEXT}>{label}</Text>
</TouchableHighlight>
);
};
renderChatButton = () => {
const { navigation } = this.props;
return (
<Block style={styles.chatContainer}>
<Button
radius={28}
opacity={0.9}
style={styles.chat}
color={argonTheme.COLORS.PRIMARY}
onPress={() => navigation.navigate("Chat")}
>
<Icon
size={18}
family="materialicon"
name="chat-bubble"
color="white"
/>
</Button>
</Block>
);
};
render() {
const { selectedSize } = this.state;
const { navigation, route } = this.props;
// const { params } = navigation && navigation.state;
// const product = params.product;
const product = route.params?.product;
return (
<Block flex style={styles.product}>
<Block flex style={{ position: "relative" }}>
{this.renderGallery()}
<Block center style={styles.dotsContainer}>
{this.renderProgress()}
</Block>
</Block>
<Block flex style={styles.options}>
{this.renderChatButton()}
<ScrollView vertical={true} showsVerticalScrollIndicator={false}>
<Block
style={{
paddingHorizontal: theme.SIZES.BASE,
paddingTop: theme.SIZES.BASE * 2
}}
>
<Text size={28} style={{ paddingBottom: 24, fontFamily: 'open-sans-regular' }} color={argonTheme.COLORS.TEXT}>
{product.title}
</Text>
<Block row space="between">
<Block row>
<Image
source={Images.ProfilePicture }
style={styles.avatar}
/>
<Block style={{ marginTop: 2 }}>
<Text style={{ fontFamily: 'open-sans-regular' }} size={14} color={argonTheme.COLORS.TEXT}>Jessica Jones</Text>
<Text style={{ fontFamily: 'open-sans-light' }} size={14} color={argonTheme.COLORS.TEXT} style={{ fontWeight: '100' }}>
Pro Seller
</Text>
</Block>
</Block>
<Text style={{ fontFamily: 'open-sans-bold' }} size={18} color={argonTheme.COLORS.TEXT}>
$899
</Text>
</Block>
</Block>
<Block style={{ padding: theme.SIZES.BASE }}>
<Text style={{ fontFamily: 'open-sans-regular' }} size={16} color={argonTheme.COLORS.TEXT}>Size</Text>
<Block card style={{ marginTop: 16 }}>
<Block row>
<Block
flex
middle
style={[
styles.size,
styles.roundTopLeft,
selectedSize === "XS" ? styles.active : null
]}
>
{this.renderSize("XS")}
</Block>
<Block
flex
middle
style={[
styles.size,
selectedSize === "S" ? styles.active : null
]}
>
{this.renderSize("S")}
</Block>
<Block
flex
middle
style={[
styles.size,
styles.roundTopRight,
selectedSize === "M" ? styles.active : null
]}
>
{this.renderSize("M")}
</Block>
</Block>
<Block row>
<Block
flex
middle
style={[
styles.size,
styles.roundBottomLeft,
selectedSize === "L" ? styles.active : null
]}
>
{this.renderSize("L")}
</Block>
<Block
flex
middle
style={[
styles.size,
{ borderBottomWidth: 0 },
selectedSize === "XL" ? styles.active : null
]}
>
{this.renderSize("XL")}
</Block>
<Block
flex
middle
style={[
styles.size,
styles.roundBottomRight,
selectedSize === "2XL" ? styles.active : null
]}
>
{this.renderSize("2XL")}
</Block>
</Block>
</Block>
<Button
shadowless
style={styles.addToCart}
color={argonTheme.COLORS.PRIMARY}
onPress={() => navigation.navigate("Cart")}
>
<Text style={{ fontFamily: 'open-sans-bold' }} color={argonTheme.COLORS.WHITE}>ADD TO CART</Text>
</Button>
</Block>
</ScrollView>
</Block>
</Block>
);
}
}
const styles = StyleSheet.create({
product: {
marginTop: Platform.OS === "android" ? -HeaderHeight : 0
},
options: {
position: "relative",
marginHorizontal: theme.SIZES.BASE,
marginTop: -theme.SIZES.BASE * 2,
marginBottom: 0,
borderTopLeftRadius: 13,
borderTopRightRadius: 13,
backgroundColor: theme.COLORS.WHITE,
shadowColor: "black",
shadowOffset: { width: 0, height: 0 },
shadowRadius: 8,
shadowOpacity: 0.2
},
galleryImage: {
width: width,
height: "auto"
},
dots: {
height: theme.SIZES.BASE / 2,
margin: theme.SIZES.BASE / 2,
borderRadius: 4,
backgroundColor: "white"
},
dotsContainer: {
position: "absolute",
bottom: theme.SIZES.BASE,
left: 0,
right: 0,
bottom: height / 10
},
addToCart: {
width: width - theme.SIZES.BASE * 4,
marginTop: theme.SIZES.BASE * 2,
shadowColor: "rgba(0, 0, 0, 0.2)",
shadowOffset: { width: 0, height: 4 },
shadowRadius: 8,
shadowOpacity: 1
},
avatar: {
height: 40,
width: 40,
borderRadius: 20,
marginBottom: theme.SIZES.BASE,
marginRight: 8
},
chat: {
width: 56,
height: 56,
padding: 20,
borderRadius: 28,
shadowColor: "rgba(0, 0, 0, 0.2)",
shadowOffset: { width: 0, height: 4 },
shadowRadius: 8,
shadowOpacity: 1
},
chatContainer: {
top: -32,
right: theme.SIZES.BASE,
zIndex: 2,
position: "absolute"
},
size: {
height: theme.SIZES.BASE * 3,
width: (width - theme.SIZES.BASE * 2) / 3,
borderBottomWidth: 0.5,
borderBottomColor: argonTheme.COLORS.BORDER_COLOR,
overflow: "hidden"
},
sizeButton: {
height: theme.SIZES.BASE * 3,
width: "100%",
justifyContent: "center",
alignItems: "center"
},
active: {
backgroundColor: argonTheme.COLORS.PRICE_COLOR
},
roundTopLeft: {
borderTopLeftRadius: 4,
borderRightColor: argonTheme.COLORS.BORDER_COLOR,
borderRightWidth: 0.5
},
roundBottomLeft: {
borderBottomLeftRadius: 4,
borderRightColor: argonTheme.COLORS.BORDER_COLOR,
borderRightWidth: 0.5,
borderBottomWidth: 0
},
roundTopRight: {
borderTopRightRadius: 4,
borderLeftColor: argonTheme.COLORS.BORDER_COLOR,
borderLeftWidth: 0.5
},
roundBottomRight: {
borderBottomRightRadius: 4,
borderLeftColor: argonTheme.COLORS.BORDER_COLOR,
borderLeftWidth: 0.5,
borderBottomWidth: 0
}
});

View File

@@ -0,0 +1,226 @@
import React from "react";
import {
StyleSheet,
Dimensions,
ScrollView,
Image,
ImageBackground,
Platform
} from "react-native";
import { Block, Text, theme } from "galio-framework";
import { Button } from "../components";
import { Images, argonTheme } from "../constants";
import { HeaderHeight } from "../constants/utils";
const { width, height } = Dimensions.get("screen");
const thumbMeasure = (width - 48 - 32) / 3;
class Profile extends React.Component {
render() {
return (
<Block flex style={styles.profile}>
<Block flex>
<ImageBackground
source={Images.ProfileBackground}
style={styles.profileContainer}
imageStyle={styles.profileBackground}
>
<ScrollView
showsVerticalScrollIndicator={false}
style={{ width, marginTop: "25%" }}
>
<Block flex style={styles.profileCard}>
<Block middle style={styles.avatarContainer}>
<Image
source={ Images.ProfilePicture }
style={styles.avatar}
/>
</Block>
<Block style={styles.info}>
<Block
middle
row
space="evenly"
style={{ marginTop: 20, paddingBottom: 24 }}
>
<Button
small
style={{ backgroundColor: argonTheme.COLORS.INFO }}
>
CONNECT
</Button>
<Button
small
style={{ backgroundColor: argonTheme.COLORS.DEFAULT }}
>
MESSAGE
</Button>
</Block>
<Block row space="between">
<Block middle>
<Text
size={18}
color="#525F7F"
style={{ marginBottom: 4, fontFamily: 'open-sans-bold' }}
>
2K
</Text>
<Text style={{ fontFamily: 'open-sans-regular' }} size={12} color={argonTheme.COLORS.TEXT}>Orders</Text>
</Block>
<Block middle>
<Text
color="#525F7F"
size={18}
style={{ marginBottom: 4, fontFamily: 'open-sans-bold' }}
>
10
</Text>
<Text style={{ fontFamily: 'open-sans-regular' }} size={12} color={argonTheme.COLORS.TEXT}>Photos</Text>
</Block>
<Block middle>
<Text
color="#525F7F"
size={18}
style={{ marginBottom: 4, fontFamily: 'open-sans-bold' }}
>
89
</Text>
<Text style={{ fontFamily: 'open-sans-regular' }} size={12} color={argonTheme.COLORS.TEXT}>Comments</Text>
</Block>
</Block>
</Block>
<Block flex>
<Block middle style={styles.nameInfo}>
<Text style={{ fontFamily: 'open-sans-regular' }} size={28} color="#32325D">
Jessica Jones, 27
</Text>
<Text size={16} color="#32325D" style={{ marginTop: 10, fontFamily: 'open-sans-light' }}>
San Francisco, USA
</Text>
</Block>
<Block middle style={{ marginTop: 30, marginBottom: 16 }}>
<Block style={styles.divider} />
</Block>
<Block middle>
<Text
size={16}
color="#525F7F"
style={{ textAlign: "center", fontFamily: 'open-sans-regular' }}
>
An artist of considerable range, Jessica name taken by
Melbourne
</Text>
<Button
color="transparent"
textStyle={{
color: "#233DD2",
fontWeight: "500",
fontSize: 16,
fontFamily: 'open-sans-regular'
}}
>
Show more
</Button>
</Block>
<Block
row
style={{ paddingVertical: 14 }}
space="between"
>
<Text bold size={16} color="#525F7F" style={{ marginTop: 3 }}>
Album
</Text>
<Button
small
color="transparent"
textStyle={{ color: "#5E72E4", fontSize: 14 }}
>
View all
</Button>
</Block>
<Block style={{ paddingBottom: -HeaderHeight * 2 }}>
<Block row space="between" style={{ flexWrap: "wrap" }}>
{Images.Viewed.map((img, imgIndex) => (
<Image
source={{ uri: img }}
key={`viewed-${img}`}
resizeMode="cover"
style={styles.thumb}
/>
))}
</Block>
</Block>
</Block>
</Block>
<Block style={{ marginBottom: 25 }}/>
</ScrollView>
</ImageBackground>
</Block>
</Block>
);
}
}
const styles = StyleSheet.create({
profile: {
marginTop: Platform.OS === "android" ? -HeaderHeight : 0,
// marginBottom: -HeaderHeight * 2,
flex: 1
},
profileContainer: {
width: width,
height: height,
padding: 0,
zIndex: 1
},
profileBackground: {
width: width,
height: height / 2
},
profileCard: {
// position: "relative",
padding: theme.SIZES.BASE,
marginHorizontal: theme.SIZES.BASE,
marginTop: 65,
borderTopLeftRadius: 6,
borderTopRightRadius: 6,
backgroundColor: theme.COLORS.WHITE,
shadowColor: "black",
shadowOffset: { width: 0, height: 0 },
shadowRadius: 8,
shadowOpacity: 0.2,
zIndex: 2
},
info: {
paddingHorizontal: 40
},
avatarContainer: {
position: "relative",
marginTop: -80
},
avatar: {
width: 124,
height: 124,
borderRadius: 62,
borderWidth: 0
},
nameInfo: {
marginTop: 35
},
divider: {
width: "90%",
borderWidth: 1,
borderColor: "#E9ECEF"
},
thumb: {
borderRadius: 4,
marginVertical: 4,
alignSelf: "center",
width: thumbMeasure,
height: thumbMeasure
}
});
export default Profile;

View File

@@ -0,0 +1,260 @@
import React from "react";
import {
StyleSheet,
ImageBackground,
Dimensions,
StatusBar,
TouchableWithoutFeedback,
Keyboard
} from "react-native";
import { Block, Checkbox, Text } from "galio-framework";
import { Button, Icon, Input } from "../components";
import { Images, argonTheme } from "../constants";
const { width, height } = Dimensions.get("screen");
const DismissKeyboard = ({ children }) => (
<TouchableWithoutFeedback onPress={() => Keyboard.dismiss()}>
{children}
</TouchableWithoutFeedback>
);
class Register extends React.Component {
render() {
return (
<DismissKeyboard>
<Block flex middle>
<StatusBar hidden />
<ImageBackground
source={Images.RegisterBackground}
style={{ width, height, zIndex: 1 }}
>
<Block flex middle>
<Block style={styles.registerContainer}>
<Block flex space="between">
<Block flex={0.2} middle style={styles.socialConnect}>
<Block flex={0.6} middle>
<Text color="#8898AA" size={12}>
Sign up with
</Text>
</Block>
<Block flex={0.4} row style={{ marginBottom: 18 }}>
<Button
style={{ ...styles.socialButtons, marginRight: 30 }}
>
<Block row>
<Icon
name="logo-github"
family="Ionicon"
size={14}
color={"black"}
style={{ marginTop: 2, marginRight: 5 }}
/>
<Text style={styles.socialTextButtons}>GITHUB</Text>
</Block>
</Button>
<Button style={styles.socialButtons}>
<Block row>
<Icon
name="facebook-square"
family="font-awesome"
size={14}
color={"black"}
style={{ marginTop: 2, marginRight: 5 }}
/>
<Text style={styles.socialTextButtons}>FACEBOOK</Text>
</Block>
</Button>
</Block>
</Block>
<Block flex={0.8} middle space="between">
<Block flex={0.2} middle>
<Text
style={{
fontFamily: "open-sans-regular",
textAlign: "center"
}}
color="#8898AA"
size={12}
>
Or sign up the classic way
</Text>
</Block>
<Block center flex={0.9}>
<Block flex space="between">
<Block>
<Block
width={width * 0.8}
style={{ marginBottom: 5 }}
>
<Input
borderless
placeholder="Name"
iconContent={
<Icon
size={16}
color="#ADB5BD"
name="hat-3"
family="ArgonExtra"
style={styles.inputIcons}
/>
}
/>
</Block>
<Block
width={width * 0.8}
style={{ marginBottom: 5 }}
>
<Input
borderless
placeholder="Email"
iconContent={
<Icon
size={16}
color="#ADB5BD"
name="ic_mail_24px"
family="ArgonExtra"
style={styles.inputIcons}
/>
}
/>
</Block>
<Block width={width * 0.8}>
<Input
password
borderless
placeholder="Password"
iconContent={
<Icon
size={16}
color="#ADB5BD"
name="padlock-unlocked"
family="ArgonExtra"
style={styles.inputIcons}
/>
}
/>
<Block row style={styles.passwordCheck}>
<Text
style={{ fontFamily: "open-sans-regular" }}
size={12}
color={argonTheme.COLORS.MUTED}
>
password strength:
</Text>
<Text
style={{ fontFamily: "open-sans-bold" }}
size={12}
color={argonTheme.COLORS.SUCCESS}
>
{" "}
strong
</Text>
</Block>
</Block>
<Block row width={width * 0.75}>
<Checkbox
checkboxStyle={{
borderWidth: 1
}}
color={argonTheme.COLORS.PRIMARY}
labelStyle={{
color: argonTheme.COLORS.TEXT,
fontFamily: "open-sans-regular"
}}
label="I agree with the"
/>
<Button
style={{ width: 100 }}
color="transparent"
textStyle={{
color: argonTheme.COLORS.PRIMARY,
fontSize: 14,
fontFamily: "open-sans-regular",
marginRight: 5
}}
>
Privacy Policy
</Button>
</Block>
</Block>
<Block center>
<Button color="primary" style={styles.createButton}>
<Text
style={{ fontFamily: "open-sans-bold" }}
size={14}
color={argonTheme.COLORS.WHITE}
>
CREATE ACCOUNT
</Text>
</Button>
</Block>
</Block>
</Block>
</Block>
</Block>
</Block>
</Block>
</ImageBackground>
</Block>
</DismissKeyboard>
);
}
}
const styles = StyleSheet.create({
registerContainer: {
width: width * 0.9,
height: height < 812 ? height * 0.9 : height * 0.8,
backgroundColor: "#F4F5F7",
borderRadius: 4,
shadowColor: argonTheme.COLORS.BLACK,
shadowOffset: {
width: 0,
height: 4
},
shadowRadius: 8,
shadowOpacity: 0.1,
elevation: 1,
overflow: "hidden"
},
socialConnect: {
backgroundColor: argonTheme.COLORS.WHITE,
borderBottomWidth: StyleSheet.hairlineWidth,
borderColor: "rgba(136, 152, 170, 0.3)"
},
socialButtons: {
width: 120,
height: 40,
backgroundColor: "#fff",
shadowColor: argonTheme.COLORS.BLACK,
shadowOffset: {
width: 0,
height: 4
},
shadowRadius: 8,
shadowOpacity: 0.1,
elevation: 1
},
socialTextButtons: {
color: argonTheme.COLORS.PRIMARY,
fontWeight: "800",
fontSize: 14
},
inputIcons: {
marginRight: 12
},
passwordCheck: {
paddingLeft: 2,
paddingTop: 6,
paddingBottom: 15
},
createButton: {
width: width * 0.5,
marginTop: 25,
marginBottom: 40
}
});
export default Register;

View File

@@ -0,0 +1,282 @@
import React from "react";
import {
Animated,
FlatList,
Dimensions,
ScrollView,
StyleSheet,
TouchableOpacity,
TouchableWithoutFeedback
} from "react-native";
import { Block, Text, Input, theme } from "galio-framework";
const { width } = Dimensions.get("screen");
import { articles, categories, argonTheme } from "../constants/";
import { Icon, Card } from "../components/";
const suggestions = [
{ id: "DJs", title: "DJs", image: categories["DJs"] },
{ id: "artists", title: "Artists", image: categories["artists"] },
{ id: "accessory", title: "Accessories", image: categories["accessory"] }
];
export default class Search extends React.Component {
state = {
results: [],
search: "",
active: false
};
animatedValue = new Animated.Value(0);
animate() {
this.animatedValue.setValue(0);
Animated.timing(this.animatedValue, {
toValue: 1,
duration: 300,
useNativeDriver: true
}).start();
}
handleSearchChange = search => {
const results = articles.filter(
item => search && item.title.toLowerCase().includes(search)
);
this.setState({ results, search });
this.animate();
};
renderSearch = () => {
const { search } = this.state;
const iconSearch = search ? (
<TouchableWithoutFeedback onPress={() => this.setState({ search: "" })}>
<Icon
size={16}
color={theme.COLORS.MUTED}
name="magnifying-glass"
family="entypo"
/>
</TouchableWithoutFeedback>
) : (
<Icon
size={16}
color={theme.COLORS.MUTED}
name="magnifying-glass"
family="entypo"
/>
);
return (
<Input
right
color="black"
autoFocus={true}
autoCorrect={false}
autoCapitalize="none"
iconContent={iconSearch}
defaultValue={search}
style={[styles.search, this.state.active ? styles.shadow : null]}
placeholder="What are you looking for?"
onFocus={() => this.setState({ active: true })}
onBlur={() => this.setState({ active: false })}
onChangeText={this.handleSearchChange}
/>
);
};
renderNotFound = () => {
return (
<Block style={styles.notfound}>
<Text style={{ fontFamily: 'open-sans-regular' }} size={18} color={argonTheme.COLORS.TEXT}>
We didnt find "<Text bold>{this.state.search}</Text>" in our store.
</Text>
<Text size={18} style={{ marginTop: theme.SIZES.BASE, fontFamily: 'open-sans-regular' }} color={argonTheme.COLORS.TEXT}>
You can see more products from other categories.
</Text>
</Block>
);
};
renderSuggestions = () => {
const { navigation } = this.props;
return (
<FlatList
data={suggestions}
keyExtractor={(item, index) => item.id}
renderItem={({ item }) => (
<TouchableOpacity
style={styles.suggestion}
onPress={() => navigation.navigate("Category", { ...item })}
>
<Block flex row middle space="between">
<Text style={{ fontFamily: 'open-sans-regular' }} size={14} color={argonTheme.COLORS.TEXT}>{item.title}</Text>
<Icon
name="chevron-right"
family="evilicon"
style={{ paddingRight: 5 }}
/>
</Block>
</TouchableOpacity>
)}
/>
);
};
renderDeals = () => {
return (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.dealsContainer}
>
<Block flex>
<Block flex row>
<Card
item={articles[1]}
style={{ marginRight: theme.SIZES.BASE }}
/>
<Card item={articles[2]} />
</Block>
<Card item={articles[0]} horizontal />
</Block>
</ScrollView>
);
};
renderResult = result => {
const opacity = this.animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0.8, 1],
extrapolate: "clamp"
});
return (
<Animated.View
style={{ width: width - theme.SIZES.BASE * 2, opacity }}
key={`result-${result.title}`}
>
<Card item={result} horizontal />
</Animated.View>
);
};
renderResults = () => {
const { results, search } = this.state;
if (results.length === 0 && search) {
return (
<Block style={{ width: width - 40 }}>
{this.renderNotFound()}
{this.renderSuggestions()}
<Text style={{ fontFamily: 'open-sans-regular' }} size={18} color={argonTheme.COLORS.TEXT}>Daily Deals</Text>
{this.renderDeals()}
</Block>
);
}
return (
<Block style={{ paddingTop: theme.SIZES.BASE * 2 }}>
{results.map(result => this.renderResult(result))}
</Block>
);
};
render() {
return (
<Block flex center style={styles.searchContainer}>
<Block center style={styles.header}>
{this.renderSearch()}
</Block>
<ScrollView showsVerticalScrollIndicator={false}>
{this.renderResults()}
</ScrollView>
</Block>
);
}
}
const styles = StyleSheet.create({
searchContainer: {
width: width,
paddingHorizontal: theme.SIZES.BASE
},
search: {
height: 48,
width: width - 32,
marginHorizontal: theme.SIZES.BASE,
marginBottom: theme.SIZES.BASE,
borderWidth: 1,
borderRadius: 3
},
shadow: {
shadowColor: "black",
shadowOffset: { width: 0, height: 3 },
shadowRadius: 4,
shadowOpacity: 0.1,
elevation: 2
},
header: {
backgroundColor: theme.COLORS.WHITE,
shadowColor: "rgba(0, 0, 0, 0.2)",
shadowOffset: { width: 0, height: 2 },
shadowRadius: 8,
shadowOpacity: 1,
elevation: 2,
zIndex: 2
},
notfound: {
marginVertical: theme.SIZES.BASE * 2
},
suggestion: {
height: theme.SIZES.BASE * 1.5,
marginBottom: theme.SIZES.BASE
},
result: {
backgroundColor: theme.COLORS.WHITE,
marginBottom: theme.SIZES.BASE,
borderWidth: 0
},
resultTitle: {
flex: 1,
flexWrap: "wrap",
paddingBottom: 6
},
resultDescription: {
padding: theme.SIZES.BASE / 2
},
image: {
overflow: "hidden",
borderBottomLeftRadius: 4,
borderTopLeftRadius: 4
},
dealsContainer: {
justifyContent: "center",
paddingTop: theme.SIZES.BASE
},
deals: {
backgroundColor: theme.COLORS.WHITE,
marginBottom: theme.SIZES.BASE,
borderWidth: 0
},
dealsTitle: {
flex: 1,
flexWrap: "wrap",
paddingBottom: 6
},
dealsDescription: {
padding: theme.SIZES.BASE / 2
},
imageHorizontal: {
overflow: "hidden",
borderBottomLeftRadius: 4,
borderTopLeftRadius: 4
},
imageVertical: {
overflow: "hidden",
borderTopRightRadius: 4,
borderTopLeftRadius: 4
}
});

View File

@@ -0,0 +1,137 @@
import React from "react";
import {
StyleSheet,
FlatList,
TouchableOpacity,
View
} from "react-native";
import { Block, Text, theme, Icon } from "galio-framework";
import { Switch } from "../components";
import argonTheme from "../constants/Theme";
export default class Settings extends React.Component {
state = {};
toggleSwitch = switchNumber =>
this.setState({ [switchNumber]: !this.state[switchNumber] });
renderItem = ({ item }) => {
const { navigate } = this.props.navigation;
switch (item.type) {
case "switch":
return (
<Block row middle space="between" style={styles.rows}>
<Text style={{ fontFamily: 'open-sans-regular' }} size={14} color="#525F7F">{item.title}</Text>
<Switch
onValueChange={() => this.toggleSwitch(item.id)}
value={this.state[item.id]}
/>
</Block>
);
case "button":
return (
<Block style={styles.rows}>
<TouchableOpacity onPress={() => (item.id !== 'Payment' && item.id !== 'gift') && navigate(item.id)}>
<Block row middle space="between" style={{ paddingTop: 7 }}>
<Text style={{ fontFamily: 'open-sans-regular' }} size={14} color="#525F7F">{item.title}</Text>
<Icon
name="angle-right"
family="font-awesome"
style={{ paddingRight: 5 }}
/>
</Block>
</TouchableOpacity>
</Block>
);
default:
break;
}
};
render() {
const recommended = [
{ title: "Use FaceID to sign in", id: "face", type: "switch" },
{ title: "Auto-Lock security", id: "autolock", type: "switch" },
{ title: "Notifications", id: "NotificationsSettings", type: "button" }
];
const payment = [
{ title: "Manage Payment Options", id: "Payment", type: "button" },
{ title: "Manage Gift Cards", id: "gift", type: "button" }
];
const privacy = [
{ title: "User Agreement", id: "Agreement", type: "button" },
{ title: "Privacy", id: "Privacy", type: "button" },
{ title: "About", id: "About", type: "button" }
];
return (
<View
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.settings}
>
<FlatList
data={recommended}
keyExtractor={(item, index) => item.id}
renderItem={this.renderItem}
ListHeaderComponent={
<Block center style={styles.title}>
<Text style={{ fontFamily: 'open-sans-bold', paddingBottom: 5 }} size={theme.SIZES.BASE} color={argonTheme.COLORS.TEXT}>
Recommended Settings
</Text>
<Text style={{ fontFamily: 'open-sans-regular' }} size={12} color={argonTheme.COLORS.CAPTION} color={argonTheme.COLORS.TEXT}>
These are the most important settings
</Text>
</Block>
}
/>
<Block center style={styles.title}>
<Text style={{ fontFamily: 'open-sans-bold', paddingBottom: 5 }} size={theme.SIZES.BASE} color={argonTheme.COLORS.TEXT}>
Payment Settings
</Text>
<Text style={{ fontFamily: 'open-sans-regular' }} size={12} color={argonTheme.COLORS.CAPTION} color={argonTheme.COLORS.TEXT}>
These are also important settings
</Text>
</Block>
<FlatList
data={payment}
keyExtractor={(item, index) => item.id}
renderItem={this.renderItem}
/>
<Block center style={styles.title}>
<Text style={{ fontFamily: 'open-sans-bold', paddingBottom: 5 }} size={theme.SIZES.BASE} color={argonTheme.COLORS.TEXT}>
Privacy Settings
</Text>
<Text style={{ fontFamily: 'open-sans-regular' }} size={12} color={argonTheme.COLORS.CAPTION} color={argonTheme.COLORS.TEXT}>
Third most important settings
</Text>
</Block>
<FlatList
data={privacy}
keyExtractor={(item, index) => item.id}
renderItem={this.renderItem}
/>
</View>
);
}
}
const styles = StyleSheet.create({
settings: {
paddingVertical: theme.SIZES.BASE / 3
},
title: {
paddingTop: theme.SIZES.BASE,
paddingBottom: theme.SIZES.BASE / 2
},
rows: {
height: theme.SIZES.BASE * 2,
paddingHorizontal: theme.SIZES.BASE,
marginBottom: theme.SIZES.BASE / 2
}
});

View File

@@ -0,0 +1,116 @@
import React from "react";
import { StyleSheet, ScrollView, Alert } from "react-native";
import { Block, Text } from "galio-framework";
import { Notification } from "../components";
import { argonTheme } from "../constants";
export default class SystemNotifications extends React.Component {
render() {
return (
<Block flex>
<ScrollView showsVerticalScrollIndicator={false} style={{ flex: 1 }}>
<Block center style={{ width: "90%" }}>
<Block style={styles.card}>
<Block style={styles.cardHeader}>
<Text
size={18}
style={{ fontFamily: "open-sans-bold" }}
color={argonTheme.COLORS.TEXT}
>
Unread notifications
</Text>
</Block>
<Block>
<Notification
transparent
system
title="New message"
time="2 hrs ago"
body="The new message from the author."
iconName="bell"
iconFamily="font-awesome"
color={"#B0EED3"}
style={{ marginBottom: 10 }}
/>
<Notification
transparent
system
title="New order"
time="3 hrs ago"
body="A confirmed request by one party."
iconName="bell"
iconFamily="font-awesome"
color={"#B0EED3"}
style={{ marginBottom: 10 }}
/>
</Block>
</Block>
<Block style={styles.card}>
<Block style={styles.cardHeader}>
<Text
size={18}
style={{ fontFamily: "open-sans-bold" }}
color={argonTheme.COLORS.TEXT}
>
Read notifications
</Text>
</Block>
<Block>
<Notification
transparent
system
title="Last message"
time="1 day ago"
body="Let's meet at Starbucks at 11:30. Wdyt?"
iconName="like1"
iconFamily="antdesign"
color={"#AAEDF9"}
style={{ marginBottom: 10 }}
/>
<Notification
transparent
system
title="Product issue"
time="2 day ago"
body="A new issue has been reported for Argon."
iconName="html5"
iconFamily="font-awesome"
color={"#FDD1DA"}
style={{ marginBottom: 10 }}
/>
<Notification
transparent
system
title="New likes"
time="4 days ago"
body="Your posts have been liked a lot."
iconName="like1"
iconFamily="antdesign"
color={"#AAEDF9"}
style={{ marginBottom: 10 }}
/>
</Block>
</Block>
</Block>
<Block style={{ marginBottom: 20 }} />
</ScrollView>
</Block>
);
}
}
const styles = StyleSheet.create({
card: {
width: '100%',
backgroundColor: argonTheme.COLORS.WHITE,
marginTop: 25,
borderRadius: 6
},
cardHeader: {
paddingTop: 20,
paddingBottom: 20,
paddingLeft: 20,
borderColor: 'rgba(0,0,0,0.2)',
borderBottomWidth: StyleSheet.hairlineWidth
}
});

Some files were not shown because too many files have changed in this diff Show More