├── .meteor
├── .gitignore
├── release
├── platforms
├── .id
├── .finished-upgraders
└── packages
├── maodou
├── posts
│ ├── .gitignore
│ ├── README.md
│ ├── lib
│ │ ├── configs
│ │ │ ├── i18n
│ │ │ │ ├── zh-cn.js
│ │ │ │ ├── en-us.js
│ │ │ │ └── index.js
│ │ │ └── index.js
│ │ └── collections
│ │ │ ├── index.js
│ │ │ └── posts.js
│ ├── client
│ │ ├── actions
│ │ │ └── index.js
│ │ ├── components
│ │ │ ├── admin
│ │ │ │ ├── index.js
│ │ │ │ └── postsAdd.js
│ │ │ ├── tabs.js
│ │ │ └── post.js
│ │ ├── containers
│ │ │ ├── admin
│ │ │ │ ├── index.js
│ │ │ │ ├── postsList.js
│ │ │ │ └── postsConfigure.js
│ │ │ ├── post.js
│ │ │ ├── tabs.js
│ │ │ └── posts.js
│ │ ├── routes.js
│ │ ├── index.js
│ │ ├── reducers
│ │ │ └── index.js
│ │ ├── admin-routes.js
│ │ └── main.scss
│ └── server
│ │ ├── permissions
│ │ └── index.js
│ │ ├── publications
│ │ └── index.js
│ │ ├── index.js
│ │ └── methods
│ │ └── index.js
├── events
│ ├── .gitignore
│ ├── README.md
│ ├── lib
│ │ ├── configs
│ │ │ ├── i18n
│ │ │ │ ├── zh-cn.js
│ │ │ │ ├── en-us.js
│ │ │ │ └── index.js
│ │ │ └── index.js
│ │ └── collections
│ │ │ ├── index.js
│ │ │ └── events.js
│ ├── client
│ │ ├── actions
│ │ │ └── index.js
│ │ ├── components
│ │ │ ├── admin
│ │ │ │ └── index.js
│ │ │ └── event.js
│ │ ├── reducers
│ │ │ └── index.js
│ │ ├── main.scss
│ │ ├── containers
│ │ │ ├── admin
│ │ │ │ ├── index.js
│ │ │ │ └── eventsList.js
│ │ │ ├── event.js
│ │ │ └── events.js
│ │ ├── routes.js
│ │ ├── index.js
│ │ └── admin-routes.js
│ └── server
│ │ ├── permissions
│ │ └── index.js
│ │ ├── publications
│ │ └── index.js
│ │ ├── methods
│ │ └── index.js
│ │ ├── index.js
│ │ └── seed.js
├── wechat
│ ├── .gitignore
│ ├── README.md
│ ├── configs
│ │ ├── i18n
│ │ │ ├── en-us.js
│ │ │ ├── zh-cn.js
│ │ │ └── index.js
│ │ └── index.js
│ ├── actions
│ │ ├── index.js
│ │ └── wechat.js
│ ├── client
│ │ ├── routes.js
│ │ ├── admin-routes.js
│ │ ├── index.js
│ │ ├── components
│ │ │ ├── sign-in-button.js
│ │ │ └── admin
│ │ │ │ └── index.js
│ │ └── containers
│ │ │ └── admin
│ │ │ └── index.js
│ └── server
│ │ ├── publications
│ │ └── index.js
│ │ ├── middleware.js
│ │ └── index.js
├── singlePages
│ ├── .gitignore
│ ├── README.md
│ ├── client
│ │ ├── actions
│ │ │ └── index.js
│ │ ├── components
│ │ │ └── admin
│ │ │ │ ├── index.js
│ │ │ │ └── singlePagesConf
│ │ │ │ ├── config
│ │ │ │ ├── iframe.js
│ │ │ │ ├── content.js
│ │ │ │ └── index.js
│ │ │ │ ├── preview.js
│ │ │ │ └── index.js
│ │ ├── routes.js
│ │ ├── containers
│ │ │ ├── admin
│ │ │ │ ├── index.js
│ │ │ │ ├── singlePagesConf
│ │ │ │ │ ├── config
│ │ │ │ │ │ └── index.js
│ │ │ │ │ ├── index.js
│ │ │ │ │ └── preview.js
│ │ │ │ └── singlePagesList.js
│ │ │ └── mainPage.js
│ │ ├── index.js
│ │ ├── reducers
│ │ │ └── index.js
│ │ └── admin-routes.js
│ ├── lib
│ │ ├── collections
│ │ │ ├── index.js
│ │ │ └── singlePages.js
│ │ └── configs
│ │ │ └── index.js
│ ├── server
│ │ ├── publications
│ │ │ └── index.js
│ │ └── index.js
│ ├── templates
│ │ └── index.js
│ └── js
│ │ └── navbar.js
├── customers
│ ├── server
│ │ ├── config
│ │ │ └── index.js
│ │ ├── permissions
│ │ │ └── index.js
│ │ ├── publications
│ │ │ └── index.js
│ │ ├── methods
│ │ │ └── index.js
│ │ └── index.js
│ ├── client
│ │ ├── reducers
│ │ │ └── index.js
│ │ ├── actions
│ │ │ └── index.js
│ │ ├── components
│ │ │ ├── admin
│ │ │ │ └── index.js
│ │ │ └── customer.js
│ │ ├── containers
│ │ │ ├── admin
│ │ │ │ ├── index.js
│ │ │ │ ├── customersAdd.js
│ │ │ │ ├── customersList.js
│ │ │ │ └── customersEdit.js
│ │ │ ├── customers.js
│ │ │ └── customer.js
│ │ ├── index.js
│ │ ├── routes.js
│ │ └── admin-routes.js
│ └── lib
│ │ ├── collections
│ │ └── index.js
│ │ └── configs
│ │ └── index.js
└── bizplans
│ ├── client
│ ├── actions
│ │ ├── index.js
│ │ └── bizplans.js
│ ├── components
│ │ ├── admin
│ │ │ ├── index.js
│ │ │ └── bizplan
│ │ │ │ ├── style.scss
│ │ │ │ └── index.js
│ │ ├── bizplansAdd
│ │ │ ├── uploadButton.js
│ │ │ ├── failedMsg.js
│ │ │ └── successMsg.js
│ │ └── singleBizplan
│ │ │ ├── style.scss
│ │ │ └── index.js
│ ├── containers
│ │ ├── admin
│ │ │ ├── index.js
│ │ │ ├── bizplan.js
│ │ │ └── bizplansList.js
│ │ ├── singleBizplan.js
│ │ ├── bizplansList.js
│ │ └── bizplansAdd
│ │ │ ├── uploadButton.js
│ │ │ └── index.js
│ ├── index.js
│ ├── routes.js
│ ├── admin-routes.js
│ └── reducers
│ │ └── index.js
│ ├── lib
│ ├── collections
│ │ ├── index.js
│ │ └── bizplans.js
│ └── config
│ │ └── index.js
│ └── server
│ ├── publications
│ └── index.js
│ ├── methods
│ └── index.js
│ └── index.js
├── server
├── configs
│ ├── events.js
│ ├── posts.js
│ ├── wechat.js
│ └── core.js
├── permissions
│ └── index.js
├── methods
│ ├── index.js
│ ├── files.js
│ └── core.js
├── context.js
├── publications
│ └── index.js
├── lib
│ └── middlewares
│ │ └── middleware.js
├── main.js
└── index.js
├── lib
├── configs
│ ├── i18n
│ │ ├── en-us.js
│ │ ├── zh-cn.js
│ │ └── index.js
│ └── index.js
├── collections
│ ├── packages.js
│ ├── index.js
│ └── users.js
├── middlewares
│ ├── collections.js
│ └── configs.js
└── helpers
│ └── index.js
├── client
├── lib
│ ├── imports
│ │ ├── theme-homer
│ │ │ ├── _tour.scss
│ │ │ ├── _text_editor.scss
│ │ │ ├── _tooltip.scss
│ │ │ ├── _fonts.scss
│ │ │ ├── _projects.scss
│ │ │ ├── _social_board.scss
│ │ │ ├── _grid.scss
│ │ │ ├── _contact.scss
│ │ │ ├── _login.scss
│ │ │ ├── _loader.scss
│ │ │ ├── _lists.scss
│ │ │ ├── _nestable_list.scss
│ │ │ ├── _progress_bar.scss
│ │ │ ├── _modal.scss
│ │ │ ├── style.scss
│ │ │ ├── _dropdown.scss
│ │ │ ├── _icheck.scss
│ │ │ ├── _mailbox.scss
│ │ │ ├── _forum.scss
│ │ │ ├── _alerts.scss
│ │ │ └── _calendar.scss
│ │ └── toastr
│ │ │ └── toastr.scss
│ ├── plupload
│ │ └── js
│ │ │ └── Moxie.xap
│ ├── middlewares
│ │ ├── layouts.js
│ │ └── i18n.js
│ └── compose-with-redux.js
├── actions
│ ├── index.js
│ └── core.js
├── components
│ ├── layout
│ │ ├── footer.js
│ │ └── index.js
│ ├── admin
│ │ ├── layout
│ │ │ ├── index.js
│ │ │ ├── aside.js
│ │ │ └── nav.js
│ │ └── index.js
│ ├── common
│ │ ├── errorPage.js
│ │ ├── welcome.js
│ │ └── loading.js
│ ├── users
│ │ ├── login.js
│ │ ├── reset-password.js
│ │ ├── email-enrollment-form.js
│ │ ├── login-form.js
│ │ └── register.js
│ └── home
│ │ └── index.js
├── main.html
├── reducers
│ └── index.js
├── index.js
├── containers
│ ├── layout
│ │ ├── index.js
│ │ └── nav.js
│ ├── users
│ │ ├── register.js
│ │ ├── reset-password.js
│ │ ├── login-form.js
│ │ ├── email-enrollment-form.js
│ │ └── login.js
│ ├── admin
│ │ ├── layout
│ │ │ ├── index.js
│ │ │ ├── aside.js
│ │ │ └── nav.js
│ │ └── index.js
│ └── home
│ │ └── index.js
├── main.scss
├── context.js
└── main.js
├── .gitignore
├── public
├── Moxie.swf
├── images
│ ├── logo.png
│ ├── logo_short.png
│ ├── logos
│ │ ├── logo_1.png
│ │ ├── logo_2.png
│ │ ├── logo_3.png
│ │ ├── logo_4.png
│ │ ├── logo_5.png
│ │ └── logo_6.png
│ ├── tense
│ │ ├── lbt1.jpg
│ │ ├── lbt2.jpg
│ │ ├── lbt3.jpg
│ │ ├── logo1.png
│ │ ├── logo2.png
│ │ ├── logo3.png
│ │ ├── logo4.png
│ │ ├── logo5.png
│ │ ├── logo6.png
│ │ ├── say1.png
│ │ ├── say2.png
│ │ ├── say3.png
│ │ ├── say4.png
│ │ ├── say5.png
│ │ ├── say6.png
│ │ ├── bgWorks.jpg
│ │ ├── member1.png
│ │ ├── member2.png
│ │ ├── member3.png
│ │ ├── member4.png
│ │ ├── welcome.jpg
│ │ ├── 600X400new1.png
│ │ ├── 600X400new2.png
│ │ ├── 600X400new3.png
│ │ ├── bgPricing.jpg
│ │ ├── logo57x56.png
│ │ ├── logo66x64.png
│ │ ├── 600X400work1.png
│ │ ├── 600X400work2.png
│ │ ├── 600X400work3.png
│ │ ├── 600X400work4.png
│ │ ├── 600X400work5.png
│ │ └── 600X400work6.png
│ ├── aboutadd-iphone.png
│ ├── aboutadd-full-macbook.png
│ ├── aboutadd-half-macbook.png
│ ├── aboutadd-iphone-half.png
│ └── light-bulb.svg
└── fonts
│ ├── FontAwesome.otf
│ ├── Pe-icon-7-stroke.eot
│ ├── Pe-icon-7-stroke.ttf
│ ├── Pe-icon-7-stroke.woff
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ ├── fontawesome-webfont.woff2
│ └── bootstrap
│ └── glyphicons-halflings-regular.woff2
├── webpack.json
├── .editorconfig
├── scripts
├── build_runtime_npm.sh
└── run_app.sh
├── Dockerfile
├── settings.json
├── .eslintrc.js
├── README.md
└── LICENSE
/.meteor/.gitignore:
--------------------------------------------------------------------------------
1 | local
2 |
--------------------------------------------------------------------------------
/maodou/posts/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 |
--------------------------------------------------------------------------------
/.meteor/release:
--------------------------------------------------------------------------------
1 | METEOR@1.4.1.1
2 |
--------------------------------------------------------------------------------
/maodou/events/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 |
--------------------------------------------------------------------------------
/maodou/events/README.md:
--------------------------------------------------------------------------------
1 | # maodou-events
--------------------------------------------------------------------------------
/maodou/posts/README.md:
--------------------------------------------------------------------------------
1 | # maodou-posts
--------------------------------------------------------------------------------
/maodou/wechat/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 |
--------------------------------------------------------------------------------
/maodou/wechat/README.md:
--------------------------------------------------------------------------------
1 | # maodou-wechat
--------------------------------------------------------------------------------
/.meteor/platforms:
--------------------------------------------------------------------------------
1 | server
2 | browser
3 |
--------------------------------------------------------------------------------
/maodou/singlePages/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 |
--------------------------------------------------------------------------------
/maodou/singlePages/README.md:
--------------------------------------------------------------------------------
1 | # maodou-singlepage
2 |
--------------------------------------------------------------------------------
/server/configs/events.js:
--------------------------------------------------------------------------------
1 | export default {
2 |
3 | };
4 |
--------------------------------------------------------------------------------
/server/configs/posts.js:
--------------------------------------------------------------------------------
1 | export default {
2 |
3 | };
4 |
--------------------------------------------------------------------------------
/server/permissions/index.js:
--------------------------------------------------------------------------------
1 | export default () => {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/lib/configs/i18n/en-us.js:
--------------------------------------------------------------------------------
1 | export default {
2 | login: 'Login'
3 | }
4 |
--------------------------------------------------------------------------------
/lib/configs/i18n/zh-cn.js:
--------------------------------------------------------------------------------
1 | export default {
2 | login: '登录'
3 | }
4 |
--------------------------------------------------------------------------------
/maodou/customers/server/config/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 |
3 | };
4 |
--------------------------------------------------------------------------------
/maodou/customers/client/reducers/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 |
3 | };
4 |
--------------------------------------------------------------------------------
/maodou/wechat/configs/i18n/en-us.js:
--------------------------------------------------------------------------------
1 | export default {
2 | hi: 'hi'
3 | }
4 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_tour.scss:
--------------------------------------------------------------------------------
1 | .tour-backdrop {
2 | opacity: 0.5;
3 | }
--------------------------------------------------------------------------------
/maodou/wechat/configs/i18n/zh-cn.js:
--------------------------------------------------------------------------------
1 | export default {
2 | hi: 'ni hao'
3 | }
4 |
--------------------------------------------------------------------------------
/maodou/events/lib/configs/i18n/zh-cn.js:
--------------------------------------------------------------------------------
1 | export default {
2 | comments: '评论'
3 | }
4 |
--------------------------------------------------------------------------------
/maodou/posts/lib/configs/i18n/zh-cn.js:
--------------------------------------------------------------------------------
1 | export default {
2 | comments: '评论'
3 | }
4 |
--------------------------------------------------------------------------------
/maodou/events/lib/configs/i18n/en-us.js:
--------------------------------------------------------------------------------
1 | export default {
2 | comments: 'comments'
3 | }
4 |
--------------------------------------------------------------------------------
/maodou/posts/lib/configs/i18n/en-us.js:
--------------------------------------------------------------------------------
1 | export default {
2 | comments: 'comments'
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .idea
3 | deploy/
4 | npm-debug.log
5 | .DS_Store
6 | mup.json
7 |
--------------------------------------------------------------------------------
/public/Moxie.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/Moxie.swf
--------------------------------------------------------------------------------
/maodou/wechat/actions/index.js:
--------------------------------------------------------------------------------
1 | import wechat from './wechat';
2 |
3 | export default {
4 | wechat
5 | };
6 |
--------------------------------------------------------------------------------
/public/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/logo.png
--------------------------------------------------------------------------------
/maodou/events/client/actions/index.js:
--------------------------------------------------------------------------------
1 | import events from './events';
2 |
3 | export default {
4 | events
5 | };
6 |
--------------------------------------------------------------------------------
/maodou/events/lib/collections/index.js:
--------------------------------------------------------------------------------
1 | import Events from './events';
2 |
3 | export default{
4 | Events
5 | };
6 |
--------------------------------------------------------------------------------
/maodou/posts/client/actions/index.js:
--------------------------------------------------------------------------------
1 | import posts from './posts';
2 |
3 | export default {
4 | posts
5 | };
6 |
--------------------------------------------------------------------------------
/maodou/posts/lib/collections/index.js:
--------------------------------------------------------------------------------
1 | import Posts from './posts';
2 |
3 | export default{
4 | Posts
5 | };
6 |
--------------------------------------------------------------------------------
/maodou/wechat/client/routes.js:
--------------------------------------------------------------------------------
1 | export default function() {
2 | return {
3 | '/admin': ['wechat']
4 | };
5 | }
6 |
--------------------------------------------------------------------------------
/lib/collections/packages.js:
--------------------------------------------------------------------------------
1 | import { Mongo } from 'meteor/mongo';
2 |
3 | export default new Mongo.Collection('packages');
4 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/actions/index.js:
--------------------------------------------------------------------------------
1 | import bizplans from './bizplans'
2 |
3 | export default {
4 | bizplans
5 | }
6 |
--------------------------------------------------------------------------------
/maodou/bizplans/lib/collections/index.js:
--------------------------------------------------------------------------------
1 | import Bizplans from './bizplans'
2 |
3 | export default{
4 | Bizplans
5 | }
6 |
--------------------------------------------------------------------------------
/public/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/public/images/logo_short.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/logo_short.png
--------------------------------------------------------------------------------
/public/images/logos/logo_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/logos/logo_1.png
--------------------------------------------------------------------------------
/public/images/logos/logo_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/logos/logo_2.png
--------------------------------------------------------------------------------
/public/images/logos/logo_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/logos/logo_3.png
--------------------------------------------------------------------------------
/public/images/logos/logo_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/logos/logo_4.png
--------------------------------------------------------------------------------
/public/images/logos/logo_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/logos/logo_5.png
--------------------------------------------------------------------------------
/public/images/logos/logo_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/logos/logo_6.png
--------------------------------------------------------------------------------
/public/images/tense/lbt1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/lbt1.jpg
--------------------------------------------------------------------------------
/public/images/tense/lbt2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/lbt2.jpg
--------------------------------------------------------------------------------
/public/images/tense/lbt3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/lbt3.jpg
--------------------------------------------------------------------------------
/public/images/tense/logo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/logo1.png
--------------------------------------------------------------------------------
/public/images/tense/logo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/logo2.png
--------------------------------------------------------------------------------
/public/images/tense/logo3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/logo3.png
--------------------------------------------------------------------------------
/public/images/tense/logo4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/logo4.png
--------------------------------------------------------------------------------
/public/images/tense/logo5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/logo5.png
--------------------------------------------------------------------------------
/public/images/tense/logo6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/logo6.png
--------------------------------------------------------------------------------
/public/images/tense/say1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/say1.png
--------------------------------------------------------------------------------
/public/images/tense/say2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/say2.png
--------------------------------------------------------------------------------
/public/images/tense/say3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/say3.png
--------------------------------------------------------------------------------
/public/images/tense/say4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/say4.png
--------------------------------------------------------------------------------
/public/images/tense/say5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/say5.png
--------------------------------------------------------------------------------
/public/images/tense/say6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/say6.png
--------------------------------------------------------------------------------
/client/lib/plupload/js/Moxie.xap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/client/lib/plupload/js/Moxie.xap
--------------------------------------------------------------------------------
/maodou/customers/client/actions/index.js:
--------------------------------------------------------------------------------
1 | import customers from './customers';
2 |
3 | export default {
4 | customers
5 | };
6 |
--------------------------------------------------------------------------------
/maodou/customers/lib/collections/index.js:
--------------------------------------------------------------------------------
1 | import Customers from './customers';
2 |
3 | export default{
4 | Customers
5 | };
6 |
--------------------------------------------------------------------------------
/public/images/tense/bgWorks.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/bgWorks.jpg
--------------------------------------------------------------------------------
/public/images/tense/member1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/member1.png
--------------------------------------------------------------------------------
/public/images/tense/member2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/member2.png
--------------------------------------------------------------------------------
/public/images/tense/member3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/member3.png
--------------------------------------------------------------------------------
/public/images/tense/member4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/member4.png
--------------------------------------------------------------------------------
/public/images/tense/welcome.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/welcome.jpg
--------------------------------------------------------------------------------
/webpack.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": ".",
3 | "devtool": "source-map",
4 | "devServer": {
5 | "host": "localhost"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/actions/index.js:
--------------------------------------------------------------------------------
1 | import singlePages from './singlePages';
2 |
3 | export default {
4 | singlePages
5 | };
6 |
--------------------------------------------------------------------------------
/maodou/singlePages/lib/collections/index.js:
--------------------------------------------------------------------------------
1 | import SinglePages from './singlePages'
2 |
3 | export default{
4 | SinglePages
5 | }
6 |
--------------------------------------------------------------------------------
/public/fonts/Pe-icon-7-stroke.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/fonts/Pe-icon-7-stroke.eot
--------------------------------------------------------------------------------
/public/fonts/Pe-icon-7-stroke.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/fonts/Pe-icon-7-stroke.ttf
--------------------------------------------------------------------------------
/public/fonts/Pe-icon-7-stroke.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/fonts/Pe-icon-7-stroke.woff
--------------------------------------------------------------------------------
/public/images/aboutadd-iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/aboutadd-iphone.png
--------------------------------------------------------------------------------
/public/images/tense/600X400new1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/600X400new1.png
--------------------------------------------------------------------------------
/public/images/tense/600X400new2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/600X400new2.png
--------------------------------------------------------------------------------
/public/images/tense/600X400new3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/600X400new3.png
--------------------------------------------------------------------------------
/public/images/tense/bgPricing.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/bgPricing.jpg
--------------------------------------------------------------------------------
/public/images/tense/logo57x56.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/logo57x56.png
--------------------------------------------------------------------------------
/public/images/tense/logo66x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/logo66x64.png
--------------------------------------------------------------------------------
/public/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/public/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/public/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/public/images/tense/600X400work1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/600X400work1.png
--------------------------------------------------------------------------------
/public/images/tense/600X400work2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/600X400work2.png
--------------------------------------------------------------------------------
/public/images/tense/600X400work3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/600X400work3.png
--------------------------------------------------------------------------------
/public/images/tense/600X400work4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/600X400work4.png
--------------------------------------------------------------------------------
/public/images/tense/600X400work5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/600X400work5.png
--------------------------------------------------------------------------------
/public/images/tense/600X400work6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/tense/600X400work6.png
--------------------------------------------------------------------------------
/client/actions/index.js:
--------------------------------------------------------------------------------
1 | import core from './core';
2 | import users from './users';
3 |
4 | export default {
5 | core,
6 | users
7 | };
8 |
--------------------------------------------------------------------------------
/lib/configs/i18n/index.js:
--------------------------------------------------------------------------------
1 | import enUS from './en-us';
2 | import zhCN from './zh-cn';
3 |
4 | export default {
5 | enUS,
6 | zhCN
7 | };
8 |
--------------------------------------------------------------------------------
/public/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/public/images/aboutadd-full-macbook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/aboutadd-full-macbook.png
--------------------------------------------------------------------------------
/public/images/aboutadd-half-macbook.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/aboutadd-half-macbook.png
--------------------------------------------------------------------------------
/public/images/aboutadd-iphone-half.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/images/aboutadd-iphone-half.png
--------------------------------------------------------------------------------
/client/components/layout/footer.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default () => (
4 |
5 |
6 |
7 | );
8 |
--------------------------------------------------------------------------------
/maodou/posts/lib/configs/i18n/index.js:
--------------------------------------------------------------------------------
1 | import enUS from './en-us';
2 | import zhCN from './zh-cn';
3 |
4 | export default {
5 | enUS,
6 | zhCN
7 | };
8 |
--------------------------------------------------------------------------------
/maodou/wechat/configs/i18n/index.js:
--------------------------------------------------------------------------------
1 | import enUS from './en-us';
2 | import zhCN from './zh-cn';
3 |
4 | export default {
5 | enUS,
6 | zhCN
7 | };
8 |
--------------------------------------------------------------------------------
/maodou/events/lib/configs/i18n/index.js:
--------------------------------------------------------------------------------
1 | import enUS from './en-us';
2 | import zhCN from './zh-cn';
3 |
4 | export default {
5 | enUS,
6 | zhCN
7 | };
8 |
--------------------------------------------------------------------------------
/client/main.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/lib/collections/index.js:
--------------------------------------------------------------------------------
1 | import { Meteor } from 'meteor/meteor';
2 | import Packages from './packages';
3 |
4 | export default{
5 | Users: Meteor.users,
6 | Packages
7 | };
8 |
--------------------------------------------------------------------------------
/public/fonts/bootstrap/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maodouio/meteor-react-redux-base/HEAD/public/fonts/bootstrap/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/maodou/bizplans/lib/config/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | bizplans: {
3 | adminLabel: '项目管理',
4 | subMenu: [
5 | { label: '所有项目', href: '/admin/bizplans/list' }
6 | ]
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/maodou/wechat/configs/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | wechat: {
3 | adminLabel: '微信配置',
4 | adminHref: '/admin/wechat',
5 | appId: Meteor.settings.public.wechat.appId || 'xxx'
6 | }
7 | };
8 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/components/admin/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | export default (props) => {
4 | return (
5 |
6 | {props.children}
7 |
8 | )
9 | }
10 |
--------------------------------------------------------------------------------
/maodou/posts/client/components/admin/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default (props) => {
4 | return (
5 |
6 | {props.children}
7 |
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/maodou/wechat/client/admin-routes.js:
--------------------------------------------------------------------------------
1 | import WechatAdmin from './containers/admin';
2 |
3 | export default function (injectDeps, { configs }) {
4 | return [{path: 'wechat', component: WechatAdmin}];
5 | }
6 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/components/admin/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default (props) => {
4 | return (
5 |
6 | {props.children}
7 |
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/server/configs/wechat.js:
--------------------------------------------------------------------------------
1 | export default {
2 | wechat: {
3 | appSecret: Meteor.settings.wechat.appSecret,
4 | token: Meteor.settings.wechat.token,
5 | encodingAESKey: Meteor.settings.wechat.encodingAESKey
6 | }
7 | };
8 |
--------------------------------------------------------------------------------
/server/methods/index.js:
--------------------------------------------------------------------------------
1 | import core from './core';
2 | import users from './users';
3 | import files from './files';
4 |
5 | export default (context) => {
6 | core(context);
7 | users(context);
8 | files(context);
9 | }
10 |
--------------------------------------------------------------------------------
/maodou/customers/client/components/admin/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default (props) => {
4 | return (
5 |
6 | {props.children}
7 |
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/maodou/events/client/components/admin/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default (props) => {
4 | return (
5 |
6 | {props.children}
7 |
8 | );
9 | }
10 |
--------------------------------------------------------------------------------
/maodou/bizplans/server/publications/index.js:
--------------------------------------------------------------------------------
1 | export default ({ Meteor, Collections }) => {
2 | const { Bizplans } = Collections
3 |
4 | Meteor.publish('bizplans.list', function (category) {
5 | return Bizplans.find({ category })
6 | })
7 | }
8 |
--------------------------------------------------------------------------------
/maodou/events/lib/configs/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | events: {
3 | adminLabel: '活动管理',
4 | subMenu: [
5 | { label: '所有活动', href: '/admin/events/list' },
6 | { label: '添加新活动', href: '/admin/event/add' },
7 | ]
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/server/context.js:
--------------------------------------------------------------------------------
1 | import { Meteor } from 'meteor/meteor';
2 | import { Roles } from 'meteor/alanning:roles';
3 | import Qiniu from 'qiniu';
4 |
5 | export default function() {
6 | return {
7 | Meteor,
8 | Roles,
9 | Qiniu
10 | };
11 | }
12 |
--------------------------------------------------------------------------------
/maodou/events/client/reducers/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | eventTmpCover(state = '', action) {
3 | switch (action.type) {
4 | case 'ADD_POST_COVER':
5 | return action.url;
6 | default:
7 | return state;
8 | }
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_text_editor.scss:
--------------------------------------------------------------------------------
1 | .note-editor {
2 | border: 1px solid $border-color;
3 | }
4 | .note-editor .note-toolbar {
5 | border-bottom: 1px solid $border-color;
6 | }
7 |
8 | .note-editor .btn-default {
9 | border-color: $border-color;
10 | }
--------------------------------------------------------------------------------
/maodou/customers/lib/configs/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | customers: {
3 | adminLabel: '客户管理',
4 | subMenu: [
5 | { label: '所有客户', href: '/admin/customers/list' },
6 | { label: '添加新客户', href: '/admin/customers/add' },
7 | ]
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/maodou/wechat/client/index.js:
--------------------------------------------------------------------------------
1 | import actions from '../actions';
2 | import configs from '../configs';
3 | import i18n from '../configs/i18n';
4 | import routes from './routes';
5 |
6 | export default {
7 | actions,
8 | configs,
9 | i18n,
10 | routes
11 | };
12 |
--------------------------------------------------------------------------------
/client/components/layout/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Nav from '../../containers/layout/nav';
3 | import Footer from './footer';
4 |
5 | export default (props) => (
6 |
7 |
8 | {props.children}
9 | {/**/}
10 |
11 | );
12 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/routes.js:
--------------------------------------------------------------------------------
1 | import MainPage from './containers/mainPage';
2 |
3 | export default function (injectDeps, { configs }) {
4 | return {
5 | '/admin': ['singlePages'],
6 |
7 | // insert routes for other layouts here
8 | '/': [
9 | {path: '/', component: MainPage}
10 | ]
11 | };
12 | }
13 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # @see http://editorconfig.org/
2 |
3 | # This is the top-most .editorconfig file; do not search in parent directories.
4 | root = true
5 |
6 | # All files.
7 | [*]
8 | end_of_line = LF
9 | indent_style = space
10 | indent_size = 2
11 | charset = utf-8
12 | trim_trailing_whitespace = true
13 | insert_final_newline = true
14 |
--------------------------------------------------------------------------------
/client/lib/middlewares/layouts.js:
--------------------------------------------------------------------------------
1 | import { injectDeps } from 'react-simple-di';
2 |
3 | export default function(layouts) {
4 | return {
5 | moduleWillInit() {
6 | for (const layout of layouts) {
7 | this.context[layout.name] = injectDeps(this.context, this.actions)(layout.component);
8 | }
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/.meteor/.id:
--------------------------------------------------------------------------------
1 | # This file contains a token that is unique to your project.
2 | # Check it into your repository along with the rest of this directory.
3 | # It can be used for purposes such as:
4 | # - ensuring you don't accidentally deploy one app on top of another
5 | # - providing package authors with aggregated statistics
6 |
7 | 18sz1161xqqec24b2uir
8 |
--------------------------------------------------------------------------------
/scripts/build_runtime_npm.sh:
--------------------------------------------------------------------------------
1 | set -e
2 |
3 | echo "=> build runtime npm."
4 |
5 | cd /bundle/bundle/programs/server/
6 | # fix cloneCurrentTree problem
7 | rm npm-shrinkwrap.json
8 | # echo "=> [zhaoic] fix fibers"
9 | # npm uninstall fibers
10 | # npm install fibers
11 | echo "=> npm install."
12 | npm install --unsafe-perm
13 |
14 | cd /bundle/bundle
15 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM index.alauda.cn/zhaoic/debian:m1
2 | MAINTAINER Maodou Ltd.
3 |
4 | ENV METEORD_DIR /opt/meteord
5 |
6 | ADD bundle.tar.gz /bundle
7 | COPY scripts/build_runtime_npm.sh $METEORD_DIR/
8 | COPY scripts/run_app.sh $METEORD_DIR/
9 |
10 | RUN bash $METEORD_DIR/build_runtime_npm.sh
11 |
12 | EXPOSE 80
13 | ENTRYPOINT bash $METEORD_DIR/run_app.sh
14 |
--------------------------------------------------------------------------------
/maodou/posts/client/containers/admin/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { composeAll } from 'react-komposer-plus';
3 |
4 | import PostsAdmin from '../../components/admin';
5 |
6 | const depsToProps = (context, actions) => ({
7 | context
8 | });
9 |
10 | export default composeAll(
11 | useDeps(depsToProps)
12 | )(PostsAdmin);
13 |
--------------------------------------------------------------------------------
/maodou/singlePages/lib/configs/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | singlePages: {
3 | adminLabel: '单页面管理',
4 | subMenu: [
5 | { label: '选择模板', href: '/admin/singlePages/list' },
6 | { label: '配置模板', href: '/admin/singlePages/config' }
7 | ],
8 | sectionsName: ['企业简介', '团队介绍', '业务类型', '工作动态', '团队案例', '合作伙伴', '联系我们', '其他']
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/containers/admin/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di'
2 | import { composeAll } from 'react-komposer-plus'
3 |
4 | import BizplansAdmin from '../../components/admin'
5 |
6 | const depsToProps = (context, actions) => ({
7 | context
8 | })
9 |
10 | export default composeAll(
11 | useDeps(depsToProps)
12 | )(BizplansAdmin)
13 |
--------------------------------------------------------------------------------
/server/configs/core.js:
--------------------------------------------------------------------------------
1 | import { Meteor } from 'meteor/meteor';
2 |
3 | export default {
4 | core: {
5 | qiniu: {
6 | ACCESS_KEY: Meteor.settings.core.qiniu.ACCESS_KEY,
7 | SECRET_KEY: Meteor.settings.core.qiniu.SECRET_KEY,
8 | BUCKET_NAME: 'maodou-base',
9 | DOMAIN_NAME: 'http://oimlv898n.bkt.clouddn.com/'
10 | }
11 | }
12 | };
13 |
--------------------------------------------------------------------------------
/maodou/posts/server/permissions/index.js:
--------------------------------------------------------------------------------
1 | export default ({ Collections }) => {
2 | const { Posts } = Collections;
3 |
4 | Posts.allow({
5 | insert: function() {
6 | return true;
7 | },
8 | update: function() {
9 | return true;
10 | },
11 | remove: function() {
12 | return true;
13 | },
14 | fetch: null
15 | });
16 | }
17 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/containers/admin/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { composeAll } from 'react-komposer-plus';
3 |
4 | import SectionsAdmin from '../../components/admin';
5 |
6 | const depsToProps = (context, actions) => ({
7 | context
8 | });
9 |
10 | export default composeAll(
11 | useDeps(depsToProps)
12 | )(SectionsAdmin);
13 |
--------------------------------------------------------------------------------
/maodou/wechat/actions/wechat.js:
--------------------------------------------------------------------------------
1 | export default {
2 | saveConfigs({ Meteor, toastr }, configs) {
3 | return (disptch) => {
4 | Meteor.call('wechat.saveConfigs', configs, (err) => {
5 | if (err) {
6 | toastr.error("配置保存失败");
7 | } else {
8 | toastr.success("保存配置成功");
9 | }
10 | });
11 | };
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/maodou/wechat/server/publications/index.js:
--------------------------------------------------------------------------------
1 | export default ({ Meteor, Collections }) => {
2 | const { Packages } = Collections;
3 |
4 | Meteor.publish('wechat.configs.user', function () {
5 | return Packages.find({ name: 'wechat' });
6 | });
7 | Meteor.publish('wechat.configs', function () {
8 | return Packages.find({ name: 'wechat' });
9 | });
10 | }
11 |
--------------------------------------------------------------------------------
/client/reducers/index.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | export default {
4 | test(state = 0, action) {
5 | switch (action.type) {
6 | default:
7 | return state;
8 | }
9 | },
10 | i18n(state = {}, action) {
11 | switch (action.type){
12 | case 'SET_LANGUAGE':
13 | return action.i18n;
14 | default:
15 | return state;
16 | }
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/maodou/events/client/main.scss:
--------------------------------------------------------------------------------
1 | .panel-footer {
2 | .fa {
3 | margin-right: 5px;
4 | }
5 | }
6 |
7 | .event-desc {
8 | padding: 0px;
9 | margin-top: -10px;
10 | font-size: 13px;
11 | text-overflow: ellipsis;
12 | display: -webkit-box;
13 | -webkit-line-clamp: 2;
14 | -webkit-box-orient: vertical;
15 | overflow: hidden;
16 | margin-bottom: -15px;
17 | }
18 |
--------------------------------------------------------------------------------
/maodou/bizplans/server/methods/index.js:
--------------------------------------------------------------------------------
1 | export default (context) => {
2 | const { Meteor, Collections } = context
3 | const { Bizplans } = Collections
4 |
5 | Meteor.methods({
6 | 'bizplans.add' (data) {
7 | Bizplans.insert({
8 | ...data
9 | })
10 | },
11 | 'bizplans.remove' (_id) {
12 | Bizplans.remove({ _id })
13 | }
14 | })
15 | }
16 |
--------------------------------------------------------------------------------
/server/publications/index.js:
--------------------------------------------------------------------------------
1 | export default ({ Meteor, Collections }) => {
2 | const { Packages } = Collections;
3 |
4 | Meteor.publish('core.configs.user', function () {
5 | // TODO: Add configs filter for normal users
6 | return Packages.find({ name: 'core' });
7 | });
8 |
9 | Meteor.publish('core.configs', function () {
10 | return Packages.find({ name: 'core' });
11 | });
12 | }
13 |
--------------------------------------------------------------------------------
/client/index.js:
--------------------------------------------------------------------------------
1 | import configs from '../lib/configs';
2 | import i18n from '../lib/configs/i18n';
3 | import collections from '../lib/collections';
4 | import actions from './actions';
5 | import reducers from './reducers';
6 |
7 | export default {
8 | configs,
9 | i18n,
10 | collections,
11 | actions,
12 | reducers,
13 | init(context, actions) {
14 | // console.log(context);
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/index.js:
--------------------------------------------------------------------------------
1 | import configs from '../lib/config'
2 | import collections from '../lib/collections'
3 | import actions from './actions'
4 | import reducers from './reducers'
5 | import routes from './routes'
6 |
7 | export default {
8 | configs,
9 | collections,
10 | actions,
11 | reducers,
12 | routes,
13 | init (context, actions) {
14 | // console.log(context)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/maodou/events/client/containers/admin/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withHandlers, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import EventsAdmin from '../../components/admin';
5 |
6 | const depsToProps = (context, actions) => ({
7 | context
8 | });
9 |
10 | export default composeAll(
11 | useDeps(depsToProps)
12 | )(EventsAdmin);
13 |
--------------------------------------------------------------------------------
/maodou/posts/client/routes.js:
--------------------------------------------------------------------------------
1 | import Posts from './containers/posts';
2 | import Post from './containers/post';
3 |
4 | export default function (injectDeps, { configs }) {
5 | return {
6 | '/admin': ['posts'],
7 |
8 | // insert routes for other layouts here
9 | '/': [
10 | {path: 'posts/list', component: Posts},
11 | {path: 'post/:id', component: Post}
12 | ]
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/components/bizplansAdd/uploadButton.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | export default class UploadButton extends Component {
4 | render () {
5 | return (
6 | 点击上传
7 | )
8 | }
9 | }
10 |
11 | const styles = {
12 | uploadButton: {
13 | width: '200px'
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/maodou/customers/server/permissions/index.js:
--------------------------------------------------------------------------------
1 | export default ({ Collections }) => {
2 | // const { Posts } = Collections;
3 | //
4 | // Posts.allow({
5 | // insert: function() {
6 | // return true;
7 | // },
8 | // update: function() {
9 | // return true;
10 | // },
11 | // remove: function() {
12 | // return true;
13 | // },
14 | // fetch: null
15 | // });
16 | }
17 |
--------------------------------------------------------------------------------
/maodou/events/server/permissions/index.js:
--------------------------------------------------------------------------------
1 | export default ({ Collections }) => {
2 | // const { Posts } = Collections;
3 | //
4 | // Posts.allow({
5 | // insert: function() {
6 | // return true;
7 | // },
8 | // update: function() {
9 | // return true;
10 | // },
11 | // remove: function() {
12 | // return true;
13 | // },
14 | // fetch: null
15 | // });
16 | }
17 |
--------------------------------------------------------------------------------
/maodou/customers/client/containers/admin/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withHandlers, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import CustomersAdmin from '../../components/admin';
5 |
6 | const depsToProps = (context, actions) => ({
7 | context
8 | });
9 |
10 | export default composeAll(
11 | useDeps(depsToProps)
12 | )(CustomersAdmin);
13 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/index.js:
--------------------------------------------------------------------------------
1 | import configs from '../lib/configs';
2 | import collections from '../lib/collections';
3 | import actions from './actions';
4 | import reducers from './reducers';
5 | import routes from './routes';
6 |
7 | export default {
8 | configs,
9 | collections,
10 | actions,
11 | reducers,
12 | routes,
13 | init (context, actions) {
14 | // console.log(context)
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/client/actions/core.js:
--------------------------------------------------------------------------------
1 | export default {
2 | setLanguage(i18n) {
3 | return { type: 'SET_LANGUAGE', i18n };
4 | },
5 | saveConfigs({ Meteor, toastr }, configs) {
6 | return (disptch) => {
7 | Meteor.call('core.saveConfigs', configs, (err) => {
8 | if (err) {
9 | toastr.error("配置保存失败");
10 | } else {
11 | toastr.success("保存配置成功");
12 | }
13 | });
14 | };
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/client/components/admin/layout/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Nav from '../../../containers/admin/layout/nav';
3 | import Aside from '../../../containers/admin/layout/aside';
4 |
5 | export default (props) => (
6 |
7 |
8 |
9 |
10 | {props.children}
11 | {/*
*/}
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------
/maodou/events/client/routes.js:
--------------------------------------------------------------------------------
1 | import Events from './containers/events';
2 | import Event from './containers/event';
3 |
4 | export default function (injectDeps, { configs }) {
5 | const routes = {
6 | '/admin': ['events'],
7 |
8 | // insert routes for other layouts here
9 |
10 | '/': [
11 | {path: 'events/list', component: Events},
12 | {path: 'event/:id', component: Event}
13 | ]
14 | };
15 |
16 | return routes;
17 | }
18 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_tooltip.scss:
--------------------------------------------------------------------------------
1 | // tooltip
2 | .tooltip-inner {
3 | background-color: $color-navy-blue;
4 | }
5 |
6 | .tooltip.top .tooltip-arrow {
7 | border-top-color: $color-navy-blue;
8 | }
9 | .tooltip.right .tooltip-arrow {
10 | border-right-color: $color-navy-blue;
11 | }
12 | .tooltip.bottom .tooltip-arrow {
13 | border-bottom-color: $color-navy-blue;
14 | }
15 | .tooltip.left .tooltip-arrow {
16 | border-left-color: $color-navy-blue;
17 | }
--------------------------------------------------------------------------------
/maodou/events/client/index.js:
--------------------------------------------------------------------------------
1 | import configs from '../lib/configs';
2 | import i18n from '../lib/configs/i18n';
3 | import collections from '../lib/collections';
4 | import actions from './actions';
5 | import reducers from './reducers';
6 | import routes from './routes';
7 |
8 | export default {
9 | configs,
10 | i18n,
11 | collections,
12 | actions,
13 | reducers,
14 | routes,
15 | init(context, actions) {
16 | // console.log(context);
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/maodou/posts/client/index.js:
--------------------------------------------------------------------------------
1 | import configs from '../lib/configs';
2 | import i18n from '../lib/configs/i18n';
3 | import collections from '../lib/collections';
4 | import actions from './actions';
5 | import reducers from './reducers';
6 | import routes from './routes';
7 |
8 | export default {
9 | configs,
10 | i18n,
11 | collections,
12 | actions,
13 | reducers,
14 | routes,
15 | init(context, actions) {
16 | // console.log(context);
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/maodou/posts/client/reducers/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | postTmpCover(state = '', action) {
3 | switch (action.type){
4 | case 'ADD_POST_COVER':
5 | return action.url;
6 | default:
7 | return state;
8 | }
9 | },
10 | postsCategory(state = '', action) {
11 | switch (action.type){
12 | case 'CHANGE_POSTS_CATEGORY':
13 | return action.category;
14 | default:
15 | return state;
16 | }
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/components/admin/singlePagesConf/config/iframe.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | export default class Iframe extends Component {
4 | render () {
5 | return (
6 |
7 |
14 |
15 | );
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/maodou/customers/client/index.js:
--------------------------------------------------------------------------------
1 | import configs from '../lib/configs';
2 | // import i18n from '../lib/configs/i18n';
3 | import collections from '../lib/collections';
4 | import actions from './actions';
5 | import reducers from './reducers';
6 | import routes from './routes';
7 |
8 | export default {
9 | configs,
10 | // i18n,
11 | collections,
12 | actions,
13 | reducers,
14 | routes,
15 | init(context, actions) {
16 | // console.log(context);
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/maodou/customers/client/routes.js:
--------------------------------------------------------------------------------
1 | import Customers from './containers/customers';
2 | import Customer from './containers/customer';
3 |
4 | export default function (injectDeps, { configs }) {
5 | const routes = {
6 | '/admin': ['customers'],
7 |
8 | // insert routes for other layouts here
9 |
10 | '/': [
11 | {path: 'customers/list', component: Customers},
12 | {path: 'customers/:id', component: Customer},
13 | ]
14 | };
15 |
16 | return routes;
17 | }
18 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/reducers/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | selectedSection(state = '', action) {
3 | switch (action.type){
4 | case 'SELECT_SECTION':
5 | return action.sectionName;
6 | default:
7 | return state;
8 | }
9 | },
10 | singlePageLogo(state = '', action) {
11 | switch (action.type){
12 | case 'CHANGE_SINGLEPAGE_LOGO':
13 | return action.url;
14 | default:
15 | return state;
16 | }
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/maodou/customers/server/publications/index.js:
--------------------------------------------------------------------------------
1 | export default ({ Meteor, Collections }) => {
2 | const { Customers, Packages } = Collections;
3 |
4 | Meteor.publish('customers.list', function () {
5 | return Customers.find({});
6 | });
7 |
8 | Meteor.publish('customers.configs.user', function () {
9 | return Packages.find({ name: 'customers' });
10 | });
11 | Meteor.publish('customers.configs', function () {
12 | return Packages.find({ name: 'customers' });
13 | });
14 | }
15 |
--------------------------------------------------------------------------------
/maodou/events/server/publications/index.js:
--------------------------------------------------------------------------------
1 | export default ({ Meteor, Collections }) => {
2 | const { Events, Packages } = Collections;
3 |
4 | Meteor.publish('events.list', function () {
5 | return Events.find({}, {sort: { time: -1}});
6 | });
7 |
8 | Meteor.publish('events.configs.user', function () {
9 | return Packages.find({ name: 'events' });
10 | });
11 | Meteor.publish('events.configs', function () {
12 | return Packages.find({ name: 'events' });
13 | });
14 | }
15 |
--------------------------------------------------------------------------------
/maodou/posts/lib/configs/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | posts: {
3 | adminLabel: '文章管理',
4 | subMenu: [
5 | { label: '配置选项', href: '/admin/posts/configure' },
6 | { label: '所有文章', href: '/admin/posts/list' },
7 | { label: '添加新文章', href: '/admin/post/add' }
8 | ],
9 | categories: ['初创公司', '创业学院', '孵化服务'],
10 | UI: {
11 | listImgPosition: 'left',
12 | categoriesPosition: 'bottom',
13 | categoriesTabsColor: 'green'
14 | }
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/client/components/common/errorPage.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Link} from 'react-router';
3 |
4 | export default ({ code, info, description }) => (
5 |
6 |
7 |
{code}
8 |
{info}
9 |
{description}
10 |
11 | 回到首页
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------
/client/components/common/welcome.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default () => (
4 |
5 |
6 |
Welcome
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
loading...
15 |
16 |
17 | );
18 |
--------------------------------------------------------------------------------
/client/components/common/loading.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default () => (
4 |
5 |
6 |
Loading...
7 | {/*
some loading descriptions
*/}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/containers/admin/singlePagesConf/config/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { composeAll, withRedux } from 'react-komposer-plus';
3 | import Config from '../../../../components/admin/singlePagesConf/config';
4 |
5 | const mapStateToProps = ({ selectedSection }) => ({
6 | selectedSection
7 | });
8 |
9 | const depsToProps = (context) => ({
10 | context,
11 | });
12 |
13 | export default composeAll(
14 | withRedux(mapStateToProps),
15 | useDeps(depsToProps)
16 | )(Config);
17 |
--------------------------------------------------------------------------------
/server/methods/files.js:
--------------------------------------------------------------------------------
1 | export default ({ Meteor, Roles, Qiniu, privateConfigs }) => {
2 | const bucketName = Qiniu.conf.BUCKET_NAME;
3 | const qiniuClient = new Qiniu.rs.Client();
4 | const wrappedQiniuIoPut = Meteor.wrapAsync(Qiniu.io.put, Qiniu.io);
5 | // const wrappedQiniuClient = Async.wrap(qiniuClient, ['stat', 'remove', 'copy', 'move']);
6 |
7 | Meteor.methods({
8 | 'files.token'() {
9 | const putPolicy = new Qiniu.rs.PutPolicy(bucketName);
10 | return putPolicy.token();
11 | }
12 | });
13 | }
14 |
--------------------------------------------------------------------------------
/.meteor/.finished-upgraders:
--------------------------------------------------------------------------------
1 | # This file contains information which helps Meteor properly upgrade your
2 | # app when you run 'meteor update'. You should check it into version control
3 | # with your project.
4 |
5 | notices-for-0.9.0
6 | notices-for-0.9.1
7 | 0.9.4-platform-file
8 | notices-for-facebook-graph-api-2
9 | 1.2.0-standard-minifiers-package
10 | 1.2.0-meteor-platform-split
11 | 1.2.0-cordova-changes
12 | 1.2.0-breaking-changes
13 | 1.3.0-split-minifiers-package
14 | 1.4.0-remove-old-dev-bundle-link
15 | 1.4.1-add-shell-server-package
16 |
--------------------------------------------------------------------------------
/maodou/singlePages/server/publications/index.js:
--------------------------------------------------------------------------------
1 | export default ({ Meteor, Collections }) => {
2 | const { SinglePages, Packages } = Collections;
3 |
4 | Meteor.publish('singlePages.list', () => {
5 | return SinglePages.find({ defaultTemplate: false});
6 | });
7 |
8 | Meteor.publish('singlePages.selected', () => {
9 | return SinglePages.find({ selected: true, defaultTemplate: false });
10 | });
11 |
12 | Meteor.publish('singlePages.configs', () => {
13 | return Packages.find({ name: 'singlePages' });
14 | });
15 | };
16 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_fonts.scss:
--------------------------------------------------------------------------------
1 | /* Fonts */
2 | .font-light {
3 | font-weight: 300;
4 | }
5 | .font-normal {
6 | font-weight: 400;
7 | }
8 | .font-bold {
9 | font-weight: 600;
10 | }
11 | .font-extra-bold {
12 | font-weight: 700;
13 | }
14 |
15 | .font-uppercase {
16 | text-transform: uppercase;
17 | }
18 |
19 | .font-trans {
20 | opacity: 0.5 !important;
21 | }
22 |
23 | .text-big {
24 | font-size: 60px;
25 | }
26 |
27 | h1, .h1, h2, .h2, h3, .h3 {
28 | margin-top: 10px;
29 | margin-bottom: 10px;
30 | font-weight: 200;
31 | }
--------------------------------------------------------------------------------
/lib/configs/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | core: {
3 | adminLabel: '核心配置',
4 | adminHref: '/admin/core',
5 | appName: Meteor.settings.public.core.appName || 'myApp',
6 | appLogo: Meteor.settings.public.core.appLogo || '/images/logo.png',
7 | ownerEmail: Meteor.settings.public.core.ownerEmail || 'app@example.com',
8 | i18n: false,
9 | languages: ['enUS'],
10 | loginMethod: 'wechat',
11 | qiniu: {
12 | BUCKET_NAME: 'maodou-base',
13 | DOMAIN_NAME: 'http://oimlv898n.bkt.clouddn.com/'
14 | }
15 | }
16 | };
17 |
--------------------------------------------------------------------------------
/server/methods/core.js:
--------------------------------------------------------------------------------
1 | export default ({ Meteor, Collections }) => {
2 | const { Packages } = Collections;
3 | Meteor.methods(({
4 | 'core.saveConfigs'(configs) {
5 | Packages.update({ name: 'core' }, {
6 | $set: {
7 | 'configs.appName': configs.appName
8 | }
9 | });
10 | },
11 | 'resetData'(){
12 | Collections.Users.remove({});
13 | Collections.Posts.remove({});
14 | Collections.Events.remove({});
15 | Collections.Bizplans.remove({});
16 | Collections.SinglePages.remove({});
17 | }
18 | }));
19 | };
20 |
--------------------------------------------------------------------------------
/lib/middlewares/collections.js:
--------------------------------------------------------------------------------
1 | export default () => {
2 | return {
3 | moduleWillLoad(module) {
4 | if (module.collections) {
5 | if (typeof module.collections !== 'object') {
6 | const message = 'Module\'s collections field should be an object.';
7 | throw new Error(message);
8 | }
9 | this._collections = this._collections || {};
10 | Object.assign(this._collections, module.collections);
11 | }
12 | },
13 |
14 | moduleWillInit() {
15 | this.context.Collections = this._collections;
16 | }
17 | };
18 | };
19 |
--------------------------------------------------------------------------------
/maodou/posts/server/publications/index.js:
--------------------------------------------------------------------------------
1 | export default ({ Meteor, Collections }) => {
2 | const { Posts, Packages } = Collections;
3 |
4 | Meteor.publish('posts.list', function (category) {
5 | if (!category) {
6 | return Posts.find({}, {sort: { createdAt: -1}});
7 | }
8 | return Posts.find({ category }, {sort: { createdAt: -1}});
9 | });
10 |
11 | Meteor.publish('posts.configs.user', function () {
12 | return Packages.find({ name: 'posts' });
13 | });
14 | Meteor.publish('posts.configs', function () {
15 | return Packages.find({ name: 'posts' });
16 | });
17 | }
18 |
--------------------------------------------------------------------------------
/client/components/admin/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default (props) => (
4 |
18 | );
19 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/routes.js:
--------------------------------------------------------------------------------
1 | import BizplansList from './containers/bizplansList'
2 | import SingleBizplan from './containers/singleBizplan'
3 | import BizplansAdd from './containers/bizplansAdd'
4 |
5 | export default function (injectDeps, { configs }) {
6 | const routes = {
7 | '/admin': ['bizplans'],
8 |
9 | // insert routes for other layouts here
10 |
11 | '/': [
12 | {path: '/bizplans/list', component: BizplansList},
13 | {path: '/bizplan/add', component: BizplansAdd},
14 | {path: '/bizplan/:id', component: SingleBizplan},
15 | ]
16 | }
17 |
18 | return routes
19 | }
20 |
--------------------------------------------------------------------------------
/client/containers/layout/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withTracker, composeAll } from 'react-komposer-plus';
3 |
4 | import Layout from '../../components/layout';
5 |
6 | const subscriptions = ({ context }, onData) => {
7 | const { Meteor } = context;
8 | _.keys(context.configs).map((module) => {
9 | Meteor.subscribe(`${module}.configs.user`);
10 | });
11 | onData(null, {});
12 | };
13 |
14 | const depsToProps = (context, actions) => ({
15 | context
16 | });
17 |
18 | export default composeAll(
19 | withTracker(subscriptions),
20 | useDeps(depsToProps)
21 | )(Layout);
22 |
--------------------------------------------------------------------------------
/maodou/wechat/client/components/sign-in-button.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export const UIState = {
4 | IDLE: 'idle',
5 | LOGGING_IN: 'loggingIn',
6 | LOGGED_IN: 'loggedIn',
7 | ERROR: 'error'
8 | };
9 |
10 | export default (props) => {
11 | switch (props.uiState) {
12 | case UIState.IDLE:
13 | return 微信一键登录;
14 |
15 | case UIState.LOGGED_IN:
16 | return 已登录;
17 |
18 | case UIState.LOGGING_IN:
19 | return 正在登录...;
20 |
21 | default:
22 | return ;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/client/containers/users/register.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {useDeps} from 'react-simple-di';
3 | import {composeAll, withTracker} from 'react-komposer-plus';
4 |
5 | import Register from '../../components/users/register';
6 |
7 | function composer({context}, onData) {
8 | onData(null, {
9 | loggedIn: !!context.Meteor.user()
10 | });
11 | }
12 |
13 | const depsToProps = (context, actions) => ({
14 | context,
15 | dispatch: context.dispatch,
16 | createNewUser: actions.users.createNewUser,
17 | });
18 |
19 | export default composeAll(
20 | withTracker(composer),
21 | useDeps(depsToProps)
22 | )(Register);
23 |
--------------------------------------------------------------------------------
/client/containers/users/reset-password.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {useDeps} from 'react-simple-di';
3 | import {composeAll} from 'react-komposer-plus';
4 |
5 | import ResetPassword from '../../components/users/reset-password';
6 |
7 | const bindTokenToAction = C => props => {
8 | const {token, resetPassword, ...other} = props;
9 | return ;
10 | };
11 |
12 | const depsToProps = (context, actions) => ({
13 | resetPassword: actions.users.resetPassword
14 | });
15 |
16 | export default composeAll(
17 | bindTokenToAction,
18 | useDeps(depsToProps)
19 | )(ResetPassword);
20 |
--------------------------------------------------------------------------------
/maodou/wechat/server/middleware.js:
--------------------------------------------------------------------------------
1 | import express from 'express';
2 | import wechat from 'wechat';
3 |
4 | export default function(context) {
5 | const app = express();
6 |
7 | app.use('/wechat', wechat({
8 | // TODO: use packages, not context
9 | token: context.privateConfigs.wechat.token,
10 | appid: context.configs.wechat.appId,
11 | encodingAESKey: context.privateConfigs.wechat.encodingAESKey
12 | }).middlewarify());
13 |
14 | app.use('/wechat', function (req, res, next) {
15 | res.end(); // looks like there's a next('route') call in the above middleware, which needs to be terminated here
16 | });
17 |
18 | return app;
19 | }
20 |
--------------------------------------------------------------------------------
/server/lib/middlewares/middleware.js:
--------------------------------------------------------------------------------
1 | import {Picker} from 'meteor/meteorhacks:picker';
2 |
3 | export default {
4 | moduleWillLoad(module) {
5 | if (module.middleware) {
6 | if (typeof module.middleware !== 'function') {
7 | const message = 'Module\'s middleware field should be an function.';
8 | throw new Error(message);
9 | }
10 | this._middlewareFns = this._middlewareFns || [];
11 | this._middlewareFns.push(module.middleware);
12 | }
13 | },
14 |
15 | moduleWillInit() {
16 | this._middlewareFns && this._middlewareFns.forEach(middlewareFn => Picker.middleware(middlewareFn(this.context)));
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/maodou/singlePages/server/index.js:
--------------------------------------------------------------------------------
1 | import collections from '../lib/collections';
2 | import configs from '../lib/configs';
3 | import publications from './publications';
4 | import methods from './methods';
5 | import templates from '../templates';
6 |
7 | export default {
8 | configs,
9 | collections,
10 | publications,
11 | methods,
12 | init (context) {
13 | const { Collections } = context;
14 | if (!Collections.Packages.findOne({ name: 'singlePages' })) {
15 | Collections.Packages.insert({
16 | name: 'singlePages',
17 | configs: context.configs.singlePages || {}
18 | });
19 | }
20 | templates();
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/client/containers/users/login-form.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {useDeps} from 'react-simple-di';
3 | import {composeAll, withTracker} from 'react-komposer-plus';
4 |
5 | import EmailEnrollmentForm from '../../components/users/login-form';
6 |
7 | function composer({context}, onData) {
8 | onData(null, {
9 | loggingIn: context.Meteor.loggingIn(),
10 | loggedIn: !!context.Meteor.user()
11 | });
12 | }
13 |
14 | const depsToProps = (context, actions) => ({
15 | context,
16 | loginWithPassword: actions.users.loginWithPassword
17 | });
18 |
19 | export default composeAll(
20 | withTracker(composer),
21 | useDeps(depsToProps)
22 | )(EmailEnrollmentForm);
23 |
--------------------------------------------------------------------------------
/client/components/users/login.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import WeChatSignIn from 'maodou/wechat/client/containers/sign-in-button';
3 | import EmailForm from '../../containers/users/email-enrollment-form';
4 | import LoginForm from '../../containers/users/login-form';
5 |
6 | export default (props) => (
7 |
8 | {/* props.isWechatVerified ?
: props.notWechat ?
:
*/}
9 | {/* props.avatar ?

:
*/}
10 | {
}
11 | {
}
12 |
13 | );
14 |
--------------------------------------------------------------------------------
/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "public": {
3 | "core": {
4 | "appName": "创投加速器",
5 | "appLogo": "/images/logo.png",
6 | "ownerEmail": "app@example.com"
7 | },
8 | "posts": {
9 | "showType": "list",
10 | "categories": ["cate1", "cate2", "cate3"],
11 | "UI": {
12 | "categoriesPosition": "top"
13 | }
14 | },
15 | "wechat": {
16 | "appId": ""
17 | }
18 | },
19 | "core": {
20 | "qiniu": {
21 | "ACCESS_KEY": "Du_Lx2xanFiDZE0NBFyvjMhGzE9KYY2rrUiiDzbI",
22 | "SECRET_KEY": "6JLS8xc9xGCws07A8WYM0E8Hg0rt0Qd_mLhfLlWi"
23 | }
24 | },
25 | "wechat": {
26 | "appSecret": ""
27 | },
28 | "mailUrl": ""
29 | }
30 |
--------------------------------------------------------------------------------
/client/containers/users/email-enrollment-form.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {useDeps} from 'react-simple-di';
3 | import {composeAll, withTracker} from 'react-komposer-plus';
4 |
5 | import EmailEnrollmentForm from '../../components/users/email-enrollment-form';
6 |
7 | function composer({context}, onData) {
8 | onData(null, {
9 | loggingIn: context.Meteor.loggingIn(),
10 | loggedIn: !!context.Meteor.user()
11 | });
12 | }
13 |
14 | const depsToProps = (context, actions) => ({
15 | context,
16 | enrollWithEmail: actions.users.enrollWithEmail
17 | });
18 |
19 | export default composeAll(
20 | withTracker(composer),
21 | useDeps(depsToProps))
22 | (EmailEnrollmentForm);
23 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/components/admin/singlePagesConf/config/content.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import wangEditor from 'wangeditor';
3 | import { $ } from 'meteor/jquery';
4 |
5 | export default class Content extends Component {
6 | render () {
7 | return (
8 |
12 | );
13 | }
14 | }
15 |
16 | Content.propTypes = {
17 | content: PropTypes.string
18 | };
19 |
20 | // 编辑器样式
21 | const style = {
22 | width: '100%',
23 | height: '800px'
24 | };
25 | //
26 |
--------------------------------------------------------------------------------
/maodou/singlePages/templates/index.js:
--------------------------------------------------------------------------------
1 | import SinglePages from '../lib/collections/singlePages';
2 |
3 | import simpleConfig from './simple';
4 | import creativeConfig from './creative';
5 | import tenseConfig from './tense';
6 |
7 | const register = (config) => {
8 | const template = SinglePages.findOne({templateName: config.templateName});
9 |
10 | if (template) {
11 | return null;
12 | }
13 |
14 | SinglePages.insert({
15 | defaultTemplate: true,
16 | ...config
17 | });
18 |
19 | SinglePages.insert({
20 | defaultTemplate: false,
21 | ...config
22 | });
23 |
24 | };
25 |
26 | export default () => {
27 | register(simpleConfig);
28 | register(creativeConfig);
29 | register(tenseConfig);
30 | };
31 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/containers/admin/bizplan.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di'
2 | import { withTracker, composeAll } from 'react-komposer-plus'
3 |
4 | import Bizplan from '../../components/admin/bizplan'
5 |
6 | const data = ({ context, params }, onData) => {
7 | const { Meteor, Collections } = context
8 | if (Meteor.subscribe('bizplans.list').ready()) {
9 | const bizplan = Collections.Bizplans.findOne({ _id: params.id })
10 |
11 | onData(null, {
12 | bizplan
13 | })
14 | }
15 | }
16 |
17 | const depsToProps = (context, actions) => ({
18 | context,
19 | dispatch: context.dispatch
20 | })
21 |
22 | export default composeAll(
23 | withTracker(data),
24 | useDeps(depsToProps)
25 | )(Bizplan)
26 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/containers/singleBizplan.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di'
2 | import { withTracker, composeAll } from 'react-komposer-plus'
3 |
4 | import SingleBizplan from '../components/singleBizplan'
5 |
6 | const data = ({ context, params }, onData) => {
7 | const { Meteor, Collections } = context
8 | if (Meteor.subscribe('bizplans.list').ready()) {
9 | const bizplan = Collections.Bizplans.findOne({ _id: params.id})
10 | onData(null, {
11 | bizplan
12 | })
13 | }
14 | }
15 |
16 | const depsToProps = (context, actions) => ({
17 | context,
18 | dispatch: context.dispatch
19 | })
20 |
21 | export default composeAll(
22 | withTracker(data),
23 | useDeps(depsToProps)
24 | )(SingleBizplan)
25 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/admin-routes.js:
--------------------------------------------------------------------------------
1 | import BizplansAdmin from './components/admin';
2 | import BizplansList from './containers/admin/bizplansList';
3 | import Bizplan from './containers/admin/bizplan';
4 |
5 | export default function (injectDeps, { configs }) {
6 | const routes = [
7 | {path: 'bizplans', component: BizplansAdmin, childRoutes: []},
8 | {path: 'bizplan/:id', component: Bizplan, childRoutes: []}
9 | ];
10 |
11 | const subMenu = configs.bizplans.subMenu;
12 | const subMenuComponents = [
13 | BizplansList
14 | ];
15 | subMenu.map((menu, index) => {
16 | routes[0].childRoutes.push({
17 | path: menu.href,
18 | component: subMenuComponents[index]
19 | });
20 | });
21 | return routes;
22 | }
23 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/admin-routes.js:
--------------------------------------------------------------------------------
1 | import SinglePagesAdmin from './components/admin';
2 | import SinglePagesList from './containers/admin/singlePagesList';
3 | import SinglePagesConf from './containers/admin/singlePagesConf';
4 |
5 | export default function (injectDeps, { configs }) {
6 | const routes = [
7 | {path: 'singlePages', component: SinglePagesAdmin, childRoutes: []}
8 | ];
9 |
10 | const subMenu = configs.singlePages.subMenu;
11 | const subMenuComponents = [
12 | SinglePagesList,
13 | SinglePagesConf
14 | ];
15 | subMenu.map((menu, index) => {
16 | routes[0].childRoutes.push({
17 | path: menu.href,
18 | component: subMenuComponents[index]
19 | });
20 | });
21 |
22 | return routes;
23 | }
24 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/containers/bizplansList.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di'
2 | import { withTracker, composeAll } from 'react-komposer-plus'
3 |
4 | import BizplansList from '../components/bizplansList'
5 |
6 | const data = ({ context }, onData) => {
7 | const { Meteor, Collections } = context
8 | if (Meteor.subscribe('bizplans.list').ready()) {
9 | const bizplans = Collections.Bizplans.find({}, { sort: { createdAt: -1 } }).fetch()
10 |
11 | onData(null, {
12 | bizplans
13 | })
14 | }
15 | }
16 |
17 | const depsToProps = (context, actions) => ({
18 | context,
19 | dispatch: context.dispatch
20 | })
21 |
22 | export default composeAll(
23 | withTracker(data),
24 | useDeps(depsToProps)
25 | )(BizplansList)
26 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_projects.scss:
--------------------------------------------------------------------------------
1 | .projects .project-label {
2 | font-weight: 600;
3 | }
4 |
5 | .projects .hpanel .panel-body {
6 | border-bottom: none;
7 | }
8 |
9 | .projects .hpanel:last-child .panel-body {
10 | border-bottom: 1px solid $border-color;
11 | }
12 |
13 | .projects .hpanel:last-child .panel-body{
14 | border-bottom: 1px solid $border-color;
15 | }
16 |
17 | .projects .hpanel h4 a {
18 | color: $color-text;
19 | }
20 |
21 | .projects .project-people img {
22 | width: 28px;
23 | height: 28px;
24 | margin-left: 2px;
25 | margin-bottom: 4px;
26 | }
27 |
28 | .projects .project-info {
29 | text-align: right;
30 | }
31 |
32 | @media(max-width:768px) {
33 | .projects .project-info {
34 | text-align: left;
35 | }
36 | }
--------------------------------------------------------------------------------
/maodou/singlePages/client/components/admin/singlePagesConf/config/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 |
3 | import Section from '../../../../containers/admin/singlePagesConf/config/section';
4 | import Content from '../../../../containers/admin/singlePagesConf/config/content';
5 | import Iframe from './iframe';
6 |
7 |
8 | export default class Config extends Component {
9 | render () {
10 | const { selectedSection } = this.props;
11 |
12 | return (
13 |
14 |
15 |
16 |
17 | { selectedSection ?
:
}
18 |
19 | );
20 | }
21 | }
22 |
23 | Config.propTypes = {
24 | selectedSection: PropTypes.string
25 | };
26 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/components/admin/singlePagesConf/preview.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes} from 'react';
2 |
3 | export default class Preview extends Component {
4 | render () {
5 | const { sections } = this.props;
6 |
7 | return (
8 |
9 |
10 | {sections.map((section) =>
11 | this.renderContent(section)
12 | )}
13 |
14 |
15 | );
16 | }
17 |
18 | renderContent(section) {
19 | return section.display ?
20 | :
21 | null;
22 | }
23 | }
24 |
25 | Preview.propTypes = {
26 | sections: PropTypes.array
27 | };
28 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es6: true,
5 | node: true,
6 | meteor: true
7 | },
8 | extends: [
9 | 'eslint:recommended',
10 | 'plugin:meteor/recommended',
11 | 'plugin:react/recommended'
12 | ],
13 | installedESLint: true,
14 | parserOptions: {
15 | ecmaFeatures: {
16 | experimentalObjectRestSpread: true,
17 | jsx: true
18 | },
19 | sourceType: 'module'
20 | },
21 | plugins: [
22 | 'react',
23 | 'meteor'
24 | ],
25 | rules: {
26 | indent: [2, 2, { SwitchCase: 1 }],
27 | quotes: [2, 'single'],
28 | semi: [2, 'always'],
29 | 'no-unused-vars': 1,
30 | 'no-console': 1,
31 | 'react/prop-types': 1, // disabled for dev
32 | 'react/no-danger': 0
33 | }
34 | };
35 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/containers/admin/bizplansList.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di'
2 | import { withTracker, composeAll } from 'react-komposer-plus'
3 |
4 | import BizplansList from '../../components/admin/bizplansList'
5 |
6 | const data = ({ context }, onData) => {
7 | const { Meteor, Collections } = context
8 | if (Meteor.subscribe('bizplans.list').ready()) {
9 | const bizplans = Collections.Bizplans.find({}, { sort: { createdAt: -1 } }).fetch()
10 |
11 | onData(null, {
12 | bizplans
13 | })
14 | }
15 | }
16 |
17 | const depsToProps = (context, actions) => ({
18 | context,
19 | dispatch: context.dispatch,
20 | ...actions.bizplans
21 | })
22 |
23 | export default composeAll(
24 | withTracker(data),
25 | useDeps(depsToProps)
26 | )(BizplansList)
27 |
--------------------------------------------------------------------------------
/maodou/wechat/server/index.js:
--------------------------------------------------------------------------------
1 | import configs from '../configs';
2 | import publications from './publications';
3 | import privateConfigs from 'server/configs/wechat';
4 | import methods from './methods';
5 |
6 | // Uncomment middleware if you need to process messages and events
7 | // import middleware from './middleware';
8 |
9 | export default {
10 | configs,
11 | publications,
12 | privateConfigs,
13 | // middleware,
14 | methods,
15 | init(context) {
16 | const { Collections } = context;
17 | if (!Collections.Packages.findOne({ name: 'wechat' })) {
18 | Collections.Packages.insert({
19 | name: 'wechat',
20 | configs: context.configs.wechat || {},
21 | privateConfigs: context.privateConfigs.wechat || {}
22 | });
23 | }
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_social_board.scss:
--------------------------------------------------------------------------------
1 | .social-board {
2 |
3 | .social-profile img {
4 | height: 42px;
5 | width: 42px;
6 | border-radius: 50%;
7 | }
8 |
9 | .social-profile h5 {
10 | margin-top: 5px;
11 | margin-bottom: 0px;
12 | }
13 |
14 | .social-form {
15 | margin: 10px 0;
16 | }
17 |
18 | .social-form input {
19 | font-size: 12px;
20 | padding: 2px 12px;
21 | height: 28px;
22 | }
23 |
24 | }
25 |
26 | .social-talk .social-profile img {
27 | height: 32px;
28 | width: 32px;
29 | border-radius: 50%;
30 | }
31 |
32 | .social-talk .text-muted {
33 | color: lighten($color-text, 25%);
34 | }
35 |
36 | .social-talk {
37 | margin-bottom: 10px;
38 | }
39 |
40 | .social-talk .social-content {
41 | margin-top: 2px;
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/maodou/events/client/admin-routes.js:
--------------------------------------------------------------------------------
1 | import EventsAdmin from './components/admin';
2 | import EventsList from './containers/admin/eventsList';
3 | import EventsAdd from './containers/admin/eventsAdd';
4 | import EventsEdit from './containers/admin/eventsEdit';
5 |
6 | export default function (injectDeps, { configs }) {
7 | const routes = [
8 | {path: 'events', component: EventsAdmin, childRoutes:[]},
9 | {path: 'event/edit/:id', component: EventsEdit, childRoutes:[]}
10 | ];
11 |
12 | const subMenu = configs.events.subMenu;
13 | const subMenuComponents = [
14 | EventsList,
15 | EventsAdd,
16 | ];
17 | subMenu.map((menu, index) => {
18 | routes[0].childRoutes.push({
19 | path: menu.href,
20 | component: subMenuComponents[index]
21 | });
22 | });
23 |
24 | return routes;
25 | }
26 |
--------------------------------------------------------------------------------
/client/lib/middlewares/i18n.js:
--------------------------------------------------------------------------------
1 | export default function(langs) {
2 | return {
3 | moduleWillLoad(module) {
4 | if (module.i18n) {
5 | if (typeof module.i18n !== 'object') {
6 | const message = "Module's i18n field should be an object.";
7 | throw new Error(message);
8 | }
9 |
10 | this.i18n = this.i18n || {};
11 | for (const lang of langs) {
12 | this.i18n[lang] = this.i18n[lang] || {};
13 | Object.assign(this.i18n[lang], module.i18n[lang]);
14 | }
15 | }
16 | },
17 | moduleWillInit() {
18 | const lang = localStorage.getItem('site-lang') || 'zhCN';
19 | this.context.T.setTexts(this.i18n[lang]);
20 | this.context.dispatch(this.actions.core.setLanguage(lang));
21 | this.context.i18n = this.i18n;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/maodou/wechat/client/components/admin/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default (props) => (
4 |
22 | );
23 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_grid.scss:
--------------------------------------------------------------------------------
1 | .ngHeaderCell {
2 | border-right: none;
3 | border-bottom: 1px solid $border-color;
4 | }
5 | .ngCell {
6 | border-right: none;
7 | }
8 | .ngTopPanel {
9 | background: #fff;
10 | }
11 | .ngRow.even {
12 | background: #f9f9f9;
13 | }
14 | .ngRow.selected {
15 | background: darken($color-background, 4%);
16 | }
17 | .ngRow {
18 | border-bottom: 1px solid $border-color;
19 | }
20 | .ngCell {
21 | background-color: transparent;
22 | }
23 | .ngHeaderCell {
24 | border-right: none;
25 | }
26 | .gridStyle {
27 | border: 1px solid $border-color;
28 | height: 400px
29 | }
30 | .show-grid [class^="col-"] {
31 | background-color: $color-background !important;
32 | border: 1px solid #ddd;
33 | padding-bottom: 10px;
34 | padding-top: 10px;
35 | }
36 |
37 | .show-grid {
38 | margin: 15px 0;
39 | }
--------------------------------------------------------------------------------
/maodou/posts/client/components/tabs.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default class extends React.Component {
4 |
5 | render() {
6 | return (
7 |
8 |
9 | {
10 | this.props.configs ?
11 | this.props.configs.categories.map((cate, i) =>
12 | - this.props.dispatch(this.props.changeCategory(e, cate))}
15 | className={`${cate===this.props.category ? 'active' : ''} flex-item`}
16 | >
17 | {cate}
18 |
19 | ) :
20 |
21 | }
22 |
23 |
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/containers/admin/singlePagesList.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { composeAll, withTracker } from 'react-komposer-plus';
3 |
4 | import singlePagesList from '../../components/admin/singlePagesList';
5 |
6 | const data = ({ context }, onData) => {
7 | const { Meteor, Collections } = context;
8 | if (Meteor.subscribe('singlePages.list').ready()) {
9 | const singlePages = Collections.SinglePages.find({}, { sort: { createdAt: 1 } }).fetch();
10 | onData(null, {singlePages});
11 | }
12 | };
13 |
14 | const depsToProps = (context, actions) => {
15 | return {
16 | context,
17 | setTemplate: actions.singlePages.setTemplate,
18 | dispatch: context.dispatch
19 | };
20 | };
21 |
22 |
23 | export default composeAll(
24 | withTracker(data),
25 | useDeps(depsToProps)
26 | )(singlePagesList);
27 |
--------------------------------------------------------------------------------
/maodou/customers/client/admin-routes.js:
--------------------------------------------------------------------------------
1 | import CustomersAdmin from './components/admin';
2 | import CustomersList from './containers/admin/customersList';
3 | import CustomersAdd from './containers/admin/customersAdd';
4 | import CustomersEdit from './containers/admin/customersEdit';
5 |
6 | export default function (injectDeps, { configs }) {
7 | const routes = [
8 | {path: 'customers', component: CustomersAdmin, childRoutes:[]},
9 | {path: 'customers/edit/:id', component: CustomersEdit, childRoutes:[]}
10 | ];
11 |
12 | const subMenu = configs.customers.subMenu;
13 | const subMenuComponents = [
14 | CustomersList,
15 | CustomersAdd
16 | ];
17 | subMenu.map((menu, index) => {
18 | routes[0].childRoutes.push({
19 | path: menu.href,
20 | component: subMenuComponents[index]
21 | });
22 | });
23 |
24 | return routes;
25 | }
26 |
--------------------------------------------------------------------------------
/client/containers/admin/layout/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withTracker, composeAll } from 'react-komposer-plus';
3 | import { browserHistory } from 'react-router';
4 | import Layout from '../../../components/admin/layout';
5 |
6 | const subscriptions = ({ context }, onData) => {
7 | const { Meteor, toastr } = context;
8 | Meteor.call('validateAdmin', Meteor.user(), (err) => {
9 | if (err) {
10 | browserHistory.push('/');
11 | toastr.error("当前用户无权访问");
12 | } else {
13 | _.keys(context.configs).map((module) => {
14 | Meteor.subscribe(`${module}.configs`)
15 | })
16 | onData(null, {})
17 | }
18 | })
19 | };
20 |
21 | const depsToProps = (context, actions) => ({
22 | context
23 | });
24 |
25 | export default composeAll(
26 | withTracker(subscriptions),
27 | useDeps(depsToProps)
28 | )(Layout);
29 |
--------------------------------------------------------------------------------
/maodou/posts/client/admin-routes.js:
--------------------------------------------------------------------------------
1 | import PostsAdmin from './components/admin';
2 | import PostsList from './containers/admin/postsList';
3 | import PostsEdit from './containers/admin/postsEdit';
4 | import PostsAdd from './containers/admin/postsAdd';
5 | import PostsConfigure from './containers/admin/postsConfigure';
6 |
7 | export default function (injectDeps, { configs }) {
8 | const routes = [
9 | {path: 'posts', component: PostsAdmin, childRoutes:[]},
10 | {path: 'post/edit/:id', component: PostsEdit, childRoutes: []}
11 | ];
12 |
13 | const subMenu = configs.posts.subMenu;
14 | const subMenuComponents = [
15 | PostsConfigure,
16 | PostsList,
17 | PostsAdd
18 | ];
19 | subMenu.map((menu, index) => {
20 | routes[0].childRoutes.push({
21 | path: menu.href,
22 | component: subMenuComponents[index]
23 | });
24 | });
25 |
26 | return routes;
27 | }
28 |
--------------------------------------------------------------------------------
/client/main.scss:
--------------------------------------------------------------------------------
1 | @import "{}/node_modules/bootstrap-sass/assets/stylesheets/_bootstrap.scss";
2 | @import "{}/node_modules/sweetalert2/src/sweetalert2.scss";
3 | @import "{}/node_modules/toastr/toastr.scss";
4 | @import "{}/node_modules/pixeden-stroke-7-icon/pe-icon-7-stroke/scss/pe-icon-7-stroke.scss";
5 | @import "{}/node_modules/ladda/css/ladda.scss";
6 | @import "./lib/imports/theme-homer/style.scss";
7 | /* @import "./lib/imports/toastr/toastr.scss"; */
8 |
9 | /* Overwrites */
10 | #navigation {
11 | z-index: 1000;
12 | height: 100%;
13 | background: #f7f9fa;
14 | }
15 |
16 | #wrapper {
17 | position: static;
18 | }
19 | .admin-package-wrapper {
20 | padding: 5px 15px;
21 | }
22 | .splash {
23 | position: static;
24 | background: none;
25 | .spinner div {
26 | margin: 1px;
27 | }
28 | }
29 |
30 | .wangEditor-container {
31 | .wangEditor-txt {
32 | height: 640px !important;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/maodou/events/server/methods/index.js:
--------------------------------------------------------------------------------
1 | export default (context) => {
2 | const { Meteor, Collections } = context;
3 | const { Events } = Collections;
4 | Meteor.methods({
5 | 'events.get'() {
6 | return Events.find().fetch();
7 | },
8 | 'events.get.single'(id) {
9 | const event = Events.findOne(id);
10 | if (!event) {
11 | throw new Meteor.Error('404', 'not found');
12 | }
13 | return event;
14 | },
15 | 'events.add'(title, coverUrl, time, location, limit, unit, fee, desc) {
16 | Events.insert({
17 | title,
18 | coverUrl,
19 | time,
20 | location,
21 | limit,
22 | unit,
23 | fee,
24 | desc
25 | });
26 | },
27 | 'events.delete'(id) {
28 | Events.remove(id);
29 | },
30 | 'events.edit'(id, data) {
31 | Events.update(id, { $set: data});
32 | }
33 | });
34 | };
35 |
--------------------------------------------------------------------------------
/maodou/posts/client/containers/admin/postsList.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withTracker, composeAll } from 'react-komposer-plus';
3 | import PostsList from '../../components/admin/postsList';
4 |
5 | const data = ({ context }, onData) => {
6 | const { Meteor, Collections } = context;
7 | if (Meteor.subscribe('posts.list').ready()) {
8 | const posts = Collections.Posts.find({}).fetch();
9 | document.title = '文章列表';
10 | onData(null, {
11 | posts: { status: 'ready', data: posts }
12 | });
13 | } else {
14 | onData(null, {
15 | posts: { status: 'pending', data: [] }
16 | });
17 | }
18 | };
19 |
20 | const depsToProps = (context, actions) => ({
21 | context,
22 | dispatch: context.dispatch,
23 | deletePost: actions.posts.deletePost
24 | });
25 |
26 | export default composeAll(
27 | withTracker(data),
28 | useDeps(depsToProps)
29 | )(PostsList);
30 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/containers/bizplansAdd/uploadButton.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di'
2 | import { withLifecycle, composeAll } from 'react-komposer-plus'
3 | import RegistUploader from '../../helpers/uploader'
4 |
5 | import UploadButton from '../../components/bizplansAdd/uploadButton'
6 |
7 | const lifeCycle = {
8 | componentDidMount () {
9 | const { qiniuDomain, dispatch, uploadingPDF, addPDF, uploadedPDF } = this.props
10 | const Uploader = RegistUploader(qiniuDomain, dispatch, uploadingPDF, addPDF, uploadedPDF)
11 | Uploader('bizplanPDF')
12 | }
13 | }
14 |
15 | const depsToProps = (context, actions) => {
16 | return {
17 | context,
18 | dispatch: context.dispatch,
19 | qiniuDomain: context.configs.core.qiniu.DOMAIN_NAME,
20 | ...actions.bizplans
21 | }
22 | }
23 |
24 | export default composeAll(
25 | withLifecycle(lifeCycle),
26 | useDeps(depsToProps)
27 | )(UploadButton)
28 |
--------------------------------------------------------------------------------
/maodou/posts/client/containers/post.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 | import { browserHistory } from 'react-router'
4 |
5 | import Post from '../components/post';
6 |
7 | const initData = ({ context, params }, onData) => {
8 | const { Meteor, toastr } = context;
9 | const postId = params.id;
10 | Meteor.call('posts.get.single', postId, (err, post) => {
11 | if (err) {
12 | if (err.error === '404'){
13 | toastr.error("文章没有找到,返回到原来页面");
14 | browserHistory.push('/posts');
15 | }
16 | } else {
17 | document.title = post.title;
18 | onData(null, { post });
19 | }
20 | });
21 | onData(null, {});
22 | };
23 |
24 | const depsToProps = (context, actions) => ({
25 | context
26 | });
27 |
28 | export default composeAll(
29 | compose(initData),
30 | useDeps(depsToProps)
31 | )(Post);
32 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_contact.scss:
--------------------------------------------------------------------------------
1 | .contact-panel h3 {
2 | margin-bottom: 2px;
3 | }
4 |
5 | .contact-panel h3 a {
6 | color: inherit;
7 | }
8 |
9 | .contact-panel p {
10 | font-size: 11px;
11 | line-height: 16px;
12 | margin-bottom: 0;
13 | }
14 |
15 | .contact-panel img {
16 | width: 76px;
17 | height: 76px;
18 | }
19 |
20 | .contact-footer {
21 | padding: 0 15px;
22 | }
23 |
24 | .contact-stat span {
25 | font-size: 10px;
26 | font-weight: 500;
27 | display: block;
28 | color: lighten($color-text, 20%);
29 | text-transform: uppercase;
30 | }
31 |
32 | .contact-stat {
33 | padding: 8px 0px;
34 | text-align: center;
35 | }
36 |
37 | .contact-panel:hover .panel-body {
38 | -webkit-animation-duration: 0.5s;
39 | animation-duration: 0.5s;
40 | -webkit-animation-fill-mode: both;
41 | animation-fill-mode: both;
42 | animation-name: pulse;
43 | -webkit-animation-name: pulse;
44 | z-index: 1;
45 | }
46 |
--------------------------------------------------------------------------------
/client/context.js:
--------------------------------------------------------------------------------
1 | import {Meteor} from 'meteor/meteor';
2 | import {Accounts} from 'meteor/accounts-base';
3 | import {Tracker} from 'meteor/tracker';
4 | import { Roles } from 'meteor/alanning:roles';
5 | import swal from 'sweetalert2';
6 | import toastr from 'toastr';
7 | import T from 'i18n-react';
8 |
9 | toastr.options = {
10 | "closeButton": true,
11 | "debug": false,
12 | "progressBar": false,
13 | "positionClass": "toast-top-right",
14 | "preventDuplicates": true,
15 | "newestOnTop": true,
16 | "onclick": null,
17 | "showDuration": "300",
18 | "hideDuration": "500",
19 | "timeOut": "1000",
20 | "extendedTimeOut": "500",
21 | "showEasing": "swing",
22 | "hideEasing": "linear",
23 | "showMethod": "fadeIn",
24 | "hideMethod": "fadeOut"
25 | }
26 |
27 | export default function() {
28 | return {
29 | Meteor,
30 | Accounts,
31 | Tracker,
32 | Roles,
33 | swal,
34 | toastr,
35 | T
36 | };
37 | }
38 |
--------------------------------------------------------------------------------
/maodou/posts/server/index.js:
--------------------------------------------------------------------------------
1 | import collections from '../lib/collections';
2 | import permissions from './permissions';
3 | import publications from './publications';
4 | import methods from './methods';
5 | import configs from '../lib/configs';
6 | import privateConfigs from 'server/configs/posts';
7 | import seeds from './seed.js';
8 |
9 | export default {
10 | configs,
11 | privateConfigs,
12 | collections,
13 | permissions,
14 | publications,
15 | methods,
16 | init(context) {
17 | const { Collections } = context;
18 | if (!Collections.Packages.findOne({ name: 'posts' })) {
19 | Collections.Packages.insert({
20 | name: 'posts',
21 | configs: context.configs.posts || {}
22 | });
23 | }
24 | if (Collections.Posts.find().count() < seeds.data.length) {
25 | for (let i = 0; i < seeds.data.length; i++) {
26 | Collections.Posts.insert(seeds.data[i]);
27 | }
28 | }
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/client/lib/compose-with-redux.js:
--------------------------------------------------------------------------------
1 | import {compose} from 'react-komposer-plus';
2 |
3 | function composeReduxBase(fn, props, onData) {
4 | if (!props.context) {
5 | throw new Error('No context passed as prop.');
6 | }
7 |
8 | const context = typeof props.context === 'function' ? props.context() : props.context;
9 | const Store = context.Store || context.store;
10 |
11 | if (!Store) {
12 | throw new Error('No store found in the context');
13 | }
14 |
15 | const processState = () => {
16 | try {
17 | const state = Store.getState();
18 | const data = fn(state, props);
19 | onData(null, data);
20 | } catch (ex) {
21 | onData(ex);
22 | }
23 | };
24 |
25 | processState();
26 | return Store.subscribe(processState);
27 | }
28 |
29 | export default function composeWithRedux(fn, L1, E1, options = { displayName: 'WithRedux' }) {
30 | return compose(composeReduxBase.bind(null, fn), L1, E1, options);
31 | }
32 |
--------------------------------------------------------------------------------
/maodou/events/client/containers/event.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withHandlers, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 | import { browserHistory } from 'react-router'
4 |
5 | import Post from '../components/event';
6 |
7 | const initData = ({ context, params }, onData) => {
8 | const { Meteor, toastr } = context;
9 | const eventId = params.id;
10 | Meteor.call('events.get.single', eventId, (err, event) => {
11 | if (err) {
12 | if (err.error === '404'){
13 | toastr.error("活动没有找到,返回到原来页面");
14 | browserHistory.push('/events');
15 | }
16 | } else {
17 | document.title = event.title;
18 | onData(null, { event });
19 | }
20 | });
21 | onData(null, {});
22 | };
23 |
24 | const depsToProps = (context, actions) => ({
25 | context
26 | });
27 |
28 | export default composeAll(
29 | compose(initData),
30 | useDeps(depsToProps)
31 | )(Post);
32 |
--------------------------------------------------------------------------------
/maodou/events/server/index.js:
--------------------------------------------------------------------------------
1 | import collections from '../lib/collections';
2 | import permissions from './permissions';
3 | import publications from './publications';
4 | import methods from './methods';
5 | import configs from '../lib/configs';
6 | import privateConfigs from 'server/configs/events';
7 | import seeds from './seed.js';
8 |
9 | export default {
10 | configs,
11 | privateConfigs,
12 | collections,
13 | permissions,
14 | publications,
15 | methods,
16 | init(context) {
17 | const { Collections } = context;
18 | if (!Collections.Packages.findOne({ name: 'events' })) {
19 | Collections.Packages.insert({
20 | name: 'events',
21 | configs: context.configs.events || {}
22 | });
23 | }
24 | if (Collections.Events.find().count() < seeds.data.length) {
25 | for (let i = 0; i < seeds.data.length; i++) {
26 | Collections.Events.insert(seeds.data[i]);
27 | }
28 | }
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/maodou/posts/client/containers/tabs.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import Tabs from '../components/tabs';
5 |
6 | const subscription = ({ context }, onData) => {
7 | const { Meteor, Collections } = context;
8 | if (Meteor.subscribe('posts.configs.user').ready()) {
9 | const configs = Collections.Packages.findOne({ name: 'posts' }).configs;
10 | onData(null, {
11 | configs
12 | });
13 | } else {
14 | onData(null, {});
15 | }
16 | };
17 |
18 | const mapStateToProps = (state) => ({
19 | category: state.postsCategory
20 | });
21 |
22 | const depsToProps = (context, actions) => ({
23 | context,
24 | dispatch: context.dispatch,
25 | changeCategory: actions.posts.changeCategory
26 | });
27 |
28 | export default composeAll(
29 | withTracker(subscription),
30 | withRedux(mapStateToProps),
31 | useDeps(depsToProps)
32 | )(Tabs);
33 |
--------------------------------------------------------------------------------
/maodou/events/client/containers/events.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withHandlers, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import Events from '../components/events';
5 |
6 | const userEvents = {
7 | deleteEvent({ context }, id, event) {
8 |
9 | }
10 | };
11 |
12 | const subscription = ({ context }, onData) => {
13 | const { Meteor, Collections } = context;
14 | if (Meteor.subscribe('events.list').ready()) {
15 | const events = Collections.Events.find().fetch();
16 | onData(null, {
17 | events: { status: 'ready', data: events }
18 | });
19 | } else {
20 | onData(null, {
21 | events: { status: 'pending', data: [] }
22 | });
23 | }
24 | };
25 |
26 | const depsToProps = (context, actions) => ({
27 | context
28 | });
29 |
30 | export default composeAll(
31 | withHandlers(userEvents),
32 | withTracker(subscription),
33 | useDeps(depsToProps)
34 | )(Events);
35 |
--------------------------------------------------------------------------------
/maodou/events/client/containers/admin/eventsList.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withHandlers, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import EventsList from '../../components/admin/eventsList';
5 |
6 | const subscription = ({ context }, onData) => {
7 | const { Meteor, Collections } = context;
8 | if (Meteor.subscribe('events.list').ready()) {
9 | const data = Collections.Events.find().fetch();
10 | document.title = '活动列表';
11 | onData(null, {
12 | events: { status: 'ready', data }
13 | });
14 | } else {
15 | onData(null, {
16 | events: { status: 'pending', data: [] }
17 | });
18 | }
19 | };
20 |
21 | const depsToProps = (context, actions) => ({
22 | context,
23 | dispatch: context.dispatch,
24 | deleteEvent: actions.events.deleteEvent
25 | });
26 |
27 | export default composeAll(
28 | withTracker(subscription),
29 | useDeps(depsToProps)
30 | )(EventsList);
31 |
--------------------------------------------------------------------------------
/client/containers/users/login.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {useDeps} from 'react-simple-di';
3 | import {composeAll, withTracker, withLifecycle} from 'react-komposer-plus';
4 |
5 | import Login from '../../components/users/login';
6 |
7 | function composer({context}, onData) {
8 | const user = context().Meteor.user();
9 | if (user && Array.isArray(user.emails) && user.emails.length > 0) {
10 | const isWechatVerified = user.profile.headimgurl && user.emails[0].verified;
11 | const isWechat = user.profile.headimgurl || user.city;
12 | const nickname = user.profile.nickname;
13 | const avatar = isWechat ? user.profile.headimgurl : '';
14 | onData(null, {
15 | loggedIn: !!user,
16 | notWechat: !isWechat,
17 | isWechatVerified,
18 | nickname,
19 | avatar
20 | });
21 | } else {
22 | onData(null, {loggedIn: user});
23 | }
24 | }
25 |
26 | export default composeAll(
27 | withTracker(composer),
28 | useDeps()
29 | )(Login);
30 |
--------------------------------------------------------------------------------
/maodou/customers/client/containers/admin/customersAdd.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withHandlers, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import CustomersAdd from '../../components/admin/customersAdd';
5 |
6 | const subscription = ({ context }, onData) => {
7 | const { Meteor, Collections } = context;
8 |
9 | if (Meteor.subscribe('customers.list').ready()) {
10 | const customers = Collections.Customers.find().fetch();
11 | onData(null, {
12 | customers: { status: 'ready', data: customers }
13 | });
14 | } else {
15 | onData(null, {
16 | customers: { status: 'pending', data: [] }
17 | });
18 | }
19 | };
20 |
21 | const depsToProps = (context, actions) => ({
22 | context,
23 | dispatch: context.dispatch,
24 | addCustomer: actions.customers.addCustomer
25 | });
26 |
27 | export default composeAll(
28 | withTracker(subscription),
29 | useDeps(depsToProps)
30 | )(CustomersAdd);
31 |
--------------------------------------------------------------------------------
/maodou/customers/client/containers/admin/customersList.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withHandlers, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import CustomersList from '../../components/admin/customersList';
5 |
6 | const subscription = ({ context }, onData) => {
7 | const { Meteor, Collections } = context;
8 |
9 | if (Meteor.subscribe('customers.list').ready()) {
10 | const customers = Collections.Customers.find().fetch();
11 | onData(null, {
12 | customers: { status: 'ready', data: customers }
13 | });
14 | } else {
15 | onData(null, {
16 | customers: { status: 'pending', data: [] }
17 | });
18 | }
19 | };
20 |
21 | const depsToProps = (context, actions) => ({
22 | context,
23 | dispatch: context.dispatch,
24 | deleteCustomer: actions.customers.deleteCustomer
25 | });
26 |
27 | export default composeAll(
28 | withTracker(subscription),
29 | useDeps(depsToProps)
30 | )(CustomersList);
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # meteor-react-redux-base
2 | BoilerPlate code for meteor-react-redux project
3 |
4 | ## Feature
5 | * Mantra-plus integrated
6 | * Webpack integrated
7 | * Wechat Login supported
8 | * Email binding and verification
9 | * Admin configuration
10 |
11 | ## Usage
12 | First, make sure you have [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [meteor](https://www.meteor.com/install) installed,
13 | Then, enter these commands in your console
14 |
15 | ```
16 | $ git clone https://github.com/maodouio/meteor-react-redux-base.git
17 | $ cd meteor-react-redux-base/
18 | $ npm install
19 | $ meteor --settings settings.json
20 | ```
21 |
22 | ## Docs
23 | * https://docs.maodou.io/ Developer Documentation
24 |
25 | ## Ref
26 | * [maodou-cli](https://github.com/maodouio/maodou-cli) Maodou command line tool
27 | ```
28 | $ npm i -g maodou
29 | $ maodou login
30 | $ maodou create appName
31 | $ maodou deploy
32 | ```
33 | * [maodou.io](https://maodou.io) Maodou official website
34 |
35 |
36 |
--------------------------------------------------------------------------------
/maodou/customers/client/containers/customers.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withHandlers, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import Customers from '../components/customers';
5 |
6 | const userCustomers = {
7 | deleteCustomer({ context }, id, customer) {
8 |
9 | }
10 | };
11 |
12 | const subscription = ({ context }, onData) => {
13 | const { Meteor, Collections } = context;
14 |
15 | if (Meteor.subscribe('customers.list').ready()) {
16 | const customers = Collections.Customers.find().fetch();
17 | onData(null, {
18 | customers: { status: 'ready', data: customers }
19 | });
20 | } else {
21 | onData(null, {
22 | customers: { status: 'pending', data: [] }
23 | });
24 | }
25 | };
26 |
27 | const depsToProps = (context, actions) => ({
28 | context
29 | });
30 |
31 | export default composeAll(
32 | withHandlers(userCustomers),
33 | withTracker(subscription),
34 | useDeps(depsToProps)
35 | )(Customers);
36 |
--------------------------------------------------------------------------------
/maodou/customers/server/methods/index.js:
--------------------------------------------------------------------------------
1 | export default (context) => {
2 | const { Meteor, Collections } = context;
3 | const { Customers } = Collections;
4 | Meteor.methods({
5 | 'customers.get'() {
6 | return Customers.find().fetch();
7 | },
8 | 'customers.get.single'(id) {
9 | const customer = Customers.findOne(id);
10 | if (!customer) {
11 | throw new Meteor.Error('404', 'not found');
12 | }
13 | return customer;
14 | },
15 | 'customers.add'(index, title, category, customerName, salesName, desc, schedule, amount, author) {
16 | Customers.insert({
17 | index,
18 | title,
19 | category,
20 | customerName,
21 | salesName,
22 | desc,
23 | schedule,
24 | amount,
25 | author
26 | });
27 | },
28 | 'customers.edit'(id, data) {
29 | Customers.update(id, {$set:data});
30 | },
31 | 'customers.delete'(id) {
32 | Customers.remove(id);
33 | }
34 | });
35 | };
36 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/containers/bizplansAdd/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di'
2 | import { withLifecycle, withRedux, composeAll } from 'react-komposer-plus'
3 |
4 | import BizplansAdd from '../../components/bizplansAdd'
5 |
6 | const lifeCycle = {
7 | componentWillUnmount () {
8 | const { dispatch, cleanselectedTypes, removePDF } = this.props
9 | dispatch(cleanselectedTypes())
10 | dispatch(removePDF())
11 | }
12 | }
13 |
14 | const mapStateToProps = (state) => {
15 | const { selectedTypes, bizplanPDF, uploading } = state
16 |
17 | return {
18 | selectedTypes,
19 | bizplanPDF,
20 | uploading
21 | }
22 | }
23 |
24 | const depsToProps = (context, actions) => {
25 | return {
26 | context,
27 | dispatch: context.dispatch,
28 | qiniuDomain: context.configs.core.qiniu.DOMAIN_NAME,
29 | ...actions.bizplans
30 | }
31 | }
32 |
33 | export default composeAll(
34 | withLifecycle(lifeCycle),
35 | withRedux(mapStateToProps),
36 | useDeps(depsToProps)
37 | )(BizplansAdd)
38 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/components/bizplansAdd/failedMsg.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | export default class FailedMsg extends Component {
4 | render () {
5 | return (
6 |
7 |
8 |
9 |
10 |
提交失败!
11 |
请确认资料输入是否正确
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | )
21 | }
22 | }
23 |
24 | const styles = {
25 | body: {
26 | textAlign: 'center',
27 | fontSize: '20px',
28 | color: 'black'
29 | },
30 | footer: {
31 | textAlign: 'center'
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/client/containers/admin/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withTracker, withHandlers, composeAll } from 'react-komposer-plus';
3 |
4 | import AdminCore from '../../components/admin';
5 |
6 | const userEvents = {
7 | saveCoreConfigs({ context, saveConfigs }, event) {
8 | event.preventDefault();
9 | const { dispatch } = context;
10 | const configs = {
11 | appName: event.target.appName.value
12 | };
13 | dispatch(saveConfigs(configs));
14 | }
15 | };
16 | const subscriptions = ({ context }, onData) => {
17 | const { Collections } = context;
18 | const corePkg = Collections.Packages.findOne({ name: 'core' });
19 | if (corePkg) {
20 | const appName = corePkg.configs.appName;
21 | onData(null, { appName });
22 | }
23 | };
24 |
25 | const depsToProps = (context, actions) => ({
26 | context,
27 | saveConfigs: actions.core.saveConfigs
28 | });
29 |
30 | export default composeAll(
31 | withHandlers(userEvents),
32 | withTracker(subscriptions),
33 | useDeps(depsToProps)
34 | )(AdminCore);
35 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/containers/admin/singlePagesConf/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withTracker, composeAll, withRedux } from 'react-komposer-plus';
3 | import SinglePagesConf from '../../../components/admin/singlePagesConf';
4 |
5 | const data = ({ context }, onData) => {
6 | const { Meteor, Collections } = context;
7 | if (Meteor.subscribe('singlePages.selected').ready()) {
8 | const singlePage = Collections.SinglePages.findOne({ selected: true });
9 |
10 | onData(null, {
11 | templateName: singlePage.templateName
12 | });
13 | }
14 | };
15 |
16 | const mapStateToProps = ({ selectedSection }) => ({
17 | selectedSection
18 | });
19 |
20 | const depsToProps = (context, actions) => ({
21 | context,
22 | dispatch: context.dispatch,
23 | selectSection: actions.singlePages.selectSection,
24 | changeReturnPrev: actions.singlePages.changeReturnPrev
25 | });
26 |
27 | export default composeAll(
28 | withRedux(mapStateToProps),
29 | withTracker(data),
30 | useDeps(depsToProps)
31 | )(SinglePagesConf);
32 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/components/bizplansAdd/successMsg.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import { Link } from 'react-router'
3 |
4 | export default class SuccessMsg extends Component {
5 | render () {
6 | return (
7 |
8 |
9 |
10 |
11 |
提交成功!
12 |
感谢您的信任,我们会尽快与您联系
13 |
14 |
15 | Close
16 |
17 |
18 |
19 |
20 |
21 | )
22 | }
23 | }
24 |
25 | const styles = {
26 | body: {
27 | paddingTop: '40px',
28 | textAlign: 'center',
29 | fontSize: '20px'
30 | },
31 | footer: {
32 | textAlign: 'center'
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/maodou/customers/client/containers/customer.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 | import { browserHistory } from 'react-router'
4 |
5 | import Customer from '../components/customer';
6 |
7 | const initData = ({ context, params }, onData) => {
8 | const { Meteor, swal } = context;
9 | const customerId = params.id;
10 | Meteor.call('customers.get.single', customerId, (err, customer) => {
11 | if (err) {
12 | if (err.error === '404'){
13 | swal({
14 | title: "Customer Not Found",
15 | text: "Jumping to customer list",
16 | type: "error"
17 | });
18 | browserHistory.push('/customers');
19 | }
20 | } else {
21 | document.title = customer.title;
22 | onData(null, { customer });
23 | }
24 | });
25 | onData(null, {});
26 | };
27 |
28 | const depsToProps = (context, actions) => ({
29 | context
30 | });
31 |
32 | export default composeAll(
33 | compose(initData),
34 | useDeps(depsToProps)
35 | )(Customer);
36 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/reducers/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | selectedTypes (state = [], action) {
3 | const { t } = action
4 | const index = state.indexOf(t)
5 | const newState = [...state]
6 |
7 | if (index === -1) {
8 | newState.push(t)
9 | } else {
10 | newState.splice(index, 1)
11 | }
12 |
13 | switch (action.type) {
14 | case 'SELECT_TYPE':
15 | return newState
16 | case 'CLEAN_SELECTED_TYPES':
17 | return []
18 | default:
19 | return state
20 | }
21 | },
22 | bizplanPDF (state = {}, action) {
23 | const { PDFName, PDFUrl } = action
24 | switch (action.type) {
25 | case 'ADD_PDF':
26 | return {PDFName, PDFUrl}
27 | case 'REMOVE_PDF':
28 | return ''
29 | default:
30 | return state
31 | }
32 | },
33 | uploading (state = false, action) {
34 | switch (action.type) {
35 | case 'UPLOADING_PDF':
36 | return true
37 | case 'UPLOADED_PDF':
38 | return false
39 | default:
40 | return state
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/client/containers/admin/layout/aside.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withHandlers, withTracker, withLifecycle, composeAll } from 'react-komposer-plus';
3 | import Aside from '../../../components/admin/layout/aside';
4 |
5 | const lifeCircle = {
6 | componentDidMount() {
7 | $('#side-menu').metisMenu();
8 | const toggleMenu = () => {
9 | if ($(window).width() < 769) {
10 | $('body').addClass('page-small');
11 | } else {
12 | $('body')
13 | .removeClass('page-small')
14 | .removeClass('show-sidebar');
15 | }
16 | };
17 | toggleMenu();
18 | $(window).resize(function () {
19 | toggleMenu();
20 | });
21 | }
22 | };
23 |
24 | const userEvents = {
25 | handleLink() {
26 | if ($(window).width() < 769) {
27 | $('body').toggleClass('show-sidebar');
28 | }
29 | }
30 | };
31 |
32 | const depsToProps = (context, actions) => ({
33 | context
34 | });
35 |
36 | export default composeAll(
37 | withHandlers(userEvents),
38 | withLifecycle(lifeCircle),
39 | useDeps(depsToProps)
40 | )(Aside);
41 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_login.scss:
--------------------------------------------------------------------------------
1 | body.blank {
2 | background-color: $color-background;
3 | }
4 |
5 | .login-container {
6 | max-width: 420px;
7 | margin:auto;
8 | padding-top: 6%;
9 | }
10 |
11 | .register-container {
12 | max-width: 720px;
13 | margin:auto;
14 | padding-top: 6%;
15 | }
16 |
17 | .lock-container {
18 | max-width: 420px;
19 | margin:auto;
20 | padding-top: 6%;
21 | }
22 |
23 | .error-container {
24 | max-width: 620px;
25 | margin:auto;
26 | padding-top: 6%;
27 | }
28 |
29 | .big-icon {
30 | font-size: 120px;
31 | }
32 |
33 | .error-container h1 {
34 | font-size: 44px;
35 | }
36 |
37 | .back-link {
38 | float: left;
39 | width: 100%;
40 | margin: 10px;
41 | }
42 |
43 | @media(max-width: 420px) {
44 | .login-container, .lock-container {
45 | margin: auto 10px;
46 | }
47 | }
48 |
49 | @media(max-width: 720px) {
50 | .register-container {
51 | margin: auto 10px;
52 | }
53 | .lock-container {
54 | padding-top: 15%;
55 | }
56 | }
57 |
58 | @media(max-width: 620px) {
59 | .error-container {
60 | margin: auto 10px;
61 | }
62 | }
--------------------------------------------------------------------------------
/maodou/posts/client/containers/posts.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import Posts from '../components/posts';
5 |
6 | const subscription = ({ context, category }, onData) => {
7 | const { Meteor, Collections } = context;
8 | const postsPkg = Collections.Packages.findOne({ name: 'posts' }) || {};
9 | if (Meteor.subscribe('posts.list', category).ready()) {
10 | const posts = Collections.Posts.find().fetch();
11 | onData(null, {
12 | posts: { status: 'ready', data: posts },
13 | configs: postsPkg.configs
14 | });
15 | } else {
16 | onData(null, {
17 | posts: { status: 'pending', data: [] },
18 | configs: postsPkg.configs
19 | });
20 | }
21 | };
22 |
23 | const mapStateToProps = (state) => ({
24 | category: state.postsCategory
25 | });
26 |
27 | const depsToProps = (context, actions) => ({
28 | context
29 | });
30 |
31 | export default composeAll(
32 | withTracker(subscription),
33 | withRedux(mapStateToProps),
34 | useDeps(depsToProps)
35 | )(Posts);
36 |
--------------------------------------------------------------------------------
/client/components/home/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default (props) => (
4 |
5 | {renderMaodou()}
6 |
7 | );
8 |
9 | const renderMaodou = () => {
10 | return (
11 |
12 |
13 |
毛豆网简介
14 |
15 |
16 |
毛豆网成立于2014年6月,是一支源自清华的技术创业团队,我们是由一批热爱开源技术,心有教育情怀的年轻人组成,渴望用技术帮助他人,改变世界。
17 |
毛豆网是国内第一家专注于服务内容创业的云平台,为内容创业者提供建站和运维的一站式服务,帮助他们降低技术门槛和运营成本,从而高效地生产优质内容。
18 |
毛豆网目前在北京清华和美国硅谷设有研发中心,核心成员出自清华、人大、浙大等国内一流高校。2016年6月毛豆网获清华x-lab创业DNA基金天使投资。
19 |
去关注
20 |
21 |
22 | );
23 | };
24 |
25 | const styles = {
26 | avatar: {
27 | height: '40px',
28 | width: '40px',
29 | borderRadius: '50%'
30 | },
31 | intro: {
32 | color: '#000',
33 | marginTop: '20px',
34 | fontSize: '16px',
35 | padding: '6px'
36 | }
37 | };
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 maodou.io
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/containers/admin/singlePagesConf/preview.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withTracker, withLifecycle, composeAll } from 'react-komposer-plus';
3 | import _ from 'lodash';
4 | import { $ } from 'meteor/jquery';
5 | import Preview from '../../../components/admin/singlePagesConf/preview';
6 |
7 | const lifeCycle = {
8 | componentDidMount() {
9 | $('#summernote').summernote({
10 | toolbar: []
11 | });
12 | $('#summernote').summernote('disable');
13 | }
14 | };
15 |
16 | const data = ({ context }, onData) => {
17 | const { Meteor, Collections } = context;
18 | if (Meteor.subscribe('singlePages.selected').ready()) {
19 | const singlePage = Collections.SinglePages.findOne({ selected: true });
20 | const sortedSections = _.sortBy(singlePage.sections, ['index']);
21 |
22 | onData(null, {
23 | ...singlePage,
24 | sections: sortedSections
25 | });
26 | }
27 | };
28 |
29 | const depsToProps = (context) => ({
30 | context,
31 | });
32 |
33 | export default composeAll(
34 | withLifecycle(lifeCycle),
35 | withTracker(data),
36 | useDeps(depsToProps)
37 | )(Preview);
38 |
--------------------------------------------------------------------------------
/maodou/wechat/client/containers/admin/index.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withTracker, withHandlers, composeAll } from 'react-komposer-plus';
3 |
4 | import WechatAdmin from '../../components/admin';
5 |
6 | const userEvents = {
7 | saveWechatConfigs({ context, saveConfigs }, event) {
8 | event.preventDefault();
9 | const { dispatch } = context;
10 | const configs = {
11 | appId: event.target.appId.value,
12 | appSecret: event.target.appSecret.value
13 | };
14 | dispatch(saveConfigs(configs));
15 | }
16 | };
17 | const subscriptions = ({ context }, onData) => {
18 | const { Collections } = context;
19 | const wechatPkg = Collections.Packages.findOne({ name: 'wechat' });
20 | if (wechatPkg) {
21 | const appId = wechatPkg.configs.appId;
22 | const appSecret = wechatPkg.privateConfigs.appSecret;
23 | onData(null, { appId, appSecret });
24 | }
25 | };
26 |
27 | const depsToProps = (context, actions) => ({
28 | context,
29 | saveConfigs: actions.wechat.saveConfigs
30 | });
31 |
32 | export default composeAll(
33 | withHandlers(userEvents),
34 | withTracker(subscriptions),
35 | useDeps(depsToProps)
36 | )(WechatAdmin);
37 |
--------------------------------------------------------------------------------
/client/containers/admin/layout/nav.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withHandlers, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import Nav from '../../../components/admin/layout/nav';
5 |
6 | const userEvents = {
7 | sidebar({ context }, event) {
8 | event.preventDefault();
9 | if ($(window).width() < 769) {
10 | $('body').toggleClass('show-sidebar');
11 | } else {
12 | $('body').toggleClass('hide-sidebar');
13 | }
14 | },
15 | login ({ context }, event) {
16 |
17 | }
18 | };
19 |
20 | const subscriptions = ({ context }, onData) => {
21 | const { Meteor, Collections } = context;
22 | const corePkg = Collections.Packages.findOne({ name: 'core' });
23 | if (corePkg) {
24 | onData(null, { appName: corePkg.configs.appName });
25 | } else {
26 | onData(null, { appName: '' });
27 | }
28 | };
29 |
30 | const mapStateToProps = (state) => ({
31 |
32 | });
33 |
34 | const depsToProps = (context, actions) => ({
35 | context
36 | });
37 |
38 | export default composeAll(
39 | withTracker(subscriptions),
40 | withHandlers(userEvents),
41 | withRedux(mapStateToProps),
42 | useDeps(depsToProps)
43 | )(Nav);
44 |
--------------------------------------------------------------------------------
/client/components/admin/layout/aside.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Link} from 'react-router';
3 |
4 | export default (props) => (
5 |
32 | );
33 |
--------------------------------------------------------------------------------
/client/components/users/reset-password.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default class extends React.Component {
4 | constructor(props) {
5 | super(props);
6 | this.state = {uiState: 'INIT'};
7 | this.onSubmit = this.onSubmit.bind(this);
8 | }
9 |
10 | onSubmit(e) {
11 | e.preventDefault();
12 | this.setState({uiState: 'SENDING'});console.log(this._input.value);
13 | this.props.resetPassword(this._input.value, (err) => {
14 | if (err) {
15 | console.log(err);
16 | this.setState({uiState: 'FAIL'});
17 | } else {
18 | this.setState({uiState: 'SUCCESS'});
19 | }
20 | });
21 | }
22 |
23 | render() {
24 | if (this.state.uiState === 'SENDING') return 正在设置密码...
;
25 | if (this.state.uiState === 'SUCCESS') return 密码设置成功
;
26 |
27 | return (
28 | );
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_loader.scss:
--------------------------------------------------------------------------------
1 | .spinner {
2 | margin: 20px auto;
3 | width: 60px;
4 | height: 50px;
5 | text-align: center;
6 | font-size: 15px;
7 | }
8 |
9 | .spinner > div {
10 | background-color: $color-green;
11 | height: 100%;
12 | width: 8px;
13 | display: inline-block;
14 |
15 | -webkit-animation: sk-stretchdelay 1.2s infinite ease-in-out;
16 | animation: sk-stretchdelay 1.2s infinite ease-in-out;
17 | }
18 |
19 | .spinner .rect2 {
20 | -webkit-animation-delay: -1.1s;
21 | animation-delay: -1.1s;
22 | }
23 |
24 | .spinner .rect3 {
25 | -webkit-animation-delay: -1.0s;
26 | animation-delay: -1.0s;
27 | }
28 |
29 | .spinner .rect4 {
30 | -webkit-animation-delay: -0.9s;
31 | animation-delay: -0.9s;
32 | }
33 |
34 | .spinner .rect5 {
35 | -webkit-animation-delay: -0.8s;
36 | animation-delay: -0.8s;
37 | }
38 |
39 | @-webkit-keyframes sk-stretchdelay {
40 | 0%, 40%, 100% { -webkit-transform: scaleY(0.4) }
41 | 20% { -webkit-transform: scaleY(1.0) }
42 | }
43 |
44 | @keyframes sk-stretchdelay {
45 | 0%, 40%, 100% {
46 | transform: scaleY(0.4);
47 | -webkit-transform: scaleY(0.4);
48 | } 20% {
49 | transform: scaleY(1.0);
50 | -webkit-transform: scaleY(1.0);
51 | }
52 | }
--------------------------------------------------------------------------------
/maodou/posts/client/containers/admin/postsConfigure.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withTracker, withRedux, composeAll } from 'react-komposer-plus';
3 |
4 | import PostsConfigure from '../../components/admin/postsConfigure';
5 |
6 | const data = ({ context }, onData) => {
7 | const { Collections } = context;
8 | const pkg = Collections.Packages.findOne({ name: 'posts' }) || {};
9 | const configs = pkg.configs || { UI: '' };
10 | document.title = '配置文章页面';
11 | onData(null, {
12 | categories: configs.categories || [],
13 | imgPosition: configs.UI.listImgPosition || 'left',
14 | tabsPosition: configs.UI.categoriesPosition || 'top',
15 | tabsColor: configs.UI.categoriesTabsColor || 'green'
16 | });
17 | };
18 |
19 | const depsToProps = (context, actions) => ({
20 | context,
21 | dispatch: context.dispatch,
22 | addCategory: actions.posts.addCategory,
23 | deleteCategory: actions.posts.deleteCategory,
24 | changeImgPosition: actions.posts.changeImgPosition,
25 | changeTabsPosition: actions.posts.changeTabsPosition,
26 | changeTabsColor: actions.posts.changeTabsColor
27 | });
28 |
29 | export default composeAll(
30 | withTracker(data),
31 | useDeps(depsToProps)
32 | )(PostsConfigure);
33 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_lists.scss:
--------------------------------------------------------------------------------
1 | /* Lists */
2 | .list .list-item-container {
3 | float: left;
4 | }
5 |
6 | .list-item-container div:first-child {
7 | border-top: none;
8 | }
9 |
10 | .list .list-item .list-item-content p {
11 | margin-bottom: 3px;
12 | margin-top: 0;
13 | }
14 | .list .list-item-date {
15 | color: #AAAAAA;
16 | font-size: 10px;
17 | text-align: center;
18 | }
19 | .list .list-item {
20 | float: left;
21 | overflow-x: hidden;
22 | position: relative;
23 | width: 100%;
24 | padding-top: 10px;
25 | margin-top: 10px;
26 | border-top: 1px solid $border-color;
27 | }
28 | .list .list-item-container-small {
29 | min-width: 80px;
30 | text-align: center;
31 | }
32 | .list .list-item .list-item-content .list-item-right {
33 | height: 100%;
34 | padding: 0 10px;
35 | position: absolute;
36 | right: 0;
37 | top: 0;
38 | }
39 | .list .list-item .list-item-content h1, .list .list-item .list-item-content h2, .list .list-item .list-item-content h3, .list .list-item .list-item-content h4, .list .list-item .list-item-content h5, .list .list-item .list-item-content h6, .list .list-item .list-item-content .list-item-title {
40 | font-size: 12px;
41 | font-weight: 600;
42 | line-height: 20px;
43 | margin: 0;
44 | }
--------------------------------------------------------------------------------
/maodou/singlePages/client/containers/mainPage.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withTracker, composeAll } from 'react-komposer-plus';
3 | import _ from 'lodash';
4 | import MainPage from '../components/mainPage';
5 |
6 | const subscription = ({ context }, onData) => {
7 | const { Meteor, Roles, Collections } = context;
8 | const corePkg = Collections.Packages.findOne({ name: 'core' });
9 |
10 | if (Meteor.subscribe('singlePages.selected').ready()) {
11 | const singlePage = Collections.SinglePages.findOne();
12 | const nickname = Meteor.user() ? Meteor.user().profile.nickname : '';
13 | const sortedSections = _.sortBy(singlePage.sections, ['index']);
14 | const data = { ...singlePage, sections: sortedSections };
15 |
16 | onData(null, {
17 | singlePage: { status: 'ready', data },
18 | appName: corePkg.configs.appName,
19 | loggedIn: !!context.Meteor.user(),
20 | nickname,
21 | isAdmin: Roles.userIsInRole(Meteor.user(), ['admin'])
22 | });
23 | } else {
24 | onData(null, {
25 | singlePage: { status: 'pending', data: {} }
26 | });
27 | }
28 | };
29 |
30 | const depsToProps = (context) => ({
31 | context
32 | });
33 |
34 | export default composeAll(
35 | withTracker(subscription),
36 | useDeps(depsToProps)
37 | )(MainPage);
38 |
--------------------------------------------------------------------------------
/server/main.js:
--------------------------------------------------------------------------------
1 | import App from './lib/app';
2 |
3 | import createContext from './context';
4 | import collectionsMiddleware from '../lib/middlewares/collections';
5 | import configMiddleware from '../lib/middlewares/configs';
6 | import middlewareMiddleware from './lib/middlewares/middleware';
7 | import coreModule from './';
8 | import postsModule from 'maodou/posts/server';
9 | import eventsModule from 'maodou/events/server';
10 | import wechatModule from 'maodou/wechat/server';
11 | import bizplansModule from 'maodou/bizplans/server';
12 | import customersModule from 'maodou/customers/server';
13 | import singlePagesModule from 'maodou/singlePages/server';
14 | // import addTemplateModule from 'maodou/addTemplate/server';
15 |
16 |
17 | //系统变量MAIL_URL配置,暂时放在这里
18 | process.env.MAIL_URL = Meteor.settings.mailUrl;
19 |
20 | const context = createContext();
21 | const app = new App(context);
22 |
23 | app.loadMiddlewares([
24 | collectionsMiddleware(),
25 | configMiddleware,
26 | middlewareMiddleware
27 | ]);
28 |
29 | app.loadModule(coreModule);
30 | app.loadModule(wechatModule);
31 | app.loadModule(postsModule);
32 | app.loadModule(eventsModule);
33 | app.loadModule(bizplansModule);
34 | app.loadModule(customersModule);
35 | app.loadModule(singlePagesModule);
36 | // app.loadModule(addTemplateModule);
37 |
38 | app.init();
39 |
--------------------------------------------------------------------------------
/maodou/customers/client/containers/admin/customersEdit.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { compose, withHandlers, withTracker, withRedux, withLifecycle, composeAll } from 'react-komposer-plus';
3 | import { browserHistory } from 'react-router';
4 |
5 | import CustumersEdit from '../../components/admin/customersEdit';
6 |
7 | // const lifeCycle = {
8 | // componentDidMount() {
9 | // $('#editor').summernote({
10 | // height: 250
11 | // });
12 | // }
13 | // };
14 |
15 | const data = ({ context, params }, onData) => {
16 | const { Meteor, Collections, swal } = context;
17 | const customerId = params.id;
18 | Meteor.call('customers.get.single', customerId, (err, customer) => {
19 | if (err) {
20 | if (err.error === '404'){
21 | toastr.error("客户没有找到,返回到原来页面");
22 | browserHistory.push('admin/customers/list');
23 | }
24 | } else {
25 | document.title = customer.title;
26 | onData(null, { customer });
27 | }
28 | });
29 | // onData(null, {});
30 | };
31 | const depsToProps = (context, actions) => ({
32 | context,
33 | dispatch: context.dispatch,
34 | editCustomer: actions.customers.editCustomer
35 | });
36 |
37 | export default composeAll(
38 | // withLifecycle(lifeCycle),
39 | withTracker(data),
40 | useDeps(depsToProps)
41 | )(CustumersEdit);
42 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_nestable_list.scss:
--------------------------------------------------------------------------------
1 | .angular-ui-tree-handle {
2 | background: none repeat scroll 0 0 $color-bright;
3 | border: 1px dashed $border-color;
4 | color: inherit;
5 | padding: 10px;
6 | font-weight: normal;
7 | }
8 | .angular-ui-tree-handle:hover {
9 | font-weight: bold;
10 | cursor: pointer;
11 | }
12 | .angular-ui-tree-placeholder {
13 | background: #f0f9ff;
14 | border: 1px dashed $border-color;
15 | -webkit-box-sizing: border-box;
16 | -moz-box-sizing: border-box;
17 | box-sizing: border-box;
18 | }
19 | .group-title {
20 | background-color: #687074 !important;
21 | color: #FFF !important;
22 | }
23 | .tree-node {
24 | background: none repeat scroll 0 0 $color-bright;
25 | border: 1px dashed $border-color;
26 | color: inherit;
27 | padding: 10px;
28 | border-radius: 3px;
29 | }
30 |
31 | .tree-node .btn {
32 | min-width: 22px;
33 | margin-right: 4px;
34 | }
35 |
36 | .tree-node-content {
37 | margin: 5px 5px 5px 0;
38 | }
39 |
40 | .tree-handle {
41 | background: none repeat scroll 0 0 $color-bright;
42 | border: 1px dashed $border-color;
43 | color: inherit;
44 | padding: 10px;
45 | }
46 |
47 | .angular-ui-tree-placeholder {
48 | background: #f0f9ff;
49 | border: 1px dashed $border-color;
50 | -webkit-box-sizing: border-box;
51 | -moz-box-sizing: border-box;
52 | box-sizing: border-box;
53 | }
--------------------------------------------------------------------------------
/server/index.js:
--------------------------------------------------------------------------------
1 | import configs from '../lib/configs';
2 | import privateConfigs from './configs/core';
3 | import collections from '../lib/collections';
4 | import permissions from './permissions';
5 | import publications from './publications';
6 | import methods from './methods';
7 |
8 | export default {
9 | configs,
10 | privateConfigs,
11 | collections,
12 | permissions,
13 | publications,
14 | methods,
15 | init(context) {
16 | const { Collections, Qiniu, privateConfigs, Meteor } = context;
17 | Qiniu.conf.ACCESS_KEY = privateConfigs.core.qiniu.ACCESS_KEY;
18 | Qiniu.conf.SECRET_KEY = privateConfigs.core.qiniu.SECRET_KEY;
19 | Qiniu.conf.BUCKET_NAME = privateConfigs.core.qiniu.BUCKET_NAME;
20 | Qiniu.conf.DOMAIN_NAME = privateConfigs.core.qiniu.DOMAIN_NAME;
21 | if (!Collections.Packages.findOne({ name: 'core' })) {
22 | Collections.Packages.insert({
23 | name: 'core',
24 | configs: context.configs.core || {}
25 | });
26 | }
27 | if (Meteor.users.find().count() === 0) {
28 | const adminUser = {
29 | username: 'admin',
30 | email: 'admin@example.com',
31 | password: '123456',
32 | profile: { nickname: 'Admin' },
33 | };
34 | const userId = Accounts.createUser(adminUser);
35 | context.Roles.addUsersToRoles(userId, ['admin']);
36 | }
37 | }
38 | };
39 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_progress_bar.scss:
--------------------------------------------------------------------------------
1 | /* Progress bar */
2 |
3 | .progress {
4 | border-radius: 2px;
5 | margin-bottom: 10px;
6 | }
7 |
8 | .progress-bar {
9 | background-color: $color-background;
10 | text-align: right;
11 | padding-right: 10px;
12 | color: $color-text;
13 | }
14 |
15 | .progress-small, .progress-small .progress-bar {
16 | height: 10px;
17 | }
18 |
19 | .progress-bar-success {
20 | border-right: 4px solid darken($color-green, 5%);
21 | }
22 |
23 | .progress-bar-info {
24 | border-right: 4px solid darken($color-blue, 5%);
25 | }
26 |
27 | .progress-bar-warning {
28 | border-right: 4px solid darken($color-yellow, 5%);
29 | }
30 |
31 | .progress-bar-danger {
32 | border-right: 4px solid darken($color-red, 5%);
33 | }
34 |
35 | .full .progress-bar-success {
36 | background-color: $color-green;
37 | border-right: 4px solid darken($color-green, 5%);
38 | }
39 |
40 | .full .progress-bar-info {
41 | background-color: $color-blue;
42 | border-right: 4px solid darken($color-blue, 5%);
43 | }
44 |
45 | .full .progress-bar-warning {
46 | background-color: $color-yellow;
47 | border-right: 4px solid darken($color-yellow, 5%);
48 | }
49 |
50 | .full .progress-bar-danger {
51 | background-color: $color-red;
52 | border-right: 4px solid darken($color-red, 5%);
53 | }
54 |
55 | .full .progress-bar {
56 | color: #ffffff;
57 | }
--------------------------------------------------------------------------------
/maodou/bizplans/lib/collections/bizplans.js:
--------------------------------------------------------------------------------
1 | import { Mongo } from 'meteor/mongo'
2 | import { SimpleSchema } from 'meteor/aldeed:simple-schema'
3 |
4 | const Bizplans = new Mongo.Collection('bizplans')
5 |
6 | Bizplans.attachSchema(
7 | new SimpleSchema({
8 | PDFName: {
9 | type: String,
10 | optional: false
11 | },
12 | PDFUrl: {
13 | type: String,
14 | optional: false
15 | },
16 | name: {
17 | type: String,
18 | max: 100,
19 | optional: false
20 | },
21 | contact: {
22 | type: String,
23 | max: 120,
24 | optional: true
25 | },
26 | types: {
27 | type: [String],
28 | optional: false
29 | },
30 | desc: {
31 | type: String,
32 | max: 1000,
33 | optional: false
34 | },
35 | createdAt: {
36 | type: Date,
37 | autoValue () {
38 | if (this.isInsert) {
39 | return new Date()
40 | } else if (this.isUpsert) {
41 | return {$setOnInsert: new Date()}
42 | } else {
43 | this.unset()
44 | }
45 | }
46 | },
47 | updatedAt: {
48 | type: Date,
49 | autoValue () {
50 | if (this.isUpdate) {
51 | return new Date()
52 | }
53 | },
54 | denyInsert: true,
55 | optional: true
56 | }
57 | })
58 | )
59 |
60 | export default Bizplans
61 |
--------------------------------------------------------------------------------
/.meteor/packages:
--------------------------------------------------------------------------------
1 | # Meteor packages used by this project, one per line.
2 | # Check this file (and the other files in this directory) into your repository.
3 | #
4 | # 'meteor add' and 'meteor remove' will edit this file for you,
5 | # but you can also edit it by hand.
6 |
7 | meteor-base@1.0.4 # Packages every Meteor app needs to have
8 | mobile-experience@1.0.4 # Packages for a great mobile UX
9 | mongo@1.1.12 # The database Meteor supports right now
10 | static-html
11 | reactive-var@1.0.10 # Reactive variable for tracker
12 | tracker@1.1.0 # Meteor's client-side reactive programming library
13 |
14 | standard-minifier-css # CSS minifier run for production mode
15 | standard-minifier-js # JS minifier run for production mode
16 | es5-shim@4.6.14 # ECMAScript 5 compatibility for older browsers.
17 | shell-server # Server-side component of the `meteor shell` command
18 | accounts-base
19 | http
20 | aldeed:simple-schema
21 | aldeed:collection2
22 | accounts-password
23 | alanning:roles # TODO: This package has blaze included. We need to get rid of blaze.
24 | underscore
25 | meteorhacks:picker
26 | fourseven:scss
27 | fortawesome:fontawesome
28 | summernote:summernote # TODO: This package has bootstrap included. However we have npm version bootstrap.
29 | onokumus:metismenu
30 | webpack:webpack
31 | webpack:react
32 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_modal.scss:
--------------------------------------------------------------------------------
1 | .h-modal-icon {
2 | font-size: 66px;
3 | }
4 | .inmodal .color-line {
5 | border-radius: 4px 4px 0 0;
6 | }
7 | .modal-content {
8 | border-radius: 5px;
9 | border: none;
10 | box-shadow: 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.2);
11 | }
12 | .modal-backdrop.in {
13 | opacity: 0.4;
14 | }
15 | .modal-backdrop {
16 | position: fixed;
17 | bottom: 0;
18 | }
19 | .modal-dialog {
20 | margin-top: 80px;
21 | }
22 | .modal-title {
23 | font-size: 30px;
24 | font-weight: 300;
25 | }
26 | .modal-header {
27 | padding: 40px 30px;
28 | background: $color-bright;
29 | }
30 | .modal-body {
31 | padding: 20px 30px;
32 | }
33 | .modal-header small {
34 | color: lighten($color-text, 20%);
35 | }
36 | .modal-footer {
37 | background: $color-bright;
38 | }
39 |
40 | .hmodal-info .color-line {
41 | background: $color-blue;
42 | }
43 | .hmodal-warning .color-line {
44 | background: $color-yellow;
45 | }
46 | .hmodal-success .color-line {
47 | background: $color-green;
48 | }
49 | .hmodal-danger .color-line {
50 | background: $color-red-deep;
51 | }
52 |
53 | .hmodal-info h4.modal-title {
54 | color: $color-blue;
55 | }
56 | .hmodal-warning h4.modal-title {
57 | color: $color-yellow;
58 | }
59 | .hmodal-success h4.modal-title {
60 | color: $color-green;
61 | }
62 | .hmodal-danger h4.modal-title {
63 | color: $color-red-deep;
64 | }
65 |
--------------------------------------------------------------------------------
/maodou/posts/client/components/post.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Loading from 'client/components/common/loading';
3 | import moment from 'moment';
4 |
5 | export default (props) => {
6 | return (
7 |
8 |
9 |
10 | {
11 | props.post ?
12 |
13 |
14 |
[{props.post.category}] {props.post.title}
15 |
16 | 作者:{props.post.author}
17 | 日期:{moment(props.post.createdAt).format('YYYY-MM-DD')}
18 |
19 |
20 |
21 | {/*
*/}
22 | {/**/}
23 | {/* 22 comments*/}
24 | {/**/}
25 | {/* 142 views*/}
26 | {/*
*/}
27 |
:
28 |
29 | }
30 |
31 |
32 |
33 | );
34 | }
35 |
--------------------------------------------------------------------------------
/lib/helpers/index.js:
--------------------------------------------------------------------------------
1 | import toastr from 'toastr';
2 |
3 | export default {
4 | shortText(text) {
5 | return text.length > 10 ? `${text.slice(0,10)}...` : text;
6 | },
7 | handlePostError(err) {
8 | switch(err.reason) {
9 | case 'Title is required':
10 | toastr.info('请先添加文章标题');
11 | break;
12 | case 'Cover url is required':
13 | toastr.info('请先添加封面图片');
14 | break;
15 | case 'Author is required':
16 | toastr.info('请先添加文章作者');
17 | break;
18 | default:
19 | toastr.error('发布失败');
20 | }
21 | },
22 | handleEventError(err) {
23 | switch(err.reason) {
24 | case 'Title is required':
25 | toastr.info('发布失败,请先添加活动标题');
26 | break;
27 | case 'Cover url is required':
28 | toastr.info('发布失败,请先添加活动封面');
29 | break;
30 | case 'Time is required':
31 | toastr.info('发布失败,请先添加活动日期');
32 | break;
33 | case 'Location is required':
34 | toastr.info('发布失败,请先添加活动地点');
35 | break;
36 | case 'Fee is required':
37 | toastr.info('发布失败,请先添加活动费用');
38 | break;
39 | case 'Limit is required':
40 | toastr.info('发布失败,请先添加活动人数限制');
41 | break;
42 | case 'Limit must be a number':
43 | toastr.info('发布失败,活动人数限制必须是数字');
44 | break;
45 | default:
46 | toastr.error('发布失败');
47 | }
48 | }
49 | };
50 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/style.scss:
--------------------------------------------------------------------------------
1 | // Import Google font
2 | @import url("https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700");
3 |
4 | // Color list
5 | $color-navy-blue: #0a5c64;
6 | $color-violet:#9b59b6;
7 | $color-blue:#3498db;
8 | $color-green:#62cb31;
9 | $color-yellow:#ffb606;
10 | $color-orange:#e67e22;
11 | $color-red:#e74c3c;
12 | $color-red-deep:#c0392b;
13 |
14 | // Additional colors
15 | $color-text: #6a6c6f;
16 | $color-bright: #f7f9fa;
17 | $color-background: #f1f3f6;
18 | $color-background-boxed: lighten($color-background, 3%);
19 | $border-color: #e4e5e7;
20 |
21 | // Additional variables
22 | $menu-width: 180px;
23 | $main-transition: all 0.1s ease-out 0s;
24 |
25 |
26 | // Import all styles
27 | @import "margins";
28 | @import "alerts";
29 | @import "modal";
30 | @import "progress_bar";
31 | @import "login";
32 | @import "timeline";
33 | @import "contact";
34 | @import "calendar";
35 | @import "text_editor";
36 | @import "grid";
37 | @import "dropdown";
38 | @import "chat";
39 | @import "various";
40 | @import "buttons";
41 | @import "fonts";
42 | @import "icheck";
43 | @import "layout";
44 | @import "lists";
45 | @import "panels";
46 | @import "tabs";
47 | @import "tooltip";
48 | @import "projects";
49 | @import "social_board";
50 | @import "nestable_list";
51 | @import "tour";
52 | @import "blog";
53 | @import "forum";
54 | @import "mailbox";
55 | @import "loader";
56 |
57 | // Styles for landing page
58 | @import "landing";
59 |
--------------------------------------------------------------------------------
/client/components/users/email-enrollment-form.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default class extends React.Component {
4 | constructor(props) {
5 | super(props);
6 | this.state = {uiState: 'INIT'};
7 | this.onSubmit = this.onSubmit.bind(this);
8 | }
9 |
10 | onSubmit(e) {
11 | e.preventDefault();
12 | this.setState({uiState: 'SENDING'});
13 | this.props.enrollWithEmail(this._input.value, (err) => {
14 | if (err) {
15 | console.log(err);
16 | this.setState({uiState: 'FAIL'});
17 | } else {
18 | this.setState({uiState: 'SUCCESS'});
19 | }
20 | });
21 | }
22 |
23 | render() {
24 | if (this.state.uiState === 'SENDING') return 正在发送邮件...
;
25 | if (this.state.uiState === 'SUCCESS') return 邮件已发送,请查看您的邮箱
;
26 |
27 | return (
28 |
29 |
30 | {this.state.uiState === 'FAIL' &&
邮件发送失败,请重试
}
31 |
请填写登录用的邮箱地址,我们将发送一个链接到你邮箱,通过该链接设置登录密码
32 |
40 |
41 |
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/client/components/admin/layout/nav.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Link} from 'react-router';
3 |
4 | export default (props) => (
5 |
6 |
7 |
8 |
9 |
10 | {props.appName}
11 |
12 |
13 |
37 |
38 | );
39 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/components/admin/bizplan/style.scss:
--------------------------------------------------------------------------------
1 | .notice {
2 | padding: 15px;
3 | background-color: #fafafa;
4 | border-left: 6px solid #7f7f84;
5 | margin-bottom: 10px;
6 | -webkit-box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
7 | -moz-box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
8 | box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
9 | }
10 |
11 | .noticemain {
12 | font-weight: bold;
13 | color: #333;
14 | padding: 15px;
15 | background-color: #fafafa;
16 | text-align: center;
17 | margin-bottom: 10px;
18 | -webkit-box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
19 | -moz-box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
20 | box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
21 | }
22 |
23 | .glyphicon {
24 | font-weight: 800;
25 | }
26 |
27 | .notice-sm {
28 | /*padding: 10px;
29 | font-size: 80%;*/
30 | border-color: #7f7f84;
31 | > strong {
32 | color: #7f7f84;
33 | }
34 | }
35 |
36 | .notice-success {
37 | border-color: #80D651;
38 | > strong {
39 | color: #80D651;
40 | }
41 | }
42 |
43 | .notice-info {
44 | border-color: #45ABCD;
45 | > strong {
46 | color: #45ABCD;
47 | }
48 | }
49 |
50 | .notice-warning {
51 | border-color: #FEAF20;
52 | > strong {
53 | color: #FEAF20;
54 | }
55 | }
56 |
57 | .notice-danger {
58 | border-color: #d73814;
59 | > strong {
60 | color: #d73814;
61 | }
62 | }
63 |
64 | .notice-button {
65 | padding: 10px;
66 | font-size: 80%;
67 | border-color: #80D651;
68 | }
69 |
70 | .btn {
71 | margin-right: 5px;
72 | }
73 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/components/singleBizplan/style.scss:
--------------------------------------------------------------------------------
1 | .notice {
2 | padding: 15px;
3 | background-color: #fafafa;
4 | border-left: 6px solid #7f7f84;
5 | margin-bottom: 10px;
6 | -webkit-box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
7 | -moz-box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
8 | box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
9 | }
10 |
11 | .noticemain {
12 | font-weight: bold;
13 | color: #333;
14 | padding: 15px;
15 | background-color: #fafafa;
16 | text-align: center;
17 | margin-bottom: 10px;
18 | -webkit-box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
19 | -moz-box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
20 | box-shadow: 0 5px 8px -6px rgba(0, 0, 0, 0.2);
21 | }
22 |
23 | .glyphicon {
24 | font-weight: 800;
25 | }
26 |
27 | .notice-sm {
28 | /*padding: 10px;
29 | font-size: 80%;*/
30 | border-color: #7f7f84;
31 | > strong {
32 | color: #7f7f84;
33 | }
34 | }
35 |
36 | .notice-success {
37 | border-color: #80D651;
38 | > strong {
39 | color: #80D651;
40 | }
41 | }
42 |
43 | .notice-info {
44 | border-color: #45ABCD;
45 | > strong {
46 | color: #45ABCD;
47 | }
48 | }
49 |
50 | .notice-warning {
51 | border-color: #FEAF20;
52 | > strong {
53 | color: #FEAF20;
54 | }
55 | }
56 |
57 | .notice-danger {
58 | border-color: #d73814;
59 | > strong {
60 | color: #d73814;
61 | }
62 | }
63 |
64 | .notice-button {
65 | padding: 10px;
66 | font-size: 80%;
67 | border-color: #80D651;
68 | }
69 |
70 | .btn {
71 | margin-right: 5px;
72 | }
73 |
--------------------------------------------------------------------------------
/maodou/bizplans/server/index.js:
--------------------------------------------------------------------------------
1 | import collections from '../lib/collections';
2 | // import permissions from './permissions'
3 | import publications from './publications';
4 | import methods from './methods';
5 | import configs from '../lib/config';
6 | // import privateConfigs from 'server/configs/posts'
7 |
8 | export default {
9 | configs,
10 | // privateConfigs,
11 | collections,
12 | // permissions,
13 | publications,
14 | methods,
15 | init (context) {
16 | const { Collections } = context;
17 | if (!Collections.Packages.findOne({ name: 'bizplans' })) {
18 | Collections.Packages.insert({
19 | name: 'bizplans',
20 | configs: context.configs.bizplans || {}
21 | });
22 | }
23 | if (Collections.Bizplans.find().count() < 2) {
24 | Collections.Bizplans.insert({
25 | PDFName:'CMS based on Meteor and React.pptx',
26 | PDFUrl:'http://og0f8itra.bkt.clouddn.com/FlCXthxYnYpTMz_9RyaCuaHTFUtf',
27 | name:'ofo 共享单车',
28 | contact:'18500557934',
29 | types: [
30 | '智能硬件',
31 | '体育'
32 | ],
33 | desc:'随时随地有车骑'
34 | });
35 | Collections.Bizplans.insert({
36 | PDFName:'Real项目需求分析书 .xlsx',
37 | PDFUrl:'http://og0f8itra.bkt.clouddn.com/Ft-hZ1elMxk0AuQMuKdBUr1uS1_S',
38 | name:'毛豆网',
39 | contact:'https://www.maodou.io/',
40 | types: [
41 | '互联网与信息技术',
42 | 'SaaS/PaaS工具'
43 | ],
44 | desc:'专注内容创业的云平台'
45 | });
46 | }
47 | }
48 | };
49 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_dropdown.scss:
--------------------------------------------------------------------------------
1 | .dropdown-menu.hdropdown {
2 | padding: 0;
3 | z-index: 1060;
4 | }
5 |
6 | .dropdown-menu.hdropdown .title {
7 | padding: 12px 12px;
8 | text-align: center;
9 | border-bottom:1px solid $border-color ;
10 | }
11 |
12 | .dropdown-menu.hdropdown li {
13 | padding: 6px 12px;
14 | text-align: left;
15 | background: lighten($color-background, 3%);
16 | border-bottom:1px solid $border-color;
17 | }
18 |
19 | .dropdown-menu.filedropdown li {
20 | padding: 6px 6px;
21 | text-align: left;
22 | background: lighten($color-background, 3%);
23 | border-bottom:1px solid $border-color;
24 | }
25 |
26 | .dropdown-menu.filedropdown li i {
27 | margin-right: 10px;
28 |
29 | }
30 |
31 | .dropdown-menu.hdropdown.notification li {
32 | padding: 12px 12px;
33 | }
34 |
35 | .dropdown-menu.hdropdown.notification li .label{
36 | margin-right: 10px;
37 | }
38 |
39 | .dropdown-menu.hdropdown li > a:hover, .dropdown-menu.filedropdown li > a:hover {
40 | background: inherit;
41 | }
42 |
43 | .dropdown-menu.hdropdown li:hover, .dropdown-menu.filedropdown li:hover {
44 | background: $color-background;
45 | }
46 |
47 | .dropdown-menu.hdropdown li.summary {
48 | padding: 6px 12px;
49 | text-align: center;
50 | background: #fff;
51 | }
52 |
53 | .navbar-nav > li > a:hover, .navbar-nav > li > a:focus, .navbar-nav .open > a, .navbar-nav .open > a:hover, .navbar-nav .open > a:focus {
54 | color: inherit;
55 | background: lighten($color-background, 2%);
56 | border-bottom:1px solid $border-color;
57 | }
58 |
--------------------------------------------------------------------------------
/maodou/posts/lib/collections/posts.js:
--------------------------------------------------------------------------------
1 | import { Mongo } from 'meteor/mongo';
2 | import { SimpleSchema, attachSchema } from 'meteor/aldeed:simple-schema';
3 |
4 | const Posts = new Mongo.Collection('posts');
5 |
6 | Posts.attachSchema(
7 | new SimpleSchema({
8 | title: {
9 | type: String
10 | },
11 | author: {
12 | type: String
13 | },
14 | coverUrl: {
15 | type: String
16 | },
17 | category: {
18 | type: String
19 | },
20 | content: {
21 | type: String
22 | },
23 | plainContent: {
24 | type: String,
25 | autoValue() {
26 | const content = this.field('content');
27 | if (content.isSet) {
28 | let textToSave = content.value.substring(0,100).replace(/<\/?[^>]+(>|$)/g, '');
29 | textToSave = textToSave.replace(/ /g, ' ');
30 | return `${textToSave}...`;
31 | } else {
32 | this.unset();
33 | }
34 | }
35 | },
36 | createdAt: {
37 | type: Date,
38 | autoValue() {
39 | if (this.isInsert) {
40 | return new Date();
41 | } else if (this.isUpsert) {
42 | return {$setOnInsert: new Date()};
43 | } else {
44 | this.unset();
45 | }
46 | }
47 | },
48 | updatedAt: {
49 | type: Date,
50 | autoValue() {
51 | if (this.isUpdate) {
52 | return new Date();
53 | }
54 | },
55 | denyInsert: true,
56 | optional: true
57 | }
58 | })
59 | );
60 |
61 | export default Posts;
62 |
--------------------------------------------------------------------------------
/client/containers/layout/nav.js:
--------------------------------------------------------------------------------
1 | import { useDeps } from 'react-simple-di';
2 | import { withHandlers, withTracker, withRedux, composeAll, withLifecycle } from 'react-komposer-plus';
3 | import Nav from '../../components/layout/nav';
4 |
5 | const userEvents = {
6 | setLang({ context, setLanguage }, event, lang) {
7 | event.preventDefault();
8 | context.T.setTexts(context.i18n[lang]);
9 | context.dispatch(setLanguage(lang));
10 | },
11 | login: ({ context }, event) => {
12 |
13 | }
14 | };
15 |
16 | const lifecycle = {
17 | componentDidMount() {
18 | $('.dropdown-toggle').dropdown();
19 | }
20 | };
21 |
22 | const subscriptions = ({ context }, onData) => {
23 | const { Meteor, Collections, Roles } = context;
24 | const corePkg = Collections.Packages.findOne({ name: 'core' });
25 | if (corePkg) {
26 | const nickname = Meteor.user() ? Meteor.user().profile.nickname : '';
27 | onData(null, {
28 | appName: corePkg.configs.appName,
29 | loggedIn: !!context.Meteor.user(),
30 | nickname,
31 | isAdmin: Roles.userIsInRole(Meteor.user(), ['admin'])
32 | });
33 | } else {
34 | onData(null, {});
35 | }
36 | };
37 |
38 | const mapStateToProps = (state) => ({
39 |
40 | });
41 |
42 | const depsToProps = (context, actions) => ({
43 | context,
44 | setLanguage: actions.core.setLanguage
45 | });
46 |
47 | export default composeAll(
48 | withLifecycle(lifecycle),
49 | withTracker(subscriptions),
50 | withHandlers(userEvents),
51 | withRedux(mapStateToProps),
52 | useDeps(depsToProps)
53 | )(Nav);
54 |
--------------------------------------------------------------------------------
/public/images/light-bulb.svg:
--------------------------------------------------------------------------------
1 |
2 |
11 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_icheck.scss:
--------------------------------------------------------------------------------
1 | /* iCheck plugin Square skin, green
2 | ----------------------------------- */
3 | .icheckbox_square-green,
4 | .iradio_square-green {
5 | display: inline-block;
6 | *display: inline;
7 | vertical-align: middle;
8 | margin: 0;
9 | padding: 0;
10 | width: 22px;
11 | height: 22px;
12 | background: url("img/green.png") no-repeat;
13 | border: none;
14 | cursor: pointer;
15 | }
16 |
17 | .icheckbox_square-green {
18 | background-position: 0 0;
19 | }
20 | .icheckbox_square-green.hover {
21 | background-position: -24px 0;
22 | }
23 | .icheckbox_square-green.checked {
24 | background-position: -48px 0;
25 | }
26 | .icheckbox_square-green.disabled {
27 | background-position: -72px 0;
28 | cursor: default;
29 | }
30 | .icheckbox_square-green.checked.disabled {
31 | background-position: -96px 0;
32 | }
33 |
34 | .iradio_square-green {
35 | background-position: -120px 0;
36 | }
37 | .iradio_square-green.hover {
38 | background-position: -144px 0;
39 | }
40 | .iradio_square-green.checked {
41 | background-position: -168px 0;
42 | }
43 | .iradio_square-green.disabled {
44 | background-position: -192px 0;
45 | cursor: default;
46 | }
47 | .iradio_square-green.checked.disabled {
48 | background-position: -216px 0;
49 | }
50 |
51 | /* HiDPI support */
52 | @media (-o-min-device-pixel-ratio: 5/4), (-webkit-min-device-pixel-ratio: 1.25), (min-resolution: 120dpi) {
53 | .icheckbox_square-green,
54 | .iradio_square-green {
55 | background-image: url("img/green@2x.png");
56 | -webkit-background-size: 240px 24px;
57 | background-size: 240px 24px;
58 | }
59 | }
--------------------------------------------------------------------------------
/maodou/bizplans/client/actions/bizplans.js:
--------------------------------------------------------------------------------
1 | import { $ } from 'meteor/jquery'
2 |
3 | export default {
4 | // pure action
5 | selectType (context, t) {
6 | return { type: 'SELECT_TYPE', t }
7 | },
8 | cleanselectedTypes () {
9 | return { type: 'CLEAN_SELECTED_TYPES' }
10 | },
11 | addPDF (context, PDFName, PDFUrl) {
12 | return { type: 'ADD_PDF', PDFName, PDFUrl }
13 | },
14 | uploadingPDF (context) {
15 | return { type: 'UPLOADING_PDF' }
16 | },
17 | uploadedPDF (context) {
18 | return { type: 'UPLOADED_PDF' }
19 | },
20 | removePDF (context) {
21 | return { type: 'REMOVE_PDF' }
22 | },
23 | // redux thunk
24 | addBizplan ({ Meteor, swal }, e, bizplanPDF) {
25 | return () => {
26 | e.preventDefault()
27 |
28 | const types = $('input[name="types"]:checked').map(function () {
29 | return this.value
30 | }).get()
31 |
32 | const data = {
33 | ...bizplanPDF,
34 | name: e.target.name.value,
35 | contact: e.target.contact.value,
36 | types,
37 | desc: e.target.desc.value
38 | }
39 |
40 | Meteor.call('bizplans.add', data, (err) => {
41 | if (err) {
42 | $('#failedMsg').modal()
43 | } else {
44 | $('#successMsg').modal()
45 | }
46 | })
47 | }
48 | },
49 | removeBizplan ({ Meteor, swal, toastr }, _id) {
50 | return () => {
51 | Meteor.call('bizplans.remove', _id, (err) => {
52 | if (err) {
53 | toastr.error('删除失败');
54 | } else {
55 | toastr.success('删除成功');
56 | }
57 | })
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/client/main.js:
--------------------------------------------------------------------------------
1 | import 'bootstrap-sass';
2 | import App from './lib/app';
3 | import React from 'react';
4 | import thunk from 'redux-thunk';
5 | import createContext from './context';
6 | import collectionsMiddleware from '../lib/middlewares/collections';
7 | import reduxMiddleware from './lib/middlewares/redux';
8 | import configMiddleware from '../lib/middlewares/configs';
9 | import i18nMiddleware from './lib/middlewares/i18n';
10 |
11 | import coreModule from './';
12 | import postsModule from 'maodou/posts/client';
13 | import eventsModule from 'maodou/events/client';
14 | import wechatModule from 'maodou/wechat/client';
15 | import bizplansModule from 'maodou/bizplans/client';
16 | import customersModule from 'maodou/customers/client';
17 | import singlePagesModule from 'maodou/singlePages/client';
18 | // import addTemplateModule from 'maodou/addTemplate/client';
19 |
20 | import { render } from 'react-dom';
21 | import { Router, browserHistory } from 'react-router';
22 |
23 | const context = createContext();
24 | export const app = new App(context);
25 |
26 | app.loadMiddlewares([
27 | collectionsMiddleware(),
28 | reduxMiddleware({
29 | middlewares: [thunk]
30 | }),
31 | configMiddleware,
32 | i18nMiddleware(['enUS', 'zhCN'])
33 | ]);
34 |
35 | app.loadModule(coreModule);
36 | app.loadModule(wechatModule);
37 | app.loadModule(postsModule);
38 | app.loadModule(eventsModule);
39 | app.loadModule(bizplansModule);
40 | app.loadModule(customersModule);
41 | app.loadModule(singlePagesModule);
42 | // app.loadModule(addTemplateModule);
43 |
44 | app.init();
45 |
46 | render(, document.getElementById('body'));
47 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_mailbox.scss:
--------------------------------------------------------------------------------
1 | ul.mailbox-list, ul.h-list {
2 | list-style: none;
3 | padding: 0;
4 | }
5 |
6 | ul.mailbox-list li a, ul.h-list li a {
7 | padding: 10px 15px;
8 | display: block;
9 | }
10 |
11 | ul.mailbox-list li a i, ul.h-list li a i {
12 | margin-right: 6px;
13 | display: inline-block;
14 | }
15 |
16 | ul.mailbox-list li.active a, ul.h-list li.active a {
17 | background: #f7f9fa;
18 | border: 1px solid #e4e5e7;
19 | font-weight: 600;
20 | border-radius: 1px;
21 | }
22 | ul.mailbox-list li:hover a, ul.h-list li:hover a {
23 | font-weight: 600;
24 | }
25 |
26 | .table-mailbox {
27 | .radio, .checkbox {
28 | margin: 0;
29 | }
30 | .radio label, .checkbox label {
31 | cursor: default;
32 | }
33 |
34 | tr.unread td a {
35 | font-weight: 600;
36 | }
37 |
38 | tr td span.label {
39 | margin-left: 10px;
40 | }
41 |
42 | tr:first-child td {
43 | border-top: none;
44 | }
45 |
46 | tr td:first-child {
47 | width: 33px;
48 | padding-right: 0;
49 | }
50 | }
51 |
52 | .mailbox-pagination {
53 | text-align: right;
54 | }
55 |
56 | @media (max-width: 768px) {
57 | .mailbox-pagination {
58 | text-align: left;
59 | }
60 | }
61 |
62 | .email-compose .note-editor {
63 | border: none;
64 | }
65 |
66 | .email-compose .note-editor .note-editable {
67 | padding: 15px 25px;
68 | }
69 |
70 | .email-compose .note-toolbar {
71 | padding: 5px 15px;
72 | }
73 |
74 | .note-popover .popover .popover-content>.btn-group, .note-toolbar>.btn-group {
75 | margin-bottom: 5px;
76 | }
77 |
78 | .note-editor .note-toolbar {
79 | /* Background from footer panel */
80 | background-color: $color-bright;
81 | }
82 |
--------------------------------------------------------------------------------
/maodou/events/client/components/event.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Loading from 'client/components/common/loading';
3 | import moment from 'moment';
4 |
5 | export default (props) => {
6 | return (
7 |
8 |
9 |
10 | {
11 | props.event ?
12 |
13 |
14 |
{props.event.title}
15 |
16 | 作者:Admin
17 | 日期:{moment(props.event.createdAt).format('YYYY-MM-DD')}
18 |
19 |
20 |
时间:{moment(props.event.time).format('YYYY-MM-DD')}
21 |
地点:{props.event.location}
22 |
费用:{props.event.unit === 'dollar' ? '$' : '¥'} {props.event.fee}
23 |
人数限制:{props.event.limit}
24 |
25 |
26 | {/*
*/}
27 | {/**/}
28 | {/* 22 comments*/}
29 | {/**/}
30 | {/* 142 views*/}
31 | {/*
*/}
32 |
:
33 |
34 | }
35 |
36 |
37 |
38 | );
39 | }
40 |
--------------------------------------------------------------------------------
/client/lib/imports/toastr/toastr.scss:
--------------------------------------------------------------------------------
1 |
2 | /* Toastr custom styles*/
3 | #toast-container {
4 | }
5 |
6 | #toast-container.toast-bottom-center > div, #toast-container.toast-top-center > div {
7 | margin: 10px auto 0;
8 | }
9 |
10 | #toast-container > .toast-info,
11 | #toast-container > .toast-error,
12 | #toast-container > .toast-warning,
13 | #toast-container > .toast-success{
14 | background-image: none;
15 | }
16 |
17 | #toast-container > div {
18 | background: #fff;
19 | padding: 20px;
20 | color: #6a6c6f;
21 | box-shadow: 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.2);
22 | opacity: 1;
23 | }
24 |
25 |
26 | #toast-container > div:hover {
27 | box-shadow: 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.2);
28 | }
29 |
30 | .toast-close-button {
31 | color: #000;
32 | opacity: 0.2;
33 | }
34 |
35 | .toast-info {
36 | background: #fff;
37 | border-left: 6px solid #3498db;
38 | }
39 | .toast-success {
40 | background: #fff;
41 | border-left: 6px solid #62cb31;
42 | }
43 | .toast-warning {
44 | background: #fff;
45 | border-left: 6px solid #ffb606;
46 | }
47 | .toast-error {
48 | background: #fff;
49 | border-left: 6px solid #e74c3c;
50 | }
51 |
52 | .toast-progress {
53 | opacity: 0.6;
54 | }
55 |
56 | .toast-info .toast-progress {
57 | background-color: #3498db;
58 | }
59 | .toast-success .toast-progress {
60 | background-color: #62cb31;
61 | }
62 | .toast-warning .toast-progress {
63 | background-color: #ffb606;
64 | }
65 | .toast-error .toast-progress {
66 | background-color: #e74c3c;
67 | }
68 |
69 |
70 | @media(min-width: 768px) {
71 | #toast-container {
72 | margin-left: 180px;
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/client/containers/home/index.js:
--------------------------------------------------------------------------------
1 | // import React from 'react';
2 | // import {useDeps} from 'react-simple-di';
3 | // import {composeAll, withTracker, withLifecycle} from 'react-komposer-plus';
4 |
5 | // import Home from '../../components/home';
6 |
7 | // function composer({context}, onData) {
8 | // const user = context().Meteor.user();
9 | // if (user && Array.isArray(user.emails) && user.emails.length > 0) {
10 | // const isWechatVerified = user.profile.headimgurl && user.emails[0].verified;
11 | // const isWechat = user.profile.headimgurl || user.city;
12 | // const nickname = user.profile.nickname;
13 | // const avatar = isWechat ? user.profile.headimgurl : '';
14 | // onData(null, {
15 | // loggedIn: !!user,
16 | // notWechat: !isWechat,
17 | // isWechatVerified,
18 | // nickname,
19 | // avatar
20 | // });
21 | // } else {
22 | // onData(null, {loggedIn: user});
23 | // }
24 | // }
25 |
26 | // function configsComposer({context}, onData) {
27 | // const { Meteor } = context();
28 | // if (Meteor.subscribe('core.configs.user').ready()) {
29 | // const coreConfigs = context().Collections.Packages.findOne({ name: 'core' }).configs;
30 | // onData(null, { title: coreConfigs.appName });
31 | // } else {
32 | // onData(null, { title: '' });
33 | // }
34 | // }
35 |
36 | // const lifecycle = {
37 | // componentWillReceiveProps(nextProps) {
38 | // if (nextProps.title) {
39 | // document.title = nextProps.title;
40 | // }
41 | // }
42 | // };
43 |
44 | // export default composeAll(
45 | // withLifecycle(lifecycle),
46 | // withTracker(composer),
47 | // withTracker(configsComposer),
48 | // useDeps()
49 | // )(Home);
50 |
--------------------------------------------------------------------------------
/lib/collections/users.js:
--------------------------------------------------------------------------------
1 | import { Meteor } from 'meteor/meteor';
2 | import { SimpleSchema, attachSchema } from 'meteor/aldeed:simple-schema';
3 |
4 | let Schema = {};
5 |
6 | Schema.UserProfile = new SimpleSchema({
7 | nickname: {
8 | type: String
9 | }
10 | // firstName: {
11 | // type: String
12 | // },
13 | // lastName: {
14 | // type: String
15 | // }
16 | });
17 |
18 | Schema.User = new SimpleSchema({
19 | username: {
20 | type: String,
21 | optional: true
22 | },
23 | emails: {
24 | type: [Object],
25 | optional: true
26 | },
27 | 'emails.$.address': {
28 | type: String,
29 | regEx: SimpleSchema.RegEx.Email
30 | },
31 | 'emails.$.verified': {
32 | type: Boolean
33 | },
34 | profile: {
35 | type: Schema.UserProfile,
36 | optional: true
37 | },
38 | services: {
39 | type: Object,
40 | optional: true,
41 | blackbox: true
42 | },
43 | roles: {
44 | type: [String],
45 | optional: true
46 | },
47 | // In order to avoid an 'Exception in setInterval callback' from Meteor
48 | heartbeat: {
49 | type: Date,
50 | optional: true
51 | },
52 | createdAt: {
53 | type: Date,
54 | autoValue: function() {
55 | if (this.isInsert) {
56 | return new Date();
57 | } else if (this.isUpsert) {
58 | return {$setOnInsert: new Date()};
59 | } else {
60 | this.unset();
61 | }
62 | }
63 | },
64 | updatedAt: {
65 | type: Date,
66 | autoValue: function() {
67 | if (this.isUpdate) {
68 | return new Date();
69 | }
70 | },
71 | denyInsert: true,
72 | optional: true
73 | }
74 | });
75 |
76 | Meteor.users.attachSchema(Schema.User);
77 |
--------------------------------------------------------------------------------
/maodou/singlePages/js/navbar.js:
--------------------------------------------------------------------------------
1 | export default function () {
2 | //如果导航被点击则值为 true
3 | let nav_checked = false;
4 | //导航列表
5 | let $nav = $('.navbar-nav li a');
6 | let $public = $('.nav_aPublic li a')
7 | //导航 点击跳转到 当前导航对应位置内容 效果
8 | $public.click(function(event){
9 | event.preventDefault();
10 | });
11 | $nav.on('click',function(){
12 | //导航被点击
13 | nav_checked = true;
14 | $('.nav_in').removeClass('nav_in');
15 | $(this).addClass('nav_in');
16 | let scroll_top_demo = $('.nav_in').attr('href');
17 | let scroll_top_num = $(scroll_top_demo).offset().top;
18 | $('html,body').animate({scrollTop:scroll_top_num},'slow');
19 | //导航被点击 结束 改变状态
20 | setTimeout(function(){nav_checked = false;},1000);
21 | });
22 | $( window ).scroll(function() {
23 | if($(this).scrollTop() > $('.navbar').height() + 50) {
24 | $('.navbar').addClass('navbar-inverse');
25 | $('.navbar').addClass('scrolling');
26 | } else {
27 | $('.navbar').removeClass('navbar-inverse');
28 | $('.navbar').removeClass('scrolling');
29 | }
30 | //滚动到导航链接处,将对应导航置为选择状态
31 | let s_top = $('body').scrollTop();
32 | //点击导航则不执行这里
33 | if(!nav_checked){
34 | $nav.each(function() {
35 | let data_href = $(this).attr('href');
36 | let $nav_demo = $(data_href);
37 | let middle = $(window).height()/2;
38 | if($nav_demo.offset().top - s_top < middle){
39 | $nav.each(function() {$(this).removeClass('nav_in');});
40 | $(this).addClass('nav_in');
41 | }
42 | if($nav_demo.offset().top - s_top > middle){
43 | $(this).removeClass('nav_in');
44 | }
45 | });
46 | }
47 | });
48 | }
49 |
--------------------------------------------------------------------------------
/lib/middlewares/configs.js:
--------------------------------------------------------------------------------
1 | export default {
2 | moduleWillLoad(module) {
3 | if (!module.configs) {
4 | const message = "Module must have a configs field";
5 | throw new Error(message);
6 | }
7 | if (module.configs) {
8 | if (typeof module.configs !== 'object') {
9 | const message = "Module's configs field should be an object.";
10 | throw new Error(message);
11 | }
12 | this._configs = this._configs || {};
13 | Object.assign(this._configs, module.configs);
14 |
15 | if (this.context.Meteor.isServer) {
16 | if (module.privateConfigs) {
17 | if (typeof module.privateConfigs !== 'object') {
18 | const message = "Module's privateConfigs field should be an object.";
19 | throw new Error(message);
20 | }
21 | this._privateConfigs = this._privateConfigs || {};
22 | Object.assign(this._privateConfigs, module.privateConfigs);
23 | }
24 | }
25 | }
26 | if (module.init) {
27 | if (typeof module.init !== 'function') {
28 | const message = "Module's init field should be a function.";
29 | throw new Error(message);
30 | }
31 |
32 | if (!this._initFns) this._initFns = [];
33 | this._initFns.push(module.init);
34 | }
35 | },
36 |
37 | moduleWillInit() {
38 | this.context.configs = this._configs;
39 | if (this._initFns && this.context.Meteor.isClient) {
40 | this._initFns.forEach(fn => fn(this.context, this.actions));
41 | } else if (this._initFns && this.context.Meteor.isServer) {
42 | this.context.privateConfigs = this._privateConfigs;
43 | this._initFns.forEach(fn => fn(this.context));
44 | }
45 | }
46 | };
47 |
--------------------------------------------------------------------------------
/maodou/singlePages/lib/collections/singlePages.js:
--------------------------------------------------------------------------------
1 | import { Mongo } from 'meteor/mongo';
2 | import { SimpleSchema } from 'meteor/aldeed:simple-schema';
3 |
4 | const SinglePages = new Mongo.Collection('singlePages');
5 |
6 | const section = new SimpleSchema({
7 | name: {
8 | type: String,
9 | optional: true
10 | },
11 | anchorName: {
12 | type: String,
13 | optional: true
14 | },
15 | index: {
16 | type: Number
17 | },
18 | display: {
19 | type: Boolean
20 | },
21 | content: {
22 | type: String
23 | }
24 | });
25 |
26 | SinglePages.attachSchema(
27 | new SimpleSchema({
28 | templateName: {
29 | type: String
30 | },
31 | logoImgUrl:{
32 | type: String,
33 | optional: true
34 | },
35 | logoName: {
36 | type: String,
37 | optional: true
38 | },
39 | headTitle: {
40 | type: String,
41 | optional: true
42 | },
43 | defaultTemplate: {
44 | type: Boolean,
45 | optional: true
46 | },
47 | preview: {
48 | type: String
49 | },
50 | selected: {
51 | type: Boolean
52 | },
53 | sections: {
54 | type: [section]
55 | },
56 | createdAt: {
57 | type: Date,
58 | autoValue () {
59 | if (this.isInsert) {
60 | return new Date();
61 | } else if (this.isUpsert) {
62 | return { $setOnInsert: new Date() };
63 | }
64 | this.unset();
65 | }
66 | },
67 | updatedAt: {
68 | type: Date,
69 | autoValue () {
70 | if (this.isUpdate) {
71 | return new Date();
72 | }
73 | },
74 | denyInsert: true,
75 | optional: true
76 | }
77 | })
78 | );
79 |
80 | export default SinglePages;
81 |
--------------------------------------------------------------------------------
/scripts/run_app.sh:
--------------------------------------------------------------------------------
1 | set -e
2 |
3 | # npm config set registry https://registry.npm.taobao.org
4 | # npm config set disturl https://npm.taobao.org/dist
5 | # echo "=> Prepare run app."
6 |
7 | # if [ -d /bundle ]; then
8 | # echo "=> unzip /bundle."
9 | # cd /bundle
10 | # tar xzf *.tar.gz
11 | # cd /bundle/bundle/programs/server/
12 | # # fix cloneCurrentTree problem
13 | # rm npm-shrinkwrap.json
14 | # # echo "=> [zhaoic] fix fibers"
15 | # # npm uninstall fibers
16 | # # npm install fibers
17 | # echo "=> npm install."
18 | # npm install --unsafe-perm
19 | # cd /bundle/bundle/
20 | # elif [[ $BUNDLE_URL ]]; then
21 | # echo "=> unzip url bundle."
22 | # cd /tmp
23 | # curl -L -o bundle.tar.gz $BUNDLE_URL
24 | # tar xzf bundle.tar.gz
25 | # cd /tmp/bundle/programs/server/
26 | # npm install --unsafe-perm
27 | # cd /tmp/bundle/
28 | # elif [ -d /built_app ]; then
29 | # echo "=> /bundle_app."
30 | # cd /built_app
31 | # else
32 | # echo "=> You don't have an meteor app to run in this image."
33 | # exit 1
34 | # fi
35 |
36 | # if [[ $REBUILD_NPM_MODULES ]]; then
37 | # if [ -f /opt/meteord/rebuild_npm_modules.sh ]; then
38 | # echo "rebuild_npm_modules.sh."
39 | # cd programs/server
40 | # bash /opt/meteord/rebuild_npm_modules.sh
41 | # cd ../../
42 | # else
43 | # echo "=> Use meteorhacks/meteord:bin-build for binary bulding."
44 | # exit 1
45 | # fi
46 | # fi
47 |
48 | # Set a delay to wait to start meteor container
49 | if [[ $DELAY ]]; then
50 | echo "Delaying startup for $DELAY seconds"
51 | sleep $DELAY
52 | fi
53 |
54 | # Honour already existing PORT setup
55 | export PORT=${PORT:-80}
56 |
57 | cd /bundle/bundle
58 | echo "=> Starting meteor app on port:$PORT"
59 | node main.js
60 |
--------------------------------------------------------------------------------
/maodou/events/lib/collections/events.js:
--------------------------------------------------------------------------------
1 | import { Mongo } from 'meteor/mongo';
2 | // import { SimpleSchema, attachSchema } from 'meteor/aldeed:simple-schema';
3 |
4 | const Events = new Mongo.Collection('events');
5 |
6 | Events.attachSchema(
7 | new SimpleSchema({
8 | title: {
9 | type: String
10 | },
11 | coverUrl: {
12 | type: String
13 | },
14 | desc: {
15 | type: String
16 | },
17 | time: {
18 | type: Date
19 | },
20 | location: {
21 | type: String
22 | },
23 | limit: {
24 | type: Number
25 | },
26 | fee: {
27 | type: String,
28 | autoValue(doc) {
29 | // console.log(doc);
30 | }
31 | },
32 | unit: {
33 | type: String
34 | },
35 | plainDesc: {
36 | type: String,
37 | autoValue() {
38 | const content = this.field('desc');
39 | if (content.isSet) {
40 | let textToSave = content.value.replace(/<\/?[^>]+(>|$)/g, '');
41 | textToSave = textToSave.replace(/ /g, ' ');
42 | return textToSave;
43 | } else {
44 | this.unset();
45 | }
46 | }
47 | },
48 | createdAt: {
49 | type: Date,
50 | autoValue() {
51 | if (this.isInsert) {
52 | return new Date();
53 | } else if (this.isUpsert) {
54 | return {$setOnInsert: new Date()};
55 | } else {
56 | this.unset();
57 | }
58 | }
59 | },
60 | updatedAt: {
61 | type: Date,
62 | autoValue() {
63 | if (this.isUpdate) {
64 | return new Date();
65 | }
66 | },
67 | denyInsert: true,
68 | optional: true
69 | }
70 | })
71 | );
72 |
73 | export default Events;
74 |
--------------------------------------------------------------------------------
/maodou/events/server/seed.js:
--------------------------------------------------------------------------------
1 | export default {
2 | data: [{
3 | title: 'Kubernetes喊你来开船啦',
4 | coverUrl: 'https://ohjdeohom.qnssl.com/base/events-k8s.jpg',
5 | desc: `Kubernetes这个词起源于古希腊,意为「舵手」。
6 | 它的核心功能就是应用的自动发布、自动恢复、自动扩展、
7 | 滚动升级,毋庸置疑kubernetes能提供编程生产力方面的极大收益,
8 | 简化人工和自动化的系统管理。`,
9 | time: new Date(2016, 11, 12),
10 | location: '清华fit楼',
11 | limit: '100',
12 | fee: '0',
13 | unit: 'rmb'
14 | }, {
15 | title: '清华技术讲座:硅谷最新的React/Redux 和 Meteor共存之道',
16 | coverUrl: 'https://ohjdeohom.qnssl.com/base/events-meteor.jpg',
17 | desc: `Meteor 是一个新鲜出炉的现代网站开发平台,基础构架是 Node.JS +MongoDB,
18 | 它把这个基础构架同时延伸到了浏览器端,如果 App 用纯 JavaScript 写成,
19 | JS APIs 和 DB APIs 就可以同时在服务器端和客户端无差异地调用,
20 | 本地和远程数据通过 DDP(Distributed Data Protocol)协议传输。`,
21 | time: new Date(2016, 10, 6),
22 | location: '清华fit楼',
23 | limit: '50',
24 | fee: '0',
25 | unit: 'rmb'
26 | }, {
27 | title: '携程技术中心React Native Meetup',
28 | coverUrl: 'https://ohjdeohom.qnssl.com/base/events-reactnative.jpg',
29 | desc: `一年半前,随着React Native的到来,这些痛点都被一一解决。
30 | 目前看来,它是移动开发的一大方向,后起的Weex,微信小程序,无一例外,
31 | 都有参考React Native的设计。
32 | 不过React Native框架的使用,以及和现有业务的整合,性能优化,门槛并不低,
33 | 各个公司在业务实践过程中都遇到各自不同的问题。
34 | 本次沙龙,我们将就RN框架优化,业务实践方面的问题来做分享。
35 | 10月23日,携程上海总部,一起来聆听移动开发最前沿的声音~`,
36 | time: new Date(2016, 9, 23),
37 | location: '(上海长宁)金钟路968号凌空SOHO',
38 | limit: '500',
39 | fee: '0',
40 | unit: 'rmb'
41 | }, {
42 | title: '最后的风口',
43 | coverUrl: 'https://ohjdeohom.qnssl.com/base/events-chuangyebang.jpg',
44 | desc: `创业邦100未来领袖峰会暨2016创业邦年会`,
45 | time: new Date(2016, 11, 2),
46 | location: '(北京朝阳)国家会议中心',
47 | limit: '8000',
48 | fee: '288',
49 | unit: 'rmb'
50 | }]
51 | };
52 |
--------------------------------------------------------------------------------
/maodou/posts/client/components/admin/postsAdd.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | // import LaddaButton from 'react-ladda';
3 |
4 | export default (props) => {
5 | return (
6 |
42 | );
43 | }
44 |
--------------------------------------------------------------------------------
/maodou/customers/server/index.js:
--------------------------------------------------------------------------------
1 | import collections from '../lib/collections';
2 | import permissions from './permissions';
3 | import publications from './publications';
4 | import methods from './methods';
5 | import configs from '../lib/configs';
6 | import privateConfigs from './config';
7 |
8 | export default {
9 | configs,
10 | privateConfigs,
11 | collections,
12 | permissions,
13 | publications,
14 | methods,
15 | init(context) {
16 | const { Collections } = context;
17 | if (!Collections.Packages.findOne({ name: 'customers' })) {
18 | Collections.Packages.insert({
19 | name: 'customers',
20 | configs: context.configs.customers || {}
21 | });
22 | }
23 | if (Collections.Customers.find().count() < 3) {
24 | Collections.Customers.insert({
25 | index: 1,
26 | title: 'CRM项目重构',
27 | category: 'C类,产品无关定制项目客户',
28 | salesName: 'Shann',
29 | customerName: '张文',
30 | desc: '对已有的基于blaze的CRM项目进行重构,整合的meteor-react-redux-base的模版中,扩展数据库,扩展筛选功能。',
31 | schedule: '60% 已经收到首款,正在开发',
32 | amount: 54321,
33 | author: 'test'
34 | });
35 | Collections.Customers.insert({
36 | index: 2,
37 | title: '直播网站',
38 | category: 'A类,产品直接客户' ,
39 | salesName: '李四',
40 | customerName: '张三',
41 | desc: '王二麻子家的小淘气要开直播',
42 | schedule: '10% 已经建立联系,正在讨论项目需求',
43 | amount: 12345,
44 | author: '白云'
45 | });
46 | Collections.Customers.insert({
47 | index: 3,
48 | title: '视频直播',
49 | category: 'B类,产品相关定制项目客户' ,
50 | salesName: '小白',
51 | customerName: '葬爱',
52 | desc: '葬爱家族要开直播,要求当游客一进入官网就有一种浸泡在非主流style的感觉!',
53 | schedule: '10% 已经建立联系,正在讨论项目需求',
54 | amount: 12345,
55 | author: '黑土'
56 | });
57 | }
58 | }
59 | };
60 |
--------------------------------------------------------------------------------
/maodou/posts/server/methods/index.js:
--------------------------------------------------------------------------------
1 | export default (context) => {
2 | const { Meteor, Collections } = context;
3 | const { Posts, Packages } = Collections;
4 | Meteor.methods({
5 | 'posts.get'() {
6 | return Posts.find().fetch();
7 | },
8 | 'posts.get.single'(id) {
9 | const post = Posts.findOne(id);
10 | if (!post) {
11 | throw new Meteor.Error('404', 'not found');
12 | }
13 | return post;
14 | },
15 | 'posts.edit'(id, postData) {
16 | Posts.update(id, { $set: postData});
17 | },
18 | 'posts.add'(category, coverUrl, title, author, content) {
19 | Posts.insert({
20 | category,
21 | coverUrl,
22 | title,
23 | author,
24 | content
25 | });
26 | },
27 | 'posts.delete'(id) {
28 | Posts.remove(id);
29 | },
30 | 'posts.categories.add'(category) {
31 | Packages.update({ name: 'posts' }, {
32 | $push: {
33 | 'configs.categories': category
34 | }
35 | })
36 | },
37 | 'posts.categories.delete'(category) {
38 | Packages.update({ name: 'posts' }, {
39 | $pull: {
40 | 'configs.categories': category
41 | }
42 | });
43 | Posts.update({ category }, {
44 | $set: { category: 'none' }
45 | });
46 | },
47 | 'posts.imgPosition'(position) {
48 | Packages.update({ name: 'posts' }, {
49 | $set: { 'configs.UI.listImgPosition': position }
50 | })
51 | },
52 | 'posts.categories.tabsPosition'(position) {
53 | Packages.update({ name: 'posts' }, {
54 | $set: { 'configs.UI.categoriesPosition': position }
55 | })
56 | },
57 | 'posts.categories.color'(color) {
58 | Packages.update({ name: 'posts' }, {
59 | $set: { 'configs.UI.categoriesTabsColor': color }
60 | })
61 | }
62 | });
63 | };
64 |
--------------------------------------------------------------------------------
/client/components/users/login-form.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import {Link} from 'react-router';
3 |
4 | export default class extends React.Component {
5 | constructor(props) {
6 | super(props);
7 | this.onSubmit = this.onSubmit.bind(this);
8 | }
9 |
10 | onSubmit(e) {
11 | e.preventDefault();
12 | this.props.loginWithPassword(this._emailInput.value, this._passwordInput.value);
13 | }
14 |
15 | render() {
16 | return (
17 |
18 |
19 |
20 | {/*
*/}
21 | {/*
PLEASE LOGIN TO APP
*/}
22 | {/*This is the best app ever!*/}
23 | {/**/}
24 |
40 |
41 |
42 |
43 | );
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/client/components/users/register.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 | import {Link} from 'react-router';
3 |
4 | export default class Register extends Component {
5 | constructor(props) {
6 | super(props);
7 | }
8 |
9 | render() {
10 | const { dispatch, createNewUser } = this.props;
11 | return (
12 |
38 | );
39 | }
40 | }
41 |
42 | Register.propType = {
43 | dispatch: PropTypes.func,
44 | createNewUser: PropTypes.func
45 | };
46 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_forum.scss:
--------------------------------------------------------------------------------
1 | .forum-box {
2 |
3 | .panel-body {
4 | border-bottom: none;
5 | }
6 |
7 | .panel-body:last-child {
8 | border-bottom: 1px solid $border-color;
9 | }
10 |
11 | .forum-heading {
12 | h4 {
13 | margin-bottom: 3px;
14 | font-weight: 600;
15 | margin-top: 5px;
16 | display: inline;
17 | }
18 |
19 | .label {
20 | margin-right: 5px;
21 | }
22 |
23 | .desc {
24 | color: lighten($color-text, 15%);
25 | font-size: 12px;
26 | }
27 | }
28 |
29 | .panel-heading {
30 | border: 1px solid $border-color;
31 | border-bottom: none;
32 | font-size: 90%;
33 | background: $color-bright;
34 | padding: 10px 20px;
35 | }
36 |
37 | .forum-info {
38 | text-align: right;
39 | line-height: 20px;
40 |
41 | .number {
42 | display: block;
43 | font-weight: 600;
44 | font-size: 22px;
45 | margin-top: 5px;
46 | }
47 |
48 | span {
49 | font-size: 12px;
50 | }
51 | }
52 |
53 | .panel-body .media-image {
54 | text-align: center;
55 | margin-right: 10px;
56 | min-width: 100px;
57 | }
58 |
59 | .panel-body .media img {
60 | margin-top: 10px;
61 | width: 42px;
62 | height: 42px;
63 | border-radius: 50%;
64 | margin-bottom: 10px;
65 | }
66 |
67 | .author-info {
68 | font-size: 12px;
69 | }
70 |
71 | .forum-comments {
72 | border: 1px solid $border-color;
73 | border-left: none;
74 | border-right: none;
75 | background: $color-bright;
76 | margin-top: 20px;
77 | padding: 10px 15px;
78 | }
79 |
80 | .forum-comments .media img {
81 | width: 32px;
82 | height: 32px;
83 | border-radius: 50%;
84 | margin-top: 0;
85 | margin-bottom: 10px;
86 | }
87 |
88 | .forum-comments form {
89 | margin-top: 10px;
90 | }
91 |
92 | }
93 |
94 | @media(max-width: 768px) {
95 |
96 | .forum-box .forum-info {
97 | text-align: left;
98 | }
99 |
100 | }
101 |
102 |
103 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_alerts.scss:
--------------------------------------------------------------------------------
1 | .sweet-alert button {
2 | background-color: #34495e;
3 | color: white;
4 | border: none;
5 | box-shadow: none;
6 | font-size: 17px;
7 | font-weight: 500;
8 | border-radius: 5px;
9 | padding: 10px 32px;
10 | margin: 26px 5px 0 5px;
11 | cursor: pointer;
12 | }
13 |
14 | .sweet-alert button:focus {
15 | outline: none;
16 | box-shadow: 0 0 2px rgba(128, 179, 235, 0.5), inset 0 0 0 1px rgba(0, 0, 0, 0.05);
17 | }
18 |
19 | .sweet-alert button:hover {
20 | background-color: #a1d9f2;
21 | }
22 |
23 | .sweet-alert button:active {
24 | background-color: #81ccee;
25 | }
26 |
27 | .sweet-alert button.cancel {
28 | background-color: #D0D0D0;
29 | }
30 |
31 | .sweet-alert button.cancel:hover {
32 | background-color: #c8c8c8;
33 | }
34 |
35 | .sweet-alert button.cancel:active {
36 | background-color: #b6b6b6;
37 | }
38 | .sweet-alert p {
39 | font-size: 14px;
40 | font-weight: 400;
41 | }
42 |
43 | .sweet-alert h2 {
44 | font-size: 26px;
45 | }
46 |
47 | .sweet-alert {
48 | padding: 25px;
49 | box-shadow: 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.2);
50 | -webkit-box-shadow : 0 0 1 px rgba(0, 0, 0, 0.1), 0 2 px 4 px rgba(0, 0, 0, 0.2);
51 | -moz-box-shadow : 0 0 1 px rgba(0, 0, 0, 0.1), 0 2 px 4 px rgba(0, 0, 0, 0.2)
52 | }
53 |
54 | .table > thead > tr > th {
55 | border-bottom: 1px solid #ddd;
56 | }
57 |
58 | .cg-notify-message.homer-notify {
59 | background: #fff;
60 | padding: 0;
61 | box-shadow: 0 0 1px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.2);
62 | -webkit-box-shadow : 0 0 1 px rgba(0, 0, 0, 0.1), 0 2 px 4 px rgba(0, 0, 0, 0.2);
63 | -moz-box-shadow : 0 0 1 px rgba(0, 0, 0, 0.1), 0 2 px 4 px rgba(0, 0, 0, 0.2);
64 | border:none ;
65 | margin-top: 30px;
66 | color: inherit;
67 | }
68 |
69 | .homer-notify.alert-warning {
70 | border-left: 6px solid $color-yellow;
71 | }
72 | .homer-notify.alert-success {
73 | border-left: 6px solid $color-green;
74 | }
75 |
76 | .homer-notify.alert-danger {
77 | border-left: 6px solid $color-red-deep;
78 | }
79 |
80 | .homer-notify.alert-info {
81 | border-left: 6px solid $color-blue;
82 | }
83 |
--------------------------------------------------------------------------------
/maodou/bizplans/client/components/admin/bizplan/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import { Link } from 'react-router'
3 | // import moment from 'moment'
4 |
5 | export default class Bizplan extends Component {
6 | render () {
7 | const { bizplan } = this.props
8 |
9 | return (
10 |
11 |
12 | 项目详情
13 |
14 |
20 |
21 | 名称:
22 |
23 | {bizplan.name}
24 |
25 |
26 | 联系方式:
27 |
28 | {bizplan.contact}
29 |
30 |
31 | 项目类型:
32 |
33 | {bizplan.types.join(' | ')}
34 |
35 |
36 | 一句话概括项目内容:
37 |
38 | {bizplan.desc}
39 |
40 |
41 | 返回
42 |
43 |
44 | )
45 | }
46 |
47 | renderPic (pic) {
48 | const url = this.props.bizplan[pic]
49 | if (url) {
50 | return
51 | }
52 | }
53 | }
54 |
55 | Bizplan.propTypes = {
56 | bizplan: PropTypes.object
57 | }
58 |
59 | const styles = {
60 | root: {
61 | marginTop: '60px',
62 | fontSize: '15px'
63 | },
64 | competencyPic: {
65 | width: '500px',
66 | height: '400px'
67 | },
68 | teamPic: {
69 | width: '500px',
70 | height: '400px'
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/maodou/singlePages/client/components/admin/singlePagesConf/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes} from 'react';
2 |
3 | import Preview from '../../../containers/admin/singlePagesConf/preview';
4 | import Config from '../../../containers/admin/singlePagesConf/config';
5 |
6 | export default class SinglePagesConf extends Component {
7 | constructor(props) {
8 | super(props);
9 |
10 | this.state = {
11 | isPrev: false,
12 | };
13 | }
14 |
15 | render() {
16 | const { templateName } = this.props;
17 |
18 | return (
19 |
20 |
21 | {templateName}模板配置
22 | {this.renderButton()}
23 |
24 | { this.state.isPrev ?
:
}
25 |
26 | );
27 | }
28 |
29 | handleReturnPrev(e) {
30 | e.preventDefault();
31 |
32 | const { dispatch, selectedSection, changeReturnPrev, selectSection } = this.props;
33 | dispatch(changeReturnPrev(selectedSection, () => {
34 | this.setState({isPrev: !this.state.isPrev});
35 | dispatch(selectSection(''));
36 | }));
37 | }
38 |
39 | renderButton() {
40 | if (this.state.isPrev) {
41 | return
42 |
48 | {/* button
49 | className='btn btn-danger'
50 | style={{marginLeft: '10px'}}
51 | onClick={(e) => this.handleRevert(e)}>
52 | 一键还原
53 | */}
54 | ;
55 | }
56 | return ;
62 | }
63 | }
64 |
65 | SinglePagesConf.propTypes = {
66 | dispatch: PropTypes.func,
67 | templateName: PropTypes.string,
68 | selectedSection: PropTypes.string,
69 | changeReturnPrev: PropTypes.func,
70 | selectSection: PropTypes.func,
71 | };
72 |
--------------------------------------------------------------------------------
/maodou/posts/client/main.scss:
--------------------------------------------------------------------------------
1 | .cover-img-wrapper {
2 | width: 200px;
3 | height: 150px;
4 | &.pull-left {
5 | margin-right: 10px;
6 | }
7 | &.pull-right {
8 | margin-left: 10px;
9 | }
10 | img {
11 | height: 100%;
12 | }
13 | }
14 |
15 | .cont {
16 | width: auto;
17 | height: 150px;
18 | }
19 |
20 | .post-coverImg {
21 | margin: 10px;
22 | img {
23 | max-width: 100%;
24 | height: auto;
25 | }
26 | }
27 |
28 | .posts-tab {
29 | z-index: 1;
30 | position: fixed;
31 | bottom: 0;
32 | height: 40px;
33 | width: 100%;
34 | &.top {
35 | top: 51px;
36 | bottom: initial;
37 | }
38 | &.green {
39 | background: #41B050;
40 | }
41 | &.red {
42 | background: #a42e25;
43 | }
44 | &.black {
45 | background: #151414;
46 | }
47 | }
48 |
49 | .flex-container {
50 | padding: 0;
51 | margin: 0;
52 | list-style: none;
53 | display: -webkit-box;
54 | display: -moz-box;
55 | display: -ms-flexbox;
56 | display: -webkit-flex;
57 | display: flex;
58 | -webkit-flex-flow: row wrap;
59 | justify-content: space-around;
60 | }
61 |
62 | .flex-item {
63 | flex: 1;
64 | line-height: 40px;
65 | color: white;
66 | font-size: 1.5em;
67 | text-align: center;
68 | border-right: 1px solid rgba(255, 255, 255, 0.68);
69 | cursor: pointer;
70 | &.active {
71 | background: rgba(255, 255, 255, 0.1);
72 | }
73 | }
74 |
75 | @media (max-width: 767px) {
76 | .cover-img-wrapper {
77 | width: 80px;
78 | height: 60px;
79 | }
80 | .cont {
81 | height: 60px;
82 | .post-title {
83 | padding: 0px;
84 | margin: 0px;
85 | font-size: 16px;
86 | text-overflow: ellipsis;
87 | white-space: nowrap;
88 | word-wrap: normal;
89 | overflow: hidden;
90 | }
91 | .post-desc {
92 | padding: 0px;
93 | margin-top: 5px;
94 | font-size: 13px;
95 | text-overflow: ellipsis;
96 | display: -webkit-box;
97 | -webkit-line-clamp: 2;
98 | -webkit-box-orient: vertical;
99 | overflow: hidden;
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/maodou/customers/client/components/customer.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Loading from 'client/components/common/loading';
3 | import moment from 'moment';
4 |
5 | export default (props)=>{
6 | return(
7 |
8 |
9 |
10 | {
11 | props.customer ?
12 |
13 |
14 |
{props.customer.index}-{props.customer.title}
15 |
16 |
当前状态:{props.customer.schedule}
17 |
跟单人:{props.customer.salesName}
18 |
更新于 {showTimeAgo(props.customer.updatedAt||props.customer.createdAt)}
19 |
20 |
{props.customer.project}
21 |
项目描述:
22 |
客户类别:{props.customer.category}
23 |
客户联系人:{props.customer.customerName}
24 |
25 |
创建者:{props.customer.author}
26 |
创建于 {showPrettyTimestamp(props.customer.createdAt)}
27 |
签单金额:{props.customer.amount}元
28 |
29 |
30 |
:
31 |
32 | }
33 |
34 |
35 |
36 | )
37 | }
38 | const styles = {
39 | mLR15: {
40 | marginLeft: '15px',
41 | marginRight: '15px',
42 | color: '#333333'
43 | }
44 | }
45 | const showTimeAgo = function(date) {
46 | return !date ? "" : moment(date).fromNow();
47 | }
48 |
49 | const showPrettyTimestamp = function(date) {
50 | return !date ? "" : moment(date).format("MMMM Do YYYY, h:mm:ss a")
51 | }
52 |
--------------------------------------------------------------------------------
/client/lib/imports/theme-homer/_calendar.scss:
--------------------------------------------------------------------------------
1 | /* FULLCALENDAR */
2 | .fc-state-default {
3 | background-color: #ffffff;
4 | background-image: none;
5 | background-repeat: repeat-x;
6 | box-shadow: none;
7 | color: inherit;
8 | text-shadow: none;
9 | }
10 | .fc-state-default {
11 | border: 1px solid;
12 | }
13 | .fc-button {
14 | color: inherit;
15 | border: 1px solid $border-color;
16 | cursor: pointer;
17 | display: inline-block;
18 | height: 1.9em;
19 | line-height: 1.9em;
20 | overflow: hidden;
21 | padding: 0 0.6em;
22 | position: relative;
23 | white-space: nowrap;
24 | }
25 | .fc-state-active {
26 | background-color: $color-navy-blue;
27 | border-color: $color-navy-blue;
28 | color: #ffffff;
29 | }
30 | .fc-header-title h2 {
31 | font-size: 16px;
32 | font-weight: 600;
33 | color: inherit;
34 | }
35 | .fc-content .fc-widget-header,
36 | .fc-content .fc-widget-content {
37 | border-color: $border-color;
38 | font-weight: normal;
39 | }
40 | .fc-border-separate tbody {
41 | background-color: #F8F8F8;
42 | }
43 | .fc-state-highlight {
44 | background: none repeat scroll 0 0 $color-background;
45 | }
46 | .external-event {
47 | padding: 5px 10px;
48 | border-radius: 2px;
49 | cursor: pointer;
50 | margin-bottom: 5px;
51 | }
52 | .fc-ltr .fc-event-hori.fc-event-end,
53 | .fc-rtl .fc-event-hori.fc-event-start {
54 | border-radius: 2px;
55 | }
56 | .fc-event,
57 | .fc-agenda .fc-event-time,
58 | .fc-event a {
59 | padding: 4px 6px;
60 | background-color: $color-navy-blue;
61 | border-color: $color-navy-blue;
62 | }
63 | .fc-event-time,
64 | .fc-event-title {
65 | color: #717171;
66 | padding: 0 1px;
67 | }
68 | .ui-calendar .fc-event-time,
69 | .ui-calendar .fc-event-title {
70 | color: #fff;
71 | }
72 |
73 | .fc-view-container .fc-widget-header {
74 | background: lighten($color-background, 2%);
75 | }
76 |
77 | .fc-widget-header .fc-day-header {
78 | padding: 12px 0;
79 | }
80 |
81 | .fc-ltr .fc-basic-view .fc-day-number {
82 | text-align: center;
83 | }
84 |
85 | .fc-basic-view td.fc-day-number, .fc-basic-view td.fc-week-number span {
86 | padding: 6px;
87 | }
88 |
89 | .fc-day-grid-event {
90 | margin: 2px 6px 0;
91 | }
--------------------------------------------------------------------------------
/maodou/bizplans/client/components/singleBizplan/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import { Link } from 'react-router'
3 | // import moment from 'moment'
4 |
5 | export default class SingleBizplan extends Component {
6 | render () {
7 | const { bizplan } = this.props
8 |
9 | return (
10 |
11 |
12 | 项目详情
13 |
14 |
20 |
21 | 名称:
22 |
23 | {bizplan.name}
24 |
25 |
26 | 联系方式:
27 |
28 | {bizplan.contact}
29 |
30 |
31 | 项目类型:
32 |
33 | {bizplan.types.join(' | ')}
34 |
35 |
36 | 一句话概括项目内容:
37 |
38 | {bizplan.desc}
39 |
40 |
41 | 返回
42 |
43 |
44 | )
45 | }
46 |
47 | renderPic (pic) {
48 | const url = this.props.bizplan[pic]
49 | if (url) {
50 | return
51 | }
52 | }
53 | }
54 |
55 | SingleBizplan.propTypes = {
56 | bizplan: PropTypes.object
57 | }
58 |
59 | const styles = {
60 | root: {
61 | minHeight: '100vh',
62 | marginTop: '60px',
63 | fontSize: '15px'
64 | },
65 | competencyPic: {
66 | width: '500px',
67 | height: '400px'
68 | },
69 | teamPic: {
70 | width: '500px',
71 | height: '400px'
72 | }
73 | }
74 |
--------------------------------------------------------------------------------