Search Companies

Search for Jobs
main
David 2023-06-20 03:23:54 +02:00
parent bfa24bec37
commit 8b0c44e35b
7 changed files with 356 additions and 75 deletions

View File

@ -1,21 +1,23 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.SENDTO"/>
<application
android:label="cpd_ss23"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
android:label="cpd_ss23"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"

View File

@ -1,16 +1,15 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../Widgets/bottom_nav_bar.dart';
import '../services/global_variables.dart';
class ProfileScreen extends StatefulWidget {
final String userId;
final String userID;
const ProfileScreen({required this.userId});
const ProfileScreen({required this.userID});
@override
State<ProfileScreen> createState() => _ProfileScreenState();
@ -63,7 +62,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
final DocumentSnapshot userDoc = await FirebaseFirestore.instance
.collection('users')
.doc(widget.userId)
.doc(widget.userID)
.get();
if (userDoc.exists) {
@ -84,7 +83,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
User? user = _auth.currentUser;
final _uid = user!.uid;
setState(() {
_isSameUser = _uid == widget.userId;
_isSameUser = _uid == widget.userID;
});
} else {
print('User not found');
@ -119,7 +118,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
// Update data in Firebase
if (_isSameUser) {
_firestore.collection('users').doc(widget.userId).update({
_firestore.collection('users').doc(widget.userID).update({
'name': name,
'email': email,
'phone': phoneNumber,
@ -136,7 +135,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Profile'),
title: const Text('Profile'),
actions: [
if (_isSameUser)
ElevatedButton(
@ -150,7 +149,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
Colors.white,
),
padding: MaterialStateProperty.all<EdgeInsets>(
EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
),
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
RoundedRectangleBorder(
@ -162,7 +161,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
if (!_isSameUser && email != null)
IconButton(
onPressed: _sendEmail,
icon: Icon(Icons.mail),
icon: const Icon(Icons.mail),
),
],
),
@ -188,85 +187,85 @@ class _ProfileScreenState extends State<ProfileScreen> {
SingleChildScrollView(
child: Column(
children: [
SizedBox(height: 40),
const SizedBox(height: 40),
Container(
width: MediaQuery.of(context).size.width ,
height: MediaQuery.of(context).size.width ,
decoration: BoxDecoration(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width,
decoration: const BoxDecoration(
shape: BoxShape.circle,
),
child: ClipOval(
child: imageUrl != null
? Image.network(
imageUrl!,
fit: BoxFit.cover,
)
imageUrl!,
fit: BoxFit.cover,
)
: Image.asset(
'assets/images/signup.png',
fit: BoxFit.cover,
),
'assets/images/signup.png',
fit: BoxFit.cover,
),
),
),
SizedBox(height: 24),
const SizedBox(height: 24),
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
const Text(
'Name:',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
SizedBox(height: 4),
const SizedBox(height: 4),
_isEditing && _isSameUser
? TextFormField(
controller: _nameController,
)
controller: _nameController,
)
: Text(name ?? ''),
SizedBox(height: 16),
Text(
const SizedBox(height: 16),
const Text(
'Email:',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
SizedBox(height: 4),
const SizedBox(height: 4),
_isEditing && _isSameUser
? TextFormField(
controller: _emailController,
)
controller: _emailController,
)
: Text(email ?? ''),
SizedBox(height: 16),
Text(
const SizedBox(height: 16),
const Text(
'Phone Number:',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
SizedBox(height: 4),
const SizedBox(height: 4),
_isEditing && _isSameUser
? TextFormField(
controller: _phoneNumberController,
)
controller: _phoneNumberController,
)
: Text(phoneNumber ?? ''),
SizedBox(height: 16),
Text(
const SizedBox(height: 16),
const Text(
'Location:',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
SizedBox(height: 4),
const SizedBox(height: 4),
_isEditing && _isSameUser
? TextFormField(
controller: _locationController,
)
controller: _locationController,
)
: Text(location ?? ''),
],
),
@ -277,7 +276,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
if (_isLoading)
Container(
color: Colors.black.withOpacity(0.5),
child: Center(
child: const Center(
child: CircularProgressIndicator(),
),
),

View File

@ -1,39 +1,114 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cpd_ss23/Widgets/all_companies_widget.dart';
import 'package:cpd_ss23/Widgets/bottom_nav_bar.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
class AllWorkersScreen extends StatefulWidget {
@override
State<AllWorkersScreen> createState() => _AllWorkersScreenState();
}
class _AllWorkersScreenState extends State<AllWorkersScreen> {
final TextEditingController _searchQueryController = TextEditingController();
String searchQuery = 'Search Query';
Widget _buildSearchField() {
return TextField(
controller: _searchQueryController,
autocorrect: true,
decoration: const InputDecoration(
hintText: "Search for companies...",
border: InputBorder.none,
hintStyle: TextStyle(color: Colors.white),
),
style: const TextStyle(color: Colors.white, fontSize: 16.0),
onChanged: (query) => updateSearchQuery(query),
);
}
List<Widget> _buildActions() {
return <Widget>[
IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
_clearSearchQuery();
},
)
];
}
void _clearSearchQuery() {
setState(() {
_searchQueryController.clear();
updateSearchQuery("");
});
}
void updateSearchQuery(String newQuery) {
setState(() {
searchQuery = newQuery;
print(searchQuery);
});
}
@override
Widget build(BuildContext context) {
return Container(
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [Colors.cyan, Colors.white60],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
stops: [0.2, 0.9],
)
gradient: LinearGradient(
colors: [Colors.cyan, Colors.white60],
begin: Alignment.centerLeft,
end: Alignment.centerRight,
stops: [0.2, 0.9],
)
),
child: Scaffold(
bottomNavigationBar: BottomNavigationBarForApp(indexNum: 1,),
bottomNavigationBar: BottomNavigationBarForApp(
indexNum: 1,
),
backgroundColor: Colors.transparent,
appBar: AppBar(
backgroundColor: Colors.cyan,
title: const Text('All Workers Screen'),
actions: [
IconButton(
icon: const Icon(Icons.search),
onPressed: () {
// Action when the search icon is clicked
},
),
],
automaticallyImplyLeading: false,
title: _buildSearchField(),
actions: _buildActions(),
),
body: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("users")
.where("name", isGreaterThanOrEqualTo: searchQuery)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.connectionState == ConnectionState.active) {
if (snapshot.data!.docs.isNotEmpty) {
return ListView.builder(
itemCount: snapshot.data!.docs.length,
itemBuilder: (BuildContext context, int index) {
return AllWorkersWidget(
userID: snapshot.data!.docs[index]["id"],
userName: snapshot.data!.docs[index]["name"],
userEmail: snapshot.data!.docs[index]["email"],
phoneNumber: snapshot.data!.docs[index]["phone"],
userImageUrl: snapshot.data!.docs[index]["userImage"],
);
});
} else {
return const Center(
child: Text("There is no user."),
);
}
}
return const Center(
child: Text(
"Something went wrong",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30),
),
);
},
),
),
);

View File

@ -1,11 +1,57 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:cpd_ss23/Widgets/job_widget.dart';
import 'package:flutter/material.dart';
import '../jobs/jobs_screen.dart';
class SearchScreen extends StatefulWidget {
@override
State<SearchScreen> createState() => _SearchScreenState();
}
class _SearchScreenState extends State<SearchScreen> {
final TextEditingController _searchQueryController = TextEditingController();
String searchQuery = 'Search Query';
Widget _buildSearchField() {
return TextField(
controller: _searchQueryController,
autocorrect: true,
decoration: const InputDecoration(
hintText: "Search for jobs...",
border: InputBorder.none,
hintStyle: TextStyle(color: Colors.white),
),
style: const TextStyle(color: Colors.white, fontSize: 16.0),
onChanged: (query) => updateSearchQuery(query),
);
}
List<Widget> _buildActions() {
return <Widget>[
IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
_clearSearchQuery();
},
)
];
}
void _clearSearchQuery() {
setState(() {
_searchQueryController.clear();
updateSearchQuery("");
});
}
void updateSearchQuery(String newQuery) {
setState(() {
searchQuery = newQuery;
print(searchQuery);
});
}
@override
Widget build(BuildContext context) {
return Container(
@ -18,7 +64,7 @@ class _SearchScreenState extends State<SearchScreen> {
child: Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
title: const Text("Search Job Screen"),
title: _buildSearchField(),
centerTitle: true,
flexibleSpace: Container(
decoration: const BoxDecoration(
@ -28,6 +74,57 @@ class _SearchScreenState extends State<SearchScreen> {
end: Alignment.centerRight,
stops: [0.2, 0.9])),
),
leading: IconButton(
onPressed: () {
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (context) => JobScreen()));
},
icon: const Icon(Icons.arrow_back),
),
actions: _buildActions(),
),
body: StreamBuilder<QuerySnapshot<Map<String, dynamic>>>(
stream: FirebaseFirestore.instance
.collection("jobs")
.where("jobTitle", isGreaterThanOrEqualTo: searchQuery)
.where("recruitment", isEqualTo: true)
.snapshots(),
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(),
);
} else if (snapshot.connectionState == ConnectionState.active) {
if (snapshot.data?.docs.isNotEmpty == true) {
return ListView.builder(
itemCount: snapshot.data?.docs.length,
itemBuilder: (BuildContext context, int index) {
return JobWidget(
jobTitle: snapshot.data?.docs[index]["jobTitle"],
jobDescription: snapshot.data?.docs[index]
["jobDescription"],
jobId: snapshot.data?.docs[index]["jobId"],
uploadedBy: snapshot.data?.docs[index]["uploadedBy"],
userImage: snapshot.data?.docs[index]["userImage"],
name: snapshot.data?.docs[index]["name"],
recruitment: snapshot.data?.docs[index]["recruitment"],
email: snapshot.data?.docs[index]["email"],
location: snapshot.data?.docs[index]["location"]);
},
);
} else {
return const Center(
child: Text("There is no Job"),
);
}
}
return const Center(
child: Text(
"Something went wrong",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 30.0),
),
);
},
),
),
);

View File

@ -0,0 +1,103 @@
import 'package:cpd_ss23/Search/profile_company.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher_string.dart';
class AllWorkersWidget extends StatefulWidget {
final String userID;
final String userName;
final String userEmail;
final String phoneNumber;
final String userImageUrl;
const AllWorkersWidget({
required this.userID,
required this.userName,
required this.userEmail,
required this.phoneNumber,
required this.userImageUrl,
});
@override
State<AllWorkersWidget> createState() => _AllWorkersWidgetState();
}
class _AllWorkersWidgetState extends State<AllWorkersWidget> {
void _mailTo() async {
var mailUrl = "mailto: ${widget.userEmail}";
print("widget.userEmail ${widget.userEmail}");
if (await canLaunchUrlString(mailUrl)) {
await launchUrlString(mailUrl);
} else {
print("error");
throw "Error Occured";
}
}
@override
Widget build(BuildContext context) {
return Card(
elevation: 8,
color: Colors.white10,
margin: const EdgeInsets.symmetric(horizontal: 20, vertical: 6),
child: ListTile(
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => ProfileScreen(userID: widget.userID)));
},
contentPadding:
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
leading: Container(
padding: const EdgeInsets.only(right: 12),
decoration: const BoxDecoration(
border: Border(
right: BorderSide(width: 1),
),
),
child: CircleAvatar(
backgroundColor: Colors.transparent,
radius: 20,
child: Image.network(widget.userImageUrl == null
? "https://st4.depositphotos.com/4329009/19956/v/600/depositphotos_199564354-stock-illustration-creative-vector-illustration-default-avatar.jpg"
: widget.userImageUrl),
),
),
title: Text(
widget.userName,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
subtitle: const Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
"Visit Profile",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.grey,
),
)
],
),
trailing: IconButton(
icon: const Icon(
Icons.mail_outline,
size: 30,
color: Colors.grey,
),
onPressed: () {
_mailTo();
},
),
),
);
}
}

View File

@ -5,6 +5,7 @@ import 'package:cpd_ss23/user_state.dart';
import 'package:curved_navigation_bar/curved_navigation_bar.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import '../jobs/jobs_screen.dart';
class BottomNavigationBarForApp extends StatelessWidget {
@ -94,11 +95,12 @@ class BottomNavigationBarForApp extends StatelessWidget {
} else if (index == 2){
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => UploadJobNow()));
} else if (index == 3){
final FirebaseAuth _auth=FirebaseAuth.instance;
final User? user = _auth.currentUser;
final String uid = user!.uid;
Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => ProfileScreen(userId: uid)));
}
final FirebaseAuth _auth = FirebaseAuth.instance;
final User? user = _auth.currentUser;
final String uid = user!.uid;
Navigator.pushReplacement(context,
MaterialPageRoute(builder: (_) => ProfileScreen(userID: uid)));
}
else if (index == 4){
_logout(context);
}

View File

@ -1,5 +1,4 @@
import 'package:cpd_ss23/Search/profile_company.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class CommentWidget extends StatefulWidget {
@ -26,7 +25,11 @@ class _CommentWidgetState extends State<CommentWidget> {
Widget build(BuildContext context) {
return InkWell(
onTap: () {
Navigator.push(context, MaterialPageRoute(builder: (context)=> ProfileScreen(userId: widget.commenterId)));
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
ProfileScreen(userID: widget.commenterId)));
},
child: Container(
decoration: BoxDecoration(